// Directory list view: /directory
// Search, filters, sort, grid/list/map layouts, cards.

const { useState, useMemo, useEffect } = React;

function DirectoryView({ tweaks, onOpenMsp, onVerify }) {
  const [q, setQ] = useState("");
  const [stage, setStage] = useState("all"); // all | journey | trusted
  const [regions, setRegions] = useState(new Set());
  const [industries, setIndustries] = useState(new Set());
  const [certs, setCerts] = useState(new Set());
  const [sort, setSort] = useState("recent"); // name | recent

  const layout = tweaks.layout; // grid | list | map
  const density = tweaks.density; // comfy | compact

  const filtered = useMemo(() => {
    let list = window.MSPS.filter(m => {
      if (q) {
        const needle = q.toLowerCase();
        const hay = (m.name + " " + m.city + " " + m.tagline + " " + m.specialisms.join(" ") + " " + m.industries.join(" ")).toLowerCase();
        if (!hay.includes(needle)) return false;
      }
      if (stage !== "all" && m.stage !== stage) return false;
      if (regions.size && !regions.has(m.region)) return false;
      if (industries.size && !m.industries.some(i => industries.has(i))) return false;
      if (certs.size && !m.certifications.some(c => certs.has(c))) return false;
      return true;
    });
    list.sort((a,b) => {
      if (sort === "name") return a.name.localeCompare(b.name);
      return new Date(b.lastVerified) - new Date(a.lastVerified);
    });
    return list;
  }, [q, stage, regions, industries, certs, sort]);

  const toggle = (set, setter, v) => {
    const n = new Set(set);
    n.has(v) ? n.delete(v) : n.add(v);
    setter(n);
  };

  const activeFilters = regions.size + industries.size + certs.size + (stage!=="all"?1:0);
  const clearAll = () => { setRegions(new Set()); setIndustries(new Set()); setCerts(new Set()); setStage("all"); setQ(""); };

  const toggleSet = (set, setter, v) => {
    const n = new Set(set);
    n.has(v) ? n.delete(v) : n.add(v);
    setter(n);
  };

  return (
    <div>
      <Hero
        q={q} setQ={setQ}
        industries={industries}
        onPickVertical={(v)=>toggleSet(industries, setIndustries, v)}
        total={window.MSPS.length}
        onVerify={onVerify}
      />

      <div style={{maxWidth:1320, margin:"0 auto", padding:"32px 32px 0"}}>
        {/* Unified filter bar — replaces the old sidebar */}
        <FilterBar
          q={q} setQ={setQ}
          stage={stage} setStage={setStage}
          regions={regions} setRegions={setRegions}
          industries={industries} setIndustries={setIndustries}
          certs={certs} setCerts={setCerts}
          activeFilters={activeFilters}
          onClear={clearAll}
        />

        <main style={{marginTop:24}}>
          <Toolbar
            count={filtered.length}
            total={window.MSPS.length}
            activeFilters={activeFilters}
            onClear={clearAll}
            sort={sort}
            setSort={setSort}
            layout={layout}
            tweaks={tweaks}
          />

          {filtered.length === 0 ? (
            <EmptyState onClear={clearAll}/>
          ) : layout === "map" ? (
            <MapView msps={filtered} onOpen={onOpenMsp}/>
          ) : layout === "list" ? (
            <ListView msps={filtered} onOpen={onOpenMsp} density={density}/>
          ) : (
            <GridView msps={filtered} onOpen={onOpenMsp} density={density} tweaks={tweaks}/>
          )}

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

// ---------- Unified filter bar ---------------------------------------------
// Replaces the old sticky sidebar. Search input + 4 filter popover buttons
// in a single row, so search and filters feel like one thing (Oscar's ask).
function FilterBar({ q, setQ, stage, setStage, regions, setRegions,
                    industries, setIndustries, certs, setCerts,
                    activeFilters, onClear }) {
  const [openMenu, setOpenMenu] = useState(null); // 'stage'|'region'|'industry'|'cert'|null

  // Close on outside click
  useEffect(() => {
    if (!openMenu) return;
    const close = (e) => {
      if (!e.target.closest("[data-filter-menu]")) setOpenMenu(null);
    };
    document.addEventListener("mousedown", close);
    return () => document.removeEventListener("mousedown", close);
  }, [openMenu]);

  const toggleSet = (set, setter, v) => {
    const n = new Set(set);
    n.has(v) ? n.delete(v) : n.add(v);
    setter(n);
  };

  // Faceted counts: for each panel, the row counts reflect the dataset
  // filtered by all OTHER active filters (not the panel's own selection).
  // Picking "Legal" then opening Region shows Region counts among Legal MSPs.
  const passes = (m, exclude) => {
    if (exclude !== "q" && q) {
      const needle = q.toLowerCase();
      const hay = (m.name + " " + m.city + " " + m.tagline + " " + m.specialisms.join(" ") + " " + m.industries.join(" ")).toLowerCase();
      if (!hay.includes(needle)) return false;
    }
    if (exclude !== "stage" && stage !== "all" && m.stage !== stage) return false;
    if (exclude !== "region" && regions.size && !regions.has(m.region)) return false;
    if (exclude !== "industry" && industries.size && !m.industries.some(i => industries.has(i))) return false;
    if (exclude !== "cert" && certs.size && !m.certifications.some(c => certs.has(c))) return false;
    return true;
  };
  const countFor = (facet, predicate) =>
    window.MSPS.filter(m => passes(m, facet) && predicate(m)).length;

  const stageLabel = stage === "all" ? "Any stage"
                   : stage === "trusted" ? "Trusted MSP"
                   : "On the Journey";

  return (
    <div style={{
      background:"#fff", border:"1px solid #E4E9F2", borderRadius:16,
      padding:14,
      boxShadow:"0 1px 2px rgba(10,20,48,0.04)",
    }}>
      <div style={{display:"flex", alignItems:"center", gap:10, flexWrap:"wrap"}}>
        {/* Search */}
        <div style={{
          flex:"1 1 280px", minWidth:240,
          display:"flex", alignItems:"center", gap:8,
          background:"#F8FAFD", border:"1px solid #E4E9F2", borderRadius:12,
          padding:"0 14px",
        }}>
          <Icon name="search" size={15} color="#6B7793"/>
          <input
            value={q}
            onChange={e=>setQ(e.target.value)}
            placeholder="Search by name, city, specialism…"
            style={{
              flex:1, border:"none", outline:"none", background:"transparent",
              padding:"11px 0", fontSize:14, fontFamily:"inherit", color:"#071e47",
            }}
          />
          {q && (
            <button onClick={()=>setQ("")} aria-label="Clear search" style={{
              border:"none", background:"transparent", cursor:"pointer", padding:0,
              display:"inline-flex", alignItems:"center",
            }}>
              <Icon name="x" size={14} color="#6B7793"/>
            </button>
          )}
        </div>

        {/* Filter buttons */}
        <FilterButton
          icon="users"
          label="I'm in"
          value={industries.size ? `${industries.size} selected` : "Any industry"}
          count={industries.size}
          highlight={industries.size > 0}
          open={openMenu==="industry"}
          onClick={()=>setOpenMenu(openMenu==="industry"?null:"industry")}
        >
          {window.INDUSTRIES.map(i => (
            <CheckRow key={i} checked={industries.has(i)} onChange={()=>toggleSet(industries, setIndustries, i)}
              label={i} meta={countFor("industry", m => m.industries.includes(i))}/>
          ))}
        </FilterButton>

        <FilterButton
          icon="shield"
          label="Stage"
          value={stageLabel}
          count={stage!=="all"?1:0}
          open={openMenu==="stage"}
          onClick={()=>setOpenMenu(openMenu==="stage"?null:"stage")}
        >
          <RadioRow checked={stage==="all"} onChange={()=>{setStage("all"); setOpenMenu(null);}} label="All active certificates" meta={countFor("stage", () => true)}/>
          <RadioRow checked={stage==="trusted"} onChange={()=>{setStage("trusted"); setOpenMenu(null);}} label="Trusted MSP" meta={countFor("stage", m => m.stage==="trusted")} dot="#2a9d8f"/>
          <RadioRow checked={stage==="journey"} onChange={()=>{setStage("journey"); setOpenMenu(null);}} label="On the Journey" meta={countFor("stage", m => m.stage==="journey")} dot="#9fba3d"/>
        </FilterButton>

        <FilterButton
          icon="map-pin"
          label="Region"
          value={regions.size ? `${regions.size} selected` : "Anywhere"}
          count={regions.size}
          open={openMenu==="region"}
          onClick={()=>setOpenMenu(openMenu==="region"?null:"region")}
        >
          {window.REGIONS.map(r => (
            <CheckRow key={r} checked={regions.has(r)} onChange={()=>toggleSet(regions, setRegions, r)}
              label={r} meta={countFor("region", m => m.region===r)}/>
          ))}
        </FilterButton>

        <FilterButton
          icon="check"
          label="Certifications"
          value={certs.size ? `${certs.size} selected` : "Any"}
          count={certs.size}
          open={openMenu==="cert"}
          onClick={()=>setOpenMenu(openMenu==="cert"?null:"cert")}
        >
          {window.CERTIFICATIONS.map(c => (
            <CheckRow key={c} checked={certs.has(c)} onChange={()=>toggleSet(certs, setCerts, c)}
              label={c} meta={countFor("cert", m => m.certifications.includes(c))}/>
          ))}
        </FilterButton>

        {activeFilters > 0 && (
          <button onClick={onClear} style={{
            border:"1px solid #E4E9F2", background:"#fff",
            padding:"10px 14px", borderRadius:12,
            fontSize:12, color:"#071e47", fontWeight:500, fontFamily:"inherit",
            cursor:"pointer",
            display:"inline-flex", alignItems:"center", gap:6,
          }}>
            <Icon name="x" size={12}/> Clear {activeFilters}
          </button>
        )}
      </div>
    </div>
  );
}

function FilterButton({ icon, label, value, count, highlight, open, onClick, children }) {
  return (
    <div data-filter-menu style={{position:"relative"}}>
      <button onClick={onClick} style={{
        border: highlight ? "1px solid #071e47" : "1px solid #E4E9F2",
        background: open ? "#F4F7FB" : "#fff",
        padding:"8px 14px", borderRadius:12,
        cursor:"pointer", fontFamily:"inherit",
        display:"inline-flex", alignItems:"center", gap:10, minHeight:42,
      }}>
        <Icon name={icon} size={13} color="#6B7793"/>
        <div style={{display:"flex", flexDirection:"column", alignItems:"flex-start", lineHeight:1.15, textAlign:"left"}}>
          <span style={{fontSize:10, color:"#6B7793", fontWeight:600, textTransform:"uppercase", letterSpacing:"0.05em"}}>{label}</span>
          <span style={{fontSize:13, color:"#071e47", fontWeight:600}}>{value}</span>
        </div>
        {count > 0 && (
          <span style={{
            background:"#071e47", color:"#fff",
            fontSize:10, fontWeight:700,
            padding:"2px 6px", borderRadius:99, marginLeft:2,
          }}>{count}</span>
        )}
        <Icon name="chevron-down" size={12} color="#6B7793"/>
      </button>
      {open && (
        <div style={{
          position:"absolute", top:"calc(100% + 6px)", left:0,
          background:"#fff", border:"1px solid #E4E9F2", borderRadius:12,
          minWidth:260, maxHeight:340, overflowY:"auto",
          padding:8, zIndex:50,
          boxShadow:"0 12px 30px rgba(7,30,71,0.15)",
        }}>
          {children}
        </div>
      )}
    </div>
  );
}

// ---------- Hero ------------------------------------------------------------
// Top quick-pick verticals shown as chips so prospects can self-identify
// ("I'm a law firm…") in one click — drives both filtering and Assurix's
// own data on which verticals are most interested.
const QUICK_VERTICALS = ["Legal", "Healthcare", "Financial services", "Manufacturing", "Education", "Public sector"];

function Hero({ q, setQ, industries, onPickVertical, total, onVerify }) {
  return (
    <>
    <section style={{
      position:"relative", overflow:"hidden",
      background:"linear-gradient(180deg, #DCE6F0 0%, #E9EFF5 55%, #EEF3F8 100%)",
    }}>
      {/* Ghost hexagons on the right */}
      <GhostHexes/>
      <div style={{maxWidth:1200, margin:"0 auto", padding:"80px 40px 72px", position:"relative"}}>
        <div style={{display:"grid", gridTemplateColumns:"1.05fr 1fr", gap:40, alignItems:"center"}}>
          <div>
            {/* Pill badge */}
            <div style={{
              display:"inline-flex", alignItems:"center", gap:8,
              background:"#fff", border:"1px solid #E4E9F2",
              padding:"8px 18px", borderRadius:999,
              fontSize:13, fontWeight:500, color:"#071e47",
              marginBottom:28,
            }}>
              Continuously verified MSP directory
            </div>

            <h1 style={{
              fontFamily:window.ASX.font, fontWeight:800, letterSpacing:"-0.035em",
              fontSize:62, lineHeight:1.02, margin:0, color:"#071e47",
              textWrap:"balance",
            }}>
              Find an MSP<br/>
              your clients,<br/>
              insurers and buyers<br/>
              can actually trust
            </h1>
            <p style={{
              marginTop:22, fontSize:16, lineHeight:1.55, color:"#5C6784",
              maxWidth:520,
              fontWeight:400,
            }}>
              Every MSP in this directory holds an active Assurix BlockMark certificate — their security and operational maturity is independently verified and continuously re-checked.
            </p>

            {/* Search — pill shape */}
            <div style={{
              marginTop:28,
              display:"flex", alignItems:"center",
              background:"#fff",
              border:"1px solid #E4E9F2",
              borderRadius:999,
              padding:"5px 5px 5px 22px",
              maxWidth:560,
              boxShadow:"0 1px 2px rgba(10,20,48,0.04)",
            }}>
              <Icon name="search" size={16} color="#6B7793"/>
              <input
                value={q}
                onChange={e=>setQ(e.target.value)}
                placeholder="Search by name, city, specialism…"
                style={{
                  flex:1, border:"none", outline:"none",
                  fontSize:14, padding:"12px 14px",
                  fontFamily:window.ASX.font,
                  color:"#071e47",
                  background:"transparent",
                }}
              />
            </div>

            {/* Quick vertical picker — addresses Oscar's "let prospects say
                they're a law firm" ask. Clicking a chip applies an Industry
                filter, which the inline filter bar reflects. */}
            <div style={{marginTop:18, display:"flex", flexWrap:"wrap", gap:8, alignItems:"center"}}>
              <span style={{fontSize:12, color:"#5C6784", marginRight:4}}>I'm in:</span>
              {QUICK_VERTICALS.map(v => {
                const on = industries.has(v);
                return (
                  <button key={v} onClick={()=>onPickVertical(v)} style={{
                    border: on ? "1px solid #071e47" : "1px solid #C7D0DD",
                    background: on ? "#071e47" : "transparent",
                    color: on ? "#fff" : "#071e47",
                    fontFamily:"inherit", fontSize:12.5, fontWeight:500,
                    padding:"6px 12px", borderRadius:999, cursor:"pointer",
                  }}>
                    {v}
                  </button>
                );
              })}
            </div>

            {/* CTAs */}
            <div style={{marginTop:22, display:"flex", gap:10, flexWrap:"wrap"}}>
              <button style={pillBtnBlack}>
                Browse directory
                <span style={pillArrowWhite}><Icon name="arrow-right" size={11} color="#071e47" strokeWidth={2.4}/></span>
              </button>
            </div>
          </div>

          {/* Right: single big trustmark */}
          <div style={{display:"flex", justifyContent:"center", alignItems:"center"}}>
            <BlockMark variant="trusted" size={340} name="Assurix" blockmarkId={null}/>
          </div>
        </div>
      </div>
    </section>

    {/* Trust wall — auto-populated rolling logo strip of MSPs in the directory */}
    <LogoMarquee msps={window.MSPS} total={total}/>
    </>
  );
}

// Auto-populated rolling logo marquee. Pulls every MSP in window.MSPS so it
// stays in sync as new MSPs onboard (no manual logo uploads).
function LogoMarquee({ msps, total }) {
  // Duplicate the list so the CSS translateX loop is seamless.
  const rows = [...msps, ...msps];
  return (
    <section style={{background:"#E9EFF5", borderTop:"1px solid rgba(10,20,48,0.06)", borderBottom:"1px solid rgba(10,20,48,0.06)"}}>
      <style>{`
        @keyframes asx-marquee {
          from { transform: translateX(0); }
          to   { transform: translateX(-50%); }
        }
        @keyframes asx-pulse {
          0%   { transform: scale(1);   opacity: 0.5; }
          80%  { transform: scale(2.4); opacity: 0; }
          100% { transform: scale(2.4); opacity: 0; }
        }
        .asx-marquee-track { animation: asx-marquee 50s linear infinite; }
        .asx-marquee-viewport:hover .asx-marquee-track { animation-play-state: paused; }
      `}</style>
      <div style={{maxWidth:1320, margin:"0 auto", padding:"24px 40px 28px"}}>
        <div style={{textAlign:"center", fontSize:13, color:"#5C6784", marginBottom:14}}>
          Trusted by {total}+ leading MSPs across the UK · auto-updated as new MSPs onboard
        </div>
        <div className="asx-marquee-viewport" style={{
          overflow:"hidden",
          maskImage:"linear-gradient(to right, transparent, black 8%, black 92%, transparent)",
          WebkitMaskImage:"linear-gradient(to right, transparent, black 8%, black 92%, transparent)",
        }}>
          <div className="asx-marquee-track" style={{
            display:"flex", gap:48, width:"max-content", alignItems:"center",
            opacity:0.75,
          }}>
            {rows.map((m, i) => (
              <div key={`${m.slug}-${i}`} style={{
                display:"flex", alignItems:"center", gap:10,
                color:"#39466A", fontWeight:600, fontSize:14, letterSpacing:"-0.01em",
                whiteSpace:"nowrap",
              }}>
                <div style={{
                  width:28, height:28, borderRadius:6,
                  background: m.color, color:"#fff",
                  display:"flex", alignItems:"center", justifyContent:"center",
                  fontSize:11, fontWeight:700, flexShrink:0,
                }}>{m.name.split(" ").map(w=>w[0]).slice(0,2).join("")}</div>
                {m.name}
              </div>
            ))}
          </div>
        </div>
      </div>
    </section>
  );
}

// Large, sparse, ghosted hexagon outlines on the right of the hero
function GhostHexes() {
  const hexes = [
    { x: "58%", y: "-8%", size: 260, opacity: 0.15 },
    { x: "76%", y: "18%", size: 200, opacity: 0.22 },
    { x: "90%", y: "-2%", size: 180, opacity: 0.15 },
    { x: "92%", y: "60%", size: 140, opacity: 0.2 },
    { x: "52%", y: "70%", size: 110, opacity: 0.18 },
    { x: "68%", y: "88%", size: 90, opacity: 0.15 },
  ];
  return (
    <div aria-hidden="true" style={{position:"absolute", inset:0, pointerEvents:"none", overflow:"hidden"}}>
      {hexes.map((h,i) => (
        <svg key={i} width={h.size} height={h.size * 1.08} viewBox="0 0 100 108" style={{position:"absolute", left:h.x, top:h.y, opacity:h.opacity}}>
          <path d="M50 2 L91 25 L91 73 L50 96 L9 73 L9 25 Z" fill="none" stroke="#071e47" strokeWidth="0.8"/>
        </svg>
      ))}
    </div>
  );
}

// ---------- Toolbar ---------------------------------------------------------
function Toolbar({ count, total, activeFilters, onClear, sort, setSort, layout, tweaks }) {
  return (
    <div style={{
      display:"flex", alignItems:"center", gap:16,
      paddingBottom:16, marginBottom:20,
      borderBottom:"1px solid #E4E9F2",
    }}>
      <div style={{fontSize:14, color:"#071e47", fontWeight:600}}>
        {count} <span style={{color:"#6B7793", fontWeight:400}}>of {total} MSPs</span>
      </div>
      {activeFilters > 0 && (
        <button onClick={onClear} style={{
          border:"none", background:"transparent",
          fontSize:12, color:"#071e47",
          display:"inline-flex", alignItems:"center", gap:4,
          cursor:"pointer",
          padding:"4px 8px", borderRadius:6,
        }}>
          <Icon name="x" size={12}/> Clear {activeFilters} filter{activeFilters>1?"s":""}
        </button>
      )}
      <div style={{flex:1}}/>

      {/* Layout toggle */}
      <div style={{display:"flex", background:"#fff", border:"1px solid #E4E9F2", borderRadius:10, padding:3}}>
        {[
          {id:"grid", icon:"grid", label:"Grid"},
          {id:"list", icon:"list", label:"List"},
          {id:"map", icon:"map", label:"Map"},
        ].map(v => (
          <button key={v.id}
            onClick={()=>tweaks.set("layout", v.id)}
            style={{
              display:"inline-flex", alignItems:"center", gap:6,
              border:"none", background: layout===v.id ? "#071e47" : "transparent",
              color: layout===v.id ? "#fff" : "#071e47",
              fontSize:12, fontWeight:500,
              padding:"6px 10px", borderRadius:7,
              cursor:"pointer",
            }}>
            <Icon name={v.icon} size={13}/> {v.label}
          </button>
        ))}
      </div>

      <select value={sort} onChange={e=>setSort(e.target.value)} style={{
        border:"1px solid #E4E9F2", background:"#fff", borderRadius:10,
        fontSize:12, padding:"8px 10px", color:"#071e47", fontFamily:"inherit",
      }}>
        <option value="recent">Sort: Recently added</option>
        <option value="name">Sort: A–Z</option>
      </select>
    </div>
  );
}

// ---------- Filter UI -------------------------------------------------------
function FilterGroup({ title, count, open, onToggle, children }) {
  return (
    <div style={{padding:"4px 16px", borderBottom:"1px solid #F0F3F8"}}>
      <button onClick={onToggle} style={{
        width:"100%", background:"transparent", border:"none",
        display:"flex", alignItems:"center", gap:8,
        padding:"14px 0", cursor:"pointer",
        fontFamily:"inherit",
      }}>
        <Icon name="chevron-right" size={14} color="#6B7793" />
        <span style={{fontSize:13, fontWeight:600, color:"#071e47"}}>{title}</span>
        {count > 0 && (
          <span style={{
            background:"#071e47", color:"#fff",
            fontSize:10, fontWeight:700,
            padding:"2px 6px", borderRadius:99,
          }}>{count}</span>
        )}
        <span style={{flex:1}}/>
      </button>
      {open && <div style={{paddingBottom:12, display:"flex", flexDirection:"column", gap:2}}>{children}</div>}
    </div>
  );
}

function CheckRow({ checked, onChange, label, meta }) {
  return (
    <label style={{
      display:"flex", alignItems:"center", gap:10,
      padding:"6px 8px", borderRadius:6, cursor:"pointer",
      fontSize:13, color:"#39466A",
      background: checked ? "#F4F7FB" : "transparent",
    }}>
      <span style={{
        width:16, height:16, borderRadius:4,
        border: `1.5px solid ${checked ? "#071e47":"#C7CEDC"}`,
        background: checked ? "#071e47" : "#fff",
        display:"flex", alignItems:"center", justifyContent:"center",
        flexShrink:0,
      }}>
        {checked && <Icon name="check" size={10} color="#fff" strokeWidth={3}/>}
      </span>
      <input type="checkbox" checked={checked} onChange={onChange} style={{display:"none"}}/>
      <span style={{flex:1}}>{label}</span>
      <span style={{color:"#98A2B3", fontSize:11, fontVariantNumeric:"tabular-nums"}}>{meta}</span>
    </label>
  );
}

function RadioRow({ checked, onChange, label, meta, dot }) {
  return (
    <label style={{
      display:"flex", alignItems:"center", gap:10,
      padding:"7px 8px", borderRadius:6, cursor:"pointer",
      fontSize:13, color:"#39466A",
      background: checked ? "#F4F7FB" : "transparent",
    }}>
      <span style={{
        width:16, height:16, borderRadius:99,
        border: `1.5px solid ${checked ? "#071e47":"#C7CEDC"}`,
        background:"#fff",
        display:"flex", alignItems:"center", justifyContent:"center",
        flexShrink:0,
      }}>
        {checked && <span style={{width:8, height:8, borderRadius:99, background:"#071e47"}}/>}
      </span>
      <input type="radio" checked={checked} onChange={onChange} style={{display:"none"}}/>
      {dot && <span style={{width:7, height:7, borderRadius:99, background:dot}}/>}
      <span style={{flex:1}}>{label}</span>
      <span style={{color:"#98A2B3", fontSize:11, fontVariantNumeric:"tabular-nums"}}>{meta}</span>
    </label>
  );
}

// ---------- Views -----------------------------------------------------------
function GridView({ msps, onOpen, density, tweaks }) {
  const cols = density === "compact" ? 3 : (tweaks.perRow === 2 ? 2 : 3);
  return (
    <div style={{display:"grid", gridTemplateColumns:`repeat(${cols}, 1fr)`, gap:20}}>
      {msps.map(m => <GridCard key={m.slug} msp={m} onOpen={onOpen} density={density} tweaks={tweaks}/>)}
    </div>
  );
}

function GridCard({ msp, onOpen, density, tweaks }) {
  const compact = density === "compact";
  const showMark = tweaks.showMark;
  return (
    <article onClick={()=>onOpen(msp.slug)} style={{
      background:"#fff", border:"1px solid #E4E9F2", borderRadius:14,
      padding: compact ? 18 : 22,
      cursor:"pointer",
      transition:"transform .15s ease, box-shadow .15s ease, border-color .15s ease",
      display:"flex", flexDirection:"column", gap: compact ? 12 : 16,
      position:"relative",
    }}
    onMouseEnter={e=>{ e.currentTarget.style.transform="translateY(-2px)"; e.currentTarget.style.boxShadow="0 12px 32px -12px rgba(11,21,51,0.18)"; e.currentTarget.style.borderColor="#071e47"; }}
    onMouseLeave={e=>{ e.currentTarget.style.transform=""; e.currentTarget.style.boxShadow=""; e.currentTarget.style.borderColor="#E4E9F2"; }}
    >
      <header style={{display:"flex", gap:12, alignItems:"flex-start"}}>
        <MspMark msp={msp} size={compact ? 38 : 44}/>
        <div style={{flex:1, minWidth:0}}>
          <div style={{fontSize: compact?15:17, fontWeight:700, color:"#071e47", letterSpacing:"-0.01em", lineHeight:1.2}}>{msp.name}</div>
          <div style={{fontSize:12, color:"#6B7793", marginTop:3, display:"flex", alignItems:"center", gap:4}}>
            <Icon name="map-pin" size={11}/> {msp.city} · {msp.region}
          </div>
        </div>
        <StageChip stage={msp.stage} small/>
      </header>

      {!compact && (
        <p style={{fontSize:13, color:"#39466A", lineHeight:1.5, margin:0, textWrap:"pretty"}}>
          {msp.tagline}
        </p>
      )}

      {/* Footer: tier + Founding 50 badge */}
      <footer style={{
        marginTop:"auto",
        display:"flex", alignItems:"center", justifyContent:"space-between",
        gap:8,
        paddingTop: compact ? 10 : 14,
        borderTop:"1px dashed #E4E9F2",
      }}>
        <div style={{display:"flex", alignItems:"center", gap:8, minWidth:0}}>
          {msp.founding50 ? (
            <FoundingBadge small/>
          ) : (
            <div style={{fontSize:12, color:"#6B7793"}}>
              {msp.stage === "trusted" ? "Trusted MSP" : "On the Journey"}
            </div>
          )}
        </div>
        <div style={{fontSize:12, color:"#071e47", fontWeight:500, display:"inline-flex", alignItems:"center", gap:4, flexShrink:0}}>
          View profile <Icon name="arrow-right" size={11}/>
        </div>
      </footer>
    </article>
  );
}

function ListView({ msps, onOpen, density }) {
  return (
    <div style={{display:"flex", flexDirection:"column", gap:0, background:"#fff", border:"1px solid #E4E9F2", borderRadius:14, overflow:"hidden"}}>
      <div style={{
        display:"grid",
        gridTemplateColumns:"minmax(0, 3fr) 1.2fr 1.1fr",
        padding:"12px 20px",
        fontSize:11, color:"#6B7793", letterSpacing:"0.05em", textTransform:"uppercase", fontWeight:600,
        borderBottom:"1px solid #E4E9F2",
        background:"#F8FAFD",
      }}>
        <div>MSP</div>
        <div>Region</div>
        <div>Tier</div>
      </div>
      {msps.map((m,i) => (
        <button key={m.slug} onClick={()=>onOpen(m.slug)} style={{
          display:"grid",
          gridTemplateColumns:"minmax(0, 3fr) 1.2fr 1.1fr",
          alignItems:"center",
          padding:"14px 20px",
          gap:16,
          background: i%2 ? "#FBFCFE" : "#fff",
          border:"none", borderTop: i===0?"none":"1px solid #F0F3F8",
          textAlign:"left", cursor:"pointer",
          fontFamily:"inherit",
          width:"100%",
        }}
        onMouseEnter={e=>e.currentTarget.style.background="#F4F7FB"}
        onMouseLeave={e=>e.currentTarget.style.background=i%2?"#FBFCFE":"#fff"}
        >
          <div style={{display:"flex", gap:12, alignItems:"center", minWidth:0}}>
            <MspMark msp={m} size={36}/>
            <div style={{minWidth:0}}>
              <div style={{fontSize:14, fontWeight:600, color:"#071e47", display:"flex", alignItems:"center", gap:8, flexWrap:"wrap"}}>
                {m.name}
                <StageChip stage={m.stage} small/>
                {m.founding50 && <FoundingBadge small/>}
              </div>
              <div style={{fontSize:12, color:"#6B7793", marginTop:2, overflow:"hidden", textOverflow:"ellipsis", whiteSpace:"nowrap"}}>
                {m.tagline}
              </div>
            </div>
          </div>
          <div style={{fontSize:13, color:"#39466A"}}>{m.city}<span style={{color:"#98A2B3"}}> · {m.region}</span></div>
          <div style={{fontSize:12, color:"#39466A"}}>{m.stage === "trusted" ? "Trusted MSP" : "On the Journey"}</div>
        </button>
      ))}
    </div>
  );
}

function MapView({ msps, onOpen }) {
  // Real lat/lng for each city we reference (WGS84).
  const cityCoords = {
    "London":      [51.5074, -0.1278],
    "Bristol":     [51.4545, -2.5879],
    "Manchester":  [53.4808, -2.2426],
    "Edinburgh":   [55.9533, -3.1883],
    "Glasgow":     [55.8642, -4.2518],
    "Nottingham":  [52.9548, -1.1581],
    "Cardiff":     [51.4816, -3.1791],
    "Newcastle":   [54.9783, -1.6178],
    "Belfast":     [54.5973, -5.9301],
    "Norwich":     [52.6309, 1.2974],
    "Reading":     [51.4543, -0.9781],
    "Maidstone":   [51.2720, 0.5195],
    "Liverpool":   [53.4084, -2.9916],
    "Birmingham":  [52.4862, -1.8904],
    "Leeds":       [53.8008, -1.5491],
    "Sheffield":   [53.3811, -1.4701],
  };
  // Simple equirectangular projection with latitude scaling — good enough for UK.
  // viewBox is 0..100 x 0..130. Bounds chosen to frame GB + NI comfortably.
  const latMin = 49.5, latMax = 61.0;       // north–south
  const lngMin = -8.5, lngMax = 2.0;        // east–west
  const project = ([lat, lng]) => {
    const x = (lng - lngMin) / (lngMax - lngMin) * 100;
    const y = (1 - (lat - latMin) / (latMax - latMin)) * 130;
    return { x, y };
  };

  const [selected, setSelected] = useState(null);

  // Deterministic spoke layout for MSPs that share a city: first MSP at the anchor,
  // next ones offset outward at 45° increments so labels don't overlap.
  const byCity = {};
  msps.forEach(m => { (byCity[m.city] ??= []).push(m); });
  const placed = [];
  Object.entries(byCity).forEach(([city, list]) => {
    const coords = cityCoords[city] || cityCoords["London"];
    const anchor = project(coords);
    list.forEach((m, idx) => {
      if (idx === 0) {
        placed.push({ msp: m, anchor, pin: anchor, angle: null });
      } else {
        const angle = (idx - 1) * (Math.PI / 4);        // 0, 45, 90, 135…
        const r = 5 + Math.floor((idx - 1) / 8) * 3;    // second ring further out
        placed.push({
          msp: m,
          anchor,
          pin: { x: anchor.x + Math.cos(angle) * r, y: anchor.y + Math.sin(angle) * r },
          angle,
        });
      }
    });
  });

  return (
    <div style={{display:"grid", gridTemplateColumns:"minmax(0, 1fr) 340px", gap:20, alignItems:"start"}}>
      <div style={{
        position:"relative",
        background:"#071e47",
        borderRadius:14,
        aspectRatio:"100/130",
        maxWidth:520, maxHeight:680,
        width:"100%",
        margin:"0 auto",
        overflow:"hidden",
      }}>
        <HexPattern opacity={0.09} stroke="#fff" id="map-hex"/>

        {/* Real UK + Ireland silhouette (simplified but recognizable) */}
        <svg viewBox="0 0 100 130" preserveAspectRatio="xMidYMid meet"
             style={{position:"absolute", inset:0, width:"100%", height:"100%"}}>
          {/* Great Britain */}
          <path d={UK_GB_PATH}
                fill="rgba(42,157,143,0.10)"
                stroke="rgba(184,214,69,0.55)"
                strokeWidth="0.35"
                strokeLinejoin="round"/>
          {/* Ireland (NI + ROI) — drawn as silhouette, NI slightly brighter */}
          <path d={UK_IRELAND_PATH}
                fill="rgba(42,157,143,0.06)"
                stroke="rgba(184,214,69,0.35)"
                strokeWidth="0.35"
                strokeLinejoin="round"/>

          {/* Leader lines from anchor → offset pin (for clustered cities) */}
          {placed.filter(p => p.angle !== null).map(p => (
            <line key={`ll-${p.msp.slug}`}
                  x1={p.anchor.x} y1={p.anchor.y}
                  x2={p.pin.x}    y2={p.pin.y}
                  stroke="rgba(255,255,255,0.25)" strokeWidth="0.25"/>
          ))}

          {/* Anchor dots — one per unique city */}
          {Object.entries(byCity).map(([city]) => {
            const coords = cityCoords[city] || cityCoords["London"];
            const p = project(coords);
            return (
              <g key={`anchor-${city}`}>
                <circle cx={p.x} cy={p.y} r="1.6" fill="#071e47" stroke="#fff" strokeWidth="0.6"/>
              </g>
            );
          })}
        </svg>

        {/* Label pills positioned over the SVG */}
        {placed.map(({ msp: m, pin }) => {
          const isSel = selected === m.slug;
          const accent = m.stage === "trusted" ? "#2a9d8f" : "#b8d645";
          const leftPct = (pin.x / 100) * 100;
          const topPct  = (pin.y / 130) * 100;
          return (
            <button key={m.slug}
              onClick={()=>setSelected(m.slug)}
              onDoubleClick={()=>onOpen(m.slug)}
              style={{
                position:"absolute",
                left:`${leftPct}%`, top:`${topPct}%`,
                transform:"translate(-50%, -110%)",
                background: accent, color:"#071e47",
                border: isSel ? "1.5px solid #fff" : "1px solid rgba(0,0,0,0.15)",
                padding:"4px 9px", borderRadius:999,
                fontSize:10.5, fontWeight:700,
                cursor:"pointer",
                whiteSpace:"nowrap",
                boxShadow:"0 2px 6px rgba(0,0,0,0.35)",
                zIndex: isSel ? 5 : 1,
                fontFamily:"inherit",
                lineHeight:1.2,
              }}>
              {m.name}
            </button>
          );
        })}

        {/* Legend */}
        <div style={{
          position:"absolute", left:14, bottom:14,
          display:"flex", gap:12, alignItems:"center",
          background:"rgba(7,30,71,0.75)",
          backdropFilter:"blur(6px)",
          border:"1px solid rgba(255,255,255,0.1)",
          padding:"8px 12px", borderRadius:10,
          fontSize:11, color:"#fff",
        }}>
          <span style={{display:"inline-flex", alignItems:"center", gap:6}}>
            <span style={{width:8, height:8, borderRadius:99, background:"#2a9d8f"}}/> Trusted MSP
          </span>
          <span style={{display:"inline-flex", alignItems:"center", gap:6}}>
            <span style={{width:8, height:8, borderRadius:99, background:"#b8d645"}}/> On the Journey
          </span>
        </div>
      </div>

      <div style={{display:"flex", flexDirection:"column", gap:10, maxHeight:700, overflowY:"auto", paddingRight:4}}>
        {msps.map(m => (
          <button key={m.slug} onClick={()=>{setSelected(m.slug); onOpen(m.slug);}} style={{
            textAlign:"left", background:"#fff",
            border: selected===m.slug ? "1.5px solid #071e47" : "1px solid #E4E9F2",
            borderRadius:12, padding:12,
            cursor:"pointer", fontFamily:"inherit",
            display:"flex", gap:10, alignItems:"center",
          }}>
            <MspMark msp={m} size={34}/>
            <div style={{flex:1, minWidth:0}}>
              <div style={{fontSize:13, fontWeight:600, color:"#071e47"}}>{m.name}</div>
              <div style={{fontSize:11, color:"#6B7793"}}>{m.city} · {m.region}</div>
            </div>
            <StageChip stage={m.stage} small/>
          </button>
        ))}
      </div>
    </div>
  );
}

// Accurate-enough UK (Great Britain) outline derived from Natural Earth 110m.
// Projected via equirectangular onto viewBox 0..100 (lng) x 0..130 (lat) with
// bounds lat 49.5..61.0, lng -8.5..2.0. The path is simplified (~120 pts).
const UK_GB_PATH = "M 11.93 67.04 L 11.84 67.25 L 13.77 67.28 L 14.52 66.29 L 14.64 65.63 L 15.39 65.86 L 16.62 65.82 L 19.28 65.01 L 19.85 65.20 L 20.45 65.08 L 21.53 65.47 L 22.85 65.43 L 23.46 65.93 L 23.22 66.99 L 24.11 67.33 L 23.94 68.03 L 24.89 68.50 L 25.51 69.24 L 25.71 69.85 L 26.52 70.27 L 25.74 69.58 L 26.18 69.44 L 26.76 70.16 L 26.39 70.90 L 24.85 71.53 L 24.50 71.98 L 24.69 72.28 L 26.21 71.44 L 27.91 71.48 L 29.23 73.65 L 28.68 74.95 L 28.81 75.08 L 28.42 75.31 L 27.84 74.58 L 28.16 73.95 L 27.85 73.15 L 26.65 72.60 L 26.52 73.06 L 27.38 73.29 L 26.95 73.41 L 27.24 73.53 L 27.38 74.14 L 27.03 74.84 L 26.58 75.15 L 27.81 74.79 L 28.09 75.00 L 28.07 75.76 L 27.09 76.53 L 26.32 76.31 L 25.12 76.52 L 24.82 77.95 L 23.42 78.72 L 22.90 78.72 L 22.73 78.56 L 23.00 78.49 L 22.04 78.08 L 20.43 77.88 L 20.21 78.42 L 17.80 78.66 L 17.40 78.36 L 17.71 77.23 L 17.19 76.89 L 16.72 77.05 L 16.31 76.84 L 15.83 76.19 L 15.41 76.00 L 15.65 75.82 L 15.43 75.27 L 14.12 74.46 L 12.45 75.35 L 12.29 75.81 L 12.90 76.28 L 12.83 76.60 L 11.91 76.90 L 11.62 77.70 L 11.45 77.71 L 11.47 77.26 L 11.18 77.38 L 11.33 77.83 L 10.53 77.75 L 10.34 77.48 L 9.50 77.72 L 8.49 77.55 L 7.57 76.87 L 6.13 76.74 L 5.90 75.89 L 5.23 75.73 L 4.74 75.08 L 4.22 74.99 L 3.11 73.91 L 4.07 73.62 L 4.74 72.99 L 5.84 73.12 L 7.54 72.30 L 7.52 72.07 L 6.22 71.99 L 5.43 71.25 L 6.23 70.87 L 6.95 71.15 L 8.10 70.71 L 9.11 70.75 L 9.11 70.17 L 9.95 69.37 L 10.43 67.79 L 10.90 67.36 L 11.93 67.04 Z M 55.57 106.07 L 53.73 106.87 L 52.92 106.91 L 52.62 106.68 L 50.74 107.92 L 50.86 108.16 L 50.62 108.55 L 49.62 108.70 L 47.25 108.54 L 46.06 107.66 L 45.36 107.49 L 45.05 106.68 L 44.37 106.02 L 43.08 106.13 L 42.86 106.36 L 43.10 106.68 L 42.60 106.78 L 41.70 106.65 L 40.95 106.95 L 40.10 106.76 L 40.10 106.07 L 40.62 105.75 L 40.75 105.99 L 41.99 105.81 L 42.19 105.40 L 39.85 105.39 L 39.25 104.83 L 39.90 104.75 L 39.40 104.65 L 39.38 104.12 L 39.06 104.43 L 38.61 104.30 L 38.80 104.60 L 38.47 104.73 L 36.71 104.77 L 36.40 104.93 L 36.07 105.69 L 34.63 105.76 L 33.89 106.30 L 32.90 105.96 L 32.85 105.62 L 32.19 105.37 L 34.81 104.97 L 34.49 104.43 L 35.01 104.05 L 33.97 104.28 L 34.28 104.43 L 34.19 104.92 L 31.91 104.93 L 31.59 105.25 L 31.61 105.06 L 30.96 104.75 L 32.28 104.24 L 32.13 103.37 L 31.22 103.12 L 30.37 103.28 L 30.49 102.75 L 32.19 102.20 L 32.49 102.01 L 32.66 101.44 L 33.70 101.65 L 34.16 101.57 L 34.09 101.42 L 34.84 101.57 L 34.88 101.19 L 35.45 101.01 L 36.00 100.46 L 36.44 100.64 L 36.42 100.30 L 36.79 100.17 L 38.07 100.17 L 39.19 99.44 L 39.85 99.29 L 40.98 98.58 L 41.81 97.61 L 42.32 95.75 L 42.70 95.84 L 43.36 95.53 L 42.35 95.61 L 41.66 94.91 L 42.32 93.82 L 42.97 93.44 L 42.39 93.58 L 41.44 92.56 L 41.74 92.35 L 41.62 91.69 L 42.12 91.26 L 38.98 91.65 L 38.27 92.12 L 38.20 92.66 L 37.94 92.81 L 37.19 92.51 L 35.59 92.81 L 37.18 91.24 L 39.45 90.11 L 39.61 89.16 L 39.80 89.29 L 41.16 87.97 L 44.46 87.17 L 44.02 86.62 L 45.06 86.83 L 45.56 87.19 L 46.65 87.17 L 49.24 86.46 L 51.55 87.78 L 51.58 87.32 L 50.61 85.99 L 51.83 85.52 L 52.26 85.72 L 52.83 86.77 L 53.51 87.17 L 54.52 87.04 L 55.24 86.46 L 54.29 86.81 L 53.10 86.48 L 52.56 85.99 L 51.41 84.13 L 52.17 83.06 L 53.34 82.12 L 52.53 82.11 L 51.91 81.74 L 51.84 80.19 L 53.73 79.50 L 53.63 79.37 L 54.00 78.95 L 53.38 79.10 L 53.16 78.74 L 54.32 77.72 L 53.77 76.94 L 54.19 76.74 L 54.32 76.32 L 52.96 77.38 L 52.40 77.33 L 52.23 76.74 L 51.91 76.62 L 51.80 77.30 L 51.00 78.00 L 51.00 78.41 L 50.09 77.86 L 50.02 77.17 L 50.33 77.10 L 50.41 76.16 L 50.18 76.34 L 50.17 76.84 L 49.46 76.96 L 48.50 75.99 L 48.44 75.25 L 46.34 73.33 L 47.53 70.97 L 48.19 70.52 L 48.69 69.14 L 49.10 68.93 L 49.46 69.11 L 49.96 68.96 L 49.36 68.73 L 49.75 68.47 L 50.35 68.34 L 51.21 68.59 L 52.17 68.34 L 51.52 68.34 L 52.17 68.10 L 47.61 67.91 L 47.37 68.08 L 46.95 67.88 L 46.84 69.14 L 45.55 69.17 L 45.34 69.41 L 44.64 69.46 L 44.46 69.34 L 44.60 69.11 L 44.21 69.58 L 44.53 69.81 L 42.75 70.45 L 42.33 70.28 L 42.25 69.73 L 42.00 69.98 L 42.06 70.35 L 41.69 70.39 L 40.87 69.79 L 40.95 69.34 L 40.28 69.64 L 39.46 69.35 L 39.02 68.87 L 38.88 69.57 L 39.58 70.15 L 39.54 71.20 L 39.22 71.44 L 38.13 71.21 L 37.17 70.37 L 35.42 69.71 L 35.24 69.39 L 34.68 69.34 L 33.76 70.03 L 34.60 71.33 L 34.68 71.98 L 33.77 71.67 L 33.76 70.90 L 33.45 70.82 L 33.30 70.41 L 31.84 69.19 L 31.71 67.73 L 32.24 67.47 L 32.67 67.98 L 32.75 68.60 L 33.04 68.83 L 33.38 68.73 L 32.85 67.52 L 33.26 66.23 L 34.60 65.31 L 34.93 64.08 L 35.49 63.65 L 35.72 63.15 L 36.66 62.76 L 36.97 62.22 L 36.66 61.76 L 36.31 61.67 L 36.51 61.47 L 36.26 60.98 L 35.07 60.62 L 35.14 60.43 L 34.09 59.82 L 34.66 59.27 L 34.41 57.43 L 35.24 57.00 L 38.27 57.33 L 36.44 56.95 L 35.40 56.32 L 35.01 55.63 L 34.82 55.70 L 34.88 55.95 L 35.44 56.61 L 34.75 56.66 L 34.62 55.77 L 35.66 54.19 L 34.75 55.25 L 34.47 55.17 L 34.35 54.55 L 34.09 54.62 L 34.42 55.61 L 34.24 55.91 L 34.36 56.64 L 33.76 56.56 L 34.16 56.95 L 33.49 57.98 L 32.93 57.82 L 32.66 56.99 L 32.16 56.41 L 32.00 56.49 L 32.51 57.64 L 31.70 57.25 L 31.61 56.87 L 31.03 57.73 L 31.42 58.43 L 30.51 58.19 L 30.11 57.61 L 30.11 56.56 L 31.39 55.17 L 32.34 54.81 L 32.92 54.08 L 33.90 53.68 L 34.09 53.38 L 32.72 53.93 L 32.30 54.55 L 31.16 55.06 L 30.04 55.94 L 29.82 56.42 L 29.20 56.41 L 29.10 56.21 L 29.00 57.02 L 29.52 57.73 L 29.46 58.03 L 30.31 58.97 L 29.21 59.68 L 28.67 60.54 L 29.00 61.13 L 28.68 61.39 L 28.47 62.35 L 27.77 62.99 L 28.16 63.23 L 28.33 63.77 L 27.46 64.36 L 26.15 64.46 L 25.88 64.28 L 25.80 63.32 L 26.52 62.76 L 26.46 61.44 L 26.92 60.58 L 26.85 60.20 L 27.37 59.91 L 27.80 59.26 L 28.53 58.90 L 29.00 58.27 L 27.62 59.19 L 27.04 58.81 L 26.91 58.27 L 27.89 57.26 L 26.94 57.80 L 26.70 57.47 L 27.89 56.10 L 27.38 56.24 L 26.75 57.23 L 26.60 57.17 L 26.70 56.72 L 27.83 55.43 L 28.27 55.55 L 28.01 55.04 L 28.48 54.39 L 27.56 54.94 L 28.01 53.93 L 28.64 53.58 L 27.69 53.70 L 27.88 52.81 L 28.16 52.53 L 29.07 52.46 L 28.21 52.46 L 28.98 51.54 L 31.35 51.47 L 32.72 50.13 L 31.42 51.30 L 30.00 51.18 L 29.73 51.33 L 29.42 50.83 L 29.00 51.21 L 29.26 50.44 L 29.94 50.65 L 31.03 50.13 L 29.79 50.53 L 29.39 50.36 L 30.49 49.21 L 30.31 49.05 L 33.38 48.43 L 31.80 48.66 L 31.06 48.42 L 32.19 47.27 L 31.11 47.92 L 30.78 48.46 L 29.20 49.25 L 26.91 50.90 L 26.00 50.44 L 26.20 50.06 L 25.77 50.38 L 25.20 50.30 L 23.78 49.53 L 23.73 49.26 L 24.44 49.12 L 25.34 49.44 L 25.09 49.05 L 26.10 48.60 L 27.17 48.82 L 28.16 48.66 L 27.27 48.74 L 26.19 48.44 L 24.79 48.89 L 22.87 48.64 L 22.27 48.86 L 21.69 48.66 L 21.58 48.29 L 22.09 47.99 L 24.14 47.65 L 25.22 48.08 L 24.89 47.65 L 26.13 47.65 L 25.23 47.15 L 27.04 46.65 L 26.24 46.87 L 25.87 46.80 L 26.33 46.41 L 24.56 46.41 L 25.22 46.34 L 24.95 46.10 L 25.41 45.25 L 26.14 44.92 L 27.06 45.45 L 28.35 45.17 L 27.34 45.31 L 26.80 45.11 L 26.86 44.81 L 26.65 44.71 L 25.90 44.63 L 25.94 44.36 L 26.52 43.86 L 27.18 43.75 L 28.02 44.08 L 29.52 44.01 L 29.33 43.85 L 28.18 44.01 L 26.85 43.43 L 27.38 42.77 L 27.20 42.58 L 27.83 42.20 L 28.16 42.16 L 29.08 42.70 L 29.46 42.62 L 28.55 42.08 L 29.14 41.61 L 27.82 42.08 L 26.39 41.85 L 27.10 41.22 L 27.49 41.35 L 28.56 41.02 L 29.07 40.45 L 27.97 41.11 L 27.24 40.99 L 27.55 40.82 L 27.43 40.51 L 26.60 41.15 L 25.64 41.21 L 25.61 40.22 L 25.15 40.10 L 25.02 39.64 L 25.34 38.67 L 27.24 39.44 L 27.11 39.21 L 28.45 39.10 L 27.73 38.88 L 27.04 39.06 L 26.72 38.82 L 26.85 38.67 L 25.66 37.95 L 25.80 37.35 L 26.34 37.21 L 26.74 37.41 L 26.91 37.20 L 25.68 36.81 L 25.61 35.80 L 25.94 35.41 L 26.68 35.39 L 26.91 35.49 L 27.04 36.26 L 27.56 36.51 L 27.38 36.26 L 27.77 36.35 L 27.76 35.82 L 27.11 35.10 L 27.50 34.72 L 28.09 34.87 L 28.04 35.18 L 28.69 35.54 L 29.00 35.57 L 29.38 34.95 L 31.22 35.64 L 29.59 34.84 L 29.85 34.56 L 30.50 34.95 L 31.44 35.07 L 32.66 35.80 L 32.41 35.37 L 31.22 34.80 L 31.49 34.64 L 31.39 34.36 L 30.55 34.13 L 29.84 33.59 L 29.26 33.56 L 29.39 33.32 L 29.08 32.96 L 29.26 32.81 L 29.85 33.17 L 30.47 33.12 L 30.70 32.94 L 30.70 32.47 L 30.50 32.39 L 31.03 32.24 L 30.18 31.86 L 30.25 31.62 L 29.60 30.96 L 30.53 31.19 L 32.10 30.85 L 33.97 31.39 L 33.50 31.08 L 34.03 30.92 L 32.86 30.97 L 32.04 30.46 L 31.68 29.91 L 31.87 29.91 L 31.97 29.22 L 33.18 29.53 L 32.79 29.14 L 32.40 29.22 L 32.52 29.06 L 32.33 28.98 L 32.86 28.78 L 33.38 28.98 L 32.33 28.40 L 32.33 28.20 L 33.07 27.76 L 33.45 26.81 L 34.90 27.07 L 35.20 27.59 L 35.07 27.98 L 35.32 27.79 L 35.46 27.05 L 36.57 27.63 L 35.61 28.85 L 37.03 27.98 L 37.29 27.42 L 38.33 27.52 L 38.80 27.74 L 38.80 27.98 L 38.14 28.83 L 39.58 27.82 L 40.62 27.98 L 40.49 27.90 L 40.75 27.67 L 42.08 27.56 L 42.58 27.19 L 42.82 27.46 L 43.85 27.52 L 46.69 26.82 L 47.21 26.89 L 47.08 26.97 L 47.31 27.11 L 48.91 27.12 L 49.04 26.89 L 48.45 26.50 L 48.81 26.26 L 49.14 26.59 L 50.44 26.44 L 50.93 26.66 L 52.20 26.67 L 51.15 28.12 L 51.25 28.44 L 51.77 28.45 L 51.87 28.65 L 51.14 29.74 L 50.28 30.46 L 48.71 30.92 L 47.47 32.01 L 44.67 33.33 L 44.27 33.87 L 42.94 34.36 L 42.84 34.64 L 42.05 34.32 L 42.12 34.56 L 42.97 34.95 L 42.77 35.41 L 40.01 35.46 L 39.12 34.95 L 39.93 35.59 L 40.87 35.50 L 41.43 35.84 L 41.53 35.64 L 42.48 35.97 L 43.01 35.70 L 43.67 36.09 L 44.78 35.42 L 44.96 35.54 L 42.97 37.35 L 42.63 37.33 L 42.70 37.04 L 42.45 36.88 L 42.11 36.96 L 41.25 37.42 L 40.05 37.53 L 38.93 38.40 L 38.78 38.69 L 39.24 38.56 L 40.93 37.59 L 41.94 37.78 L 42.77 37.43 L 42.62 37.81 L 41.73 38.51 L 41.86 38.67 L 41.23 38.77 L 41.10 39.02 L 40.36 38.98 L 40.88 39.13 L 40.49 39.59 L 41.00 39.66 L 42.52 38.92 L 42.06 38.59 L 44.41 38.51 L 46.43 37.73 L 46.23 37.97 L 46.75 37.97 L 46.56 37.66 L 47.28 37.73 L 47.70 37.16 L 48.48 37.04 L 49.67 37.07 L 52.05 37.66 L 53.18 37.27 L 57.78 37.66 L 58.77 37.60 L 59.09 37.35 L 59.91 37.58 L 60.87 37.25 L 61.93 37.27 L 63.53 38.28 L 63.81 39.27 L 64.18 39.59 L 63.99 39.79 L 64.20 39.86 L 62.09 41.61 L 61.25 43.24 L 61.44 43.87 L 60.12 45.39 L 60.13 46.18 L 58.86 47.46 L 57.84 48.03 L 57.00 49.84 L 55.24 50.83 L 54.97 51.21 L 51.80 51.42 L 50.11 52.36 L 49.30 52.39 L 50.18 52.50 L 53.48 51.34 L 54.26 51.68 L 53.93 52.39 L 54.26 52.62 L 55.66 52.88 L 56.41 53.38 L 55.73 53.94 L 54.44 54.35 L 52.72 54.20 L 51.17 55.13 L 50.82 55.80 L 49.12 56.21 L 45.99 55.95 L 44.41 55.32 L 46.13 56.41 L 49.23 56.59 L 51.22 56.87 L 51.64 57.12 L 52.95 56.87 L 53.73 56.41 L 53.61 56.17 L 54.07 55.85 L 55.86 55.87 L 56.48 56.24 L 56.35 56.49 L 57.07 56.41 L 58.97 57.26 L 60.59 57.49 L 63.65 60.67 L 63.99 60.53 L 64.31 60.83 L 64.11 60.90 L 64.77 60.90 L 65.42 61.21 L 65.42 61.75 L 65.86 62.36 L 66.02 64.67 L 66.59 65.63 L 66.50 66.05 L 67.50 67.82 L 67.97 68.22 L 68.04 68.91 L 68.81 70.67 L 69.79 71.20 L 69.60 71.34 L 69.86 71.75 L 69.49 72.06 L 69.97 72.20 L 70.11 71.82 L 73.45 72.79 L 75.59 73.73 L 76.69 74.91 L 77.42 76.33 L 78.31 76.67 L 78.72 77.32 L 80.23 77.86 L 79.39 78.19 L 78.86 78.87 L 79.51 80.27 L 82.22 83.17 L 82.37 83.54 L 82.20 83.95 L 82.00 84.07 L 82.25 83.53 L 82.10 83.45 L 81.28 83.13 L 80.07 83.30 L 78.47 82.12 L 75.77 82.41 L 74.89 82.16 L 74.03 82.51 L 74.36 82.67 L 75.05 82.39 L 75.91 82.77 L 78.29 82.44 L 79.16 83.42 L 82.40 85.06 L 83.04 85.69 L 84.21 87.88 L 84.35 88.79 L 84.09 89.46 L 82.48 90.33 L 81.05 91.72 L 81.96 91.69 L 83.30 92.74 L 84.05 92.66 L 84.61 93.05 L 84.56 92.80 L 85.13 92.24 L 85.58 91.19 L 86.38 90.78 L 87.47 90.59 L 90.18 91.03 L 90.61 90.89 L 90.15 90.72 L 93.09 91.24 L 96.61 92.97 L 97.11 93.48 L 97.59 94.67 L 97.82 96.25 L 96.48 98.68 L 96.48 99.48 L 96.02 100.82 L 94.97 101.10 L 93.64 102.42 L 92.99 101.80 L 91.98 101.42 L 93.05 101.95 L 93.06 102.23 L 91.13 102.27 L 93.16 102.34 L 92.38 103.12 L 92.99 103.28 L 93.21 103.08 L 93.11 103.49 L 92.07 104.11 L 91.10 104.28 L 90.28 103.51 L 90.12 103.84 L 89.40 104.20 L 89.27 104.60 L 87.61 104.90 L 88.20 105.21 L 89.81 104.64 L 90.02 105.37 L 89.63 105.99 L 90.02 106.07 L 89.76 106.39 L 88.30 107.07 L 87.15 106.99 L 86.37 107.30 L 85.30 107.33 L 85.03 107.76 L 84.61 107.92 L 86.05 107.49 L 87.57 107.65 L 87.84 107.99 L 86.41 108.30 L 86.23 108.38 L 86.44 108.59 L 87.74 108.70 L 87.62 108.41 L 87.87 108.31 L 88.23 108.92 L 90.26 109.10 L 94.51 108.61 L 94.75 108.72 L 94.62 109.16 L 94.07 109.36 L 94.41 110.54 L 94.14 111.33 L 92.31 112.11 L 91.11 112.32 L 90.16 113.24 L 90.28 113.97 L 88.21 113.82 L 86.90 114.64 L 84.43 115.09 L 83.53 115.90 L 78.38 114.95 L 77.17 115.28 L 73.73 115.56 L 73.43 116.10 L 72.34 115.62 L 72.73 115.21 L 72.11 115.05 L 72.01 114.82 L 71.23 114.81 L 70.89 115.50 L 70.64 115.52 L 70.45 115.36 L 70.77 114.81 L 69.86 114.81 L 70.25 115.09 L 70.24 115.43 L 69.99 115.51 L 66.99 113.97 L 68.35 115.01 L 68.41 115.30 L 66.43 115.74 L 66.08 116.22 L 64.83 115.98 L 64.08 116.21 L 63.26 116.13 L 62.48 116.54 L 62.39 116.28 L 61.70 116.21 L 61.53 115.98 L 61.12 116.45 L 61.57 116.28 L 61.88 116.65 L 62.35 116.70 L 62.55 117.06 L 62.24 117.54 L 61.28 117.62 L 58.11 117.05 L 57.52 117.49 L 57.47 117.73 L 57.82 118.04 L 57.59 118.38 L 57.30 117.67 L 55.31 116.52 L 53.67 116.05 L 49.91 116.72 L 49.57 117.14 L 48.87 117.37 L 48.37 117.23 L 47.96 116.68 L 48.25 117.45 L 47.56 118.46 L 47.74 119.15 L 47.08 119.46 L 47.74 119.77 L 47.36 120.39 L 46.95 120.32 L 46.36 120.82 L 46.09 121.85 L 44.87 121.95 L 43.23 120.70 L 42.34 120.95 L 41.83 120.54 L 41.86 120.16 L 41.22 120.02 L 41.03 119.63 L 41.34 119.15 L 40.95 119.15 L 40.62 119.39 L 40.68 119.86 L 40.10 119.86 L 41.01 120.09 L 40.68 120.16 L 41.14 120.32 L 41.01 120.70 L 40.45 120.32 L 39.64 120.16 L 38.14 120.64 L 36.44 120.78 L 36.24 120.47 L 35.59 120.71 L 35.24 121.75 L 34.76 121.70 L 33.84 122.09 L 33.31 122.72 L 33.14 122.18 L 32.83 122.13 L 32.72 122.56 L 32.92 122.72 L 32.13 123.26 L 32.66 123.34 L 32.80 123.66 L 31.51 124.81 L 31.00 124.43 L 30.43 123.44 L 28.81 122.87 L 28.18 123.07 L 28.24 123.42 L 27.97 123.67 L 26.62 123.76 L 26.58 122.85 L 26.81 122.52 L 28.47 121.87 L 29.16 122.15 L 29.64 121.63 L 30.33 121.48 L 31.91 120.39 L 31.87 119.83 L 32.85 119.50 L 33.18 118.27 L 33.84 117.99 L 33.97 118.47 L 34.81 118.54 L 34.08 118.08 L 34.09 117.69 L 35.31 117.62 L 35.70 116.77 L 37.36 115.59 L 37.62 115.20 L 37.84 112.87 L 39.64 113.08 L 40.88 112.18 L 40.42 111.33 L 40.81 111.33 L 40.68 110.87 L 45.06 110.24 L 48.25 110.67 L 48.71 110.94 L 52.10 110.55 L 52.17 110.87 L 52.38 110.41 L 52.17 109.39 L 52.46 109.40 L 52.77 108.81 L 52.62 108.70 L 53.13 108.58 L 54.30 107.59 L 55.08 107.40 L 56.61 105.59 L 57.48 104.84 L 58.20 104.56 L 58.11 104.20 L 57.90 104.53 L 57.31 104.65 L 55.57 106.07 Z M 70.64 116.28 L 70.83 116.60 L 69.94 116.99 L 69.82 117.53 L 68.77 117.76 L 66.80 116.78 L 66.00 116.91 L 66.61 116.35 L 67.44 116.05 L 67.38 116.21 L 67.61 116.19 L 68.40 115.62 L 70.64 116.28 Z M 89.63 108.38 L 89.93 108.71 L 89.63 108.92 L 88.33 108.80 L 87.94 108.38 L 88.26 107.98 L 89.63 108.38 Z M 37.36 87.36 L 37.54 87.58 L 37.32 87.70 L 36.25 86.93 L 36.89 86.81 L 37.36 87.36 Z M 41.92 86.93 L 42.45 87.01 L 41.92 87.61 L 40.99 87.94 L 40.19 88.68 L 38.98 88.96 L 39.19 88.37 L 38.59 88.63 L 38.14 88.40 L 38.10 88.05 L 37.42 87.32 L 37.42 85.99 L 38.81 85.61 L 39.76 85.69 L 40.22 85.90 L 40.92 87.06 L 41.92 86.93 Z M 32.66 62.07 L 32.45 62.17 L 32.59 62.68 L 31.78 62.91 L 30.04 62.37 L 30.04 61.61 L 29.54 60.88 L 29.72 60.27 L 30.57 59.82 L 30.50 59.65 L 31.44 59.86 L 31.94 60.42 L 32.02 61.13 L 32.44 61.42 L 32.19 61.91 L 32.66 62.07 Z M 33.05 59.35 L 33.24 59.58 L 33.06 59.65 L 32.23 58.96 L 31.43 57.53 L 31.74 57.42 L 32.56 57.88 L 33.13 58.72 L 33.05 59.35 Z M 23.52 59.58 L 23.59 60.12 L 23.25 60.36 L 21.76 60.74 L 21.65 61.02 L 21.07 61.29 L 20.85 61.23 L 20.77 60.72 L 21.49 60.36 L 21.17 59.87 L 20.71 59.74 L 21.43 59.04 L 20.68 58.97 L 19.40 60.20 L 19.01 60.12 L 19.01 59.65 L 19.54 59.04 L 19.22 58.89 L 19.57 58.23 L 20.65 57.77 L 20.59 58.27 L 20.85 58.57 L 20.98 58.02 L 22.47 57.18 L 22.66 57.32 L 22.86 58.77 L 23.52 59.58 Z M 21.85 55.36 L 22.50 55.11 L 22.15 56.03 L 21.24 56.10 L 21.85 55.36 Z M 25.74 55.25 L 26.51 54.79 L 26.77 55.26 L 26.28 55.66 L 24.89 57.80 L 24.33 58.12 L 24.17 58.73 L 23.22 58.68 L 23.09 57.47 L 24.89 56.79 L 23.99 56.86 L 23.97 56.42 L 25.74 55.25 Z M 16.01 50.44 L 16.74 50.33 L 16.86 50.53 L 15.53 51.10 L 15.41 51.50 L 14.62 51.32 L 14.38 50.83 L 16.01 50.44 Z M 26.78 51.61 L 27.07 52.00 L 26.64 52.07 L 26.26 51.84 L 25.87 52.39 L 26.55 52.22 L 26.64 52.40 L 25.63 52.92 L 24.95 52.84 L 25.20 52.64 L 25.02 52.48 L 23.18 53.25 L 21.53 53.31 L 21.27 53.54 L 20.69 53.39 L 20.32 52.88 L 20.85 52.60 L 21.46 53.00 L 21.63 52.84 L 21.43 52.76 L 23.00 52.53 L 23.61 52.20 L 22.34 52.46 L 21.87 52.22 L 22.60 51.45 L 23.72 51.21 L 23.65 50.83 L 22.60 51.16 L 22.15 50.68 L 20.59 50.28 L 21.04 50.06 L 20.71 49.67 L 21.62 49.64 L 21.71 49.37 L 22.37 49.15 L 23.25 49.28 L 23.20 49.51 L 23.73 49.75 L 24.17 50.57 L 25.77 50.68 L 26.57 51.04 L 27.16 51.46 L 27.11 51.68 L 26.78 51.61 Z M 19.44 48.86 L 19.07 49.35 L 17.94 50.02 L 17.44 49.99 L 17.35 50.21 L 17.12 49.90 L 18.48 49.00 L 19.15 48.74 L 19.44 48.86 Z M 10.53 45.10 L 10.73 45.41 L 10.37 45.45 L 10.04 45.82 L 8.98 45.75 L 9.37 45.43 L 9.29 45.10 L 9.93 44.86 L 10.01 44.56 L 10.34 44.71 L 10.14 44.95 L 10.53 45.10 Z M 20.71 44.56 L 21.49 45.10 L 21.18 45.75 L 20.55 45.87 L 19.47 45.17 L 20.71 44.56 Z M 11.96 41.54 L 12.42 41.76 L 11.84 42.54 L 10.92 42.47 L 11.70 42.77 L 11.81 43.41 L 10.99 43.55 L 11.65 43.55 L 12.23 43.93 L 10.92 44.09 L 10.56 43.76 L 10.34 42.77 L 9.95 42.54 L 10.57 41.69 L 10.21 40.84 L 10.92 40.60 L 12.17 41.38 L 11.70 41.40 L 10.75 40.84 L 10.53 40.91 L 10.76 41.20 L 11.96 41.54 Z M 11.78 39.76 L 12.36 39.99 L 11.78 40.14 L 12.33 40.49 L 11.25 40.60 L 10.40 40.18 L 10.77 39.69 L 11.78 39.76 Z M 23.20 41.30 L 23.15 40.29 L 23.65 39.99 L 23.46 39.68 L 23.85 39.68 L 23.80 39.46 L 23.98 39.59 L 23.65 40.84 L 23.91 41.29 L 23.29 41.53 L 23.20 41.30 Z M 13.05 37.84 L 13.67 38.05 L 13.34 38.35 L 12.66 37.97 L 12.23 38.05 L 12.82 38.58 L 13.28 38.51 L 13.09 38.76 L 12.04 38.98 L 11.84 38.75 L 11.31 38.98 L 12.91 39.02 L 12.79 39.44 L 11.38 39.44 L 10.99 39.06 L 11.25 38.98 L 9.10 38.51 L 9.75 37.73 L 10.60 37.73 L 10.34 37.89 L 10.51 38.04 L 11.31 37.43 L 11.12 37.73 L 11.64 37.87 L 12.56 37.43 L 12.71 37.64 L 12.48 37.81 L 13.05 37.84 Z M 18.44 41.30 L 17.18 41.10 L 16.34 40.06 L 16.93 40.06 L 16.69 39.70 L 16.99 39.40 L 18.03 40.20 L 18.10 39.91 L 17.80 39.55 L 18.44 39.52 L 17.57 38.98 L 17.80 38.70 L 17.71 38.35 L 19.38 39.42 L 19.80 39.36 L 19.59 39.70 L 20.00 39.33 L 20.85 39.99 L 20.10 38.97 L 20.38 38.51 L 20.00 38.44 L 19.85 37.92 L 20.85 37.27 L 22.34 38.55 L 22.54 39.83 L 22.41 40.41 L 22.02 40.76 L 22.60 40.60 L 22.52 41.18 L 22.86 41.46 L 22.34 41.76 L 23.38 41.73 L 23.07 42.08 L 23.73 41.98 L 24.54 42.20 L 24.76 42.47 L 26.02 42.08 L 27.17 42.23 L 26.75 43.07 L 25.89 43.34 L 25.71 43.82 L 24.43 44.75 L 23.75 44.90 L 23.55 44.51 L 23.93 43.88 L 25.28 43.09 L 23.94 43.24 L 23.39 42.62 L 23.59 43.00 L 22.97 43.78 L 22.73 43.09 L 22.24 42.94 L 22.12 43.17 L 20.78 43.40 L 21.17 42.93 L 20.52 43.09 L 20.19 42.70 L 20.52 42.47 L 19.92 42.47 L 19.22 41.69 L 19.84 41.44 L 20.72 41.70 L 19.94 41.24 L 19.40 41.30 L 19.54 41.14 L 19.28 41.07 L 19.28 40.68 L 18.82 40.91 L 18.76 40.52 L 18.37 40.84 L 18.44 41.30 Z M 14.71 36.81 L 14.47 36.91 L 13.09 35.76 L 13.36 35.74 L 13.53 36.03 L 14.43 35.44 L 15.10 35.41 L 14.64 35.10 L 15.41 34.88 L 15.88 35.02 L 15.56 34.80 L 15.82 34.64 L 14.19 34.42 L 13.21 34.02 L 13.79 33.78 L 13.73 33.63 L 14.91 33.32 L 13.73 33.48 L 14.06 33.32 L 13.79 33.25 L 14.06 33.01 L 13.57 33.21 L 13.21 32.78 L 13.11 32.37 L 13.40 32.01 L 13.21 31.86 L 14.12 31.77 L 13.73 31.50 L 13.99 31.15 L 15.17 31.46 L 14.88 31.53 L 15.62 32.70 L 15.36 32.01 L 15.53 31.77 L 16.21 31.63 L 16.79 32.01 L 17.05 31.77 L 16.34 31.31 L 16.08 30.92 L 16.27 30.85 L 16.01 30.69 L 16.99 30.07 L 18.50 29.75 L 21.26 28.12 L 21.69 28.27 L 22.22 29.17 L 21.76 29.76 L 22.21 30.00 L 20.78 30.88 L 20.78 31.15 L 20.32 31.23 L 21.23 31.47 L 22.37 30.99 L 22.29 31.46 L 21.59 31.83 L 20.00 31.54 L 20.26 32.32 L 19.15 32.78 L 17.91 32.94 L 19.93 32.70 L 20.32 33.25 L 20.00 33.40 L 20.45 33.48 L 19.77 33.87 L 18.62 33.71 L 19.47 34.18 L 18.98 34.64 L 18.56 34.56 L 18.69 34.80 L 18.30 34.85 L 17.81 34.40 L 17.91 34.87 L 17.51 34.72 L 17.05 33.87 L 17.47 33.41 L 18.17 33.25 L 17.25 33.25 L 16.53 33.87 L 17.39 34.72 L 17.18 34.80 L 17.51 35.27 L 16.31 35.06 L 16.14 35.27 L 16.53 35.41 L 16.74 35.82 L 16.27 35.88 L 16.34 36.03 L 15.69 35.80 L 15.82 36.03 L 15.36 36.35 L 15.49 36.42 L 14.71 36.81 Z M 52.83 24.42 L 53.49 24.51 L 53.15 24.80 L 53.23 25.45 L 52.95 25.65 L 52.50 25.35 L 52.63 25.19 L 52.23 24.73 L 52.69 24.64 L 52.04 24.64 L 52.83 24.42 Z M 50.02 24.96 L 51.13 24.80 L 50.89 25.02 L 49.53 25.11 L 48.77 24.03 L 48.28 24.02 L 48.42 23.65 L 49.17 23.41 L 50.04 23.78 L 50.74 24.64 L 50.02 24.96 Z M 54.97 22.94 L 55.18 23.37 L 54.06 23.95 L 53.08 23.68 L 52.56 23.06 L 51.58 23.25 L 51.71 23.41 L 51.26 23.56 L 50.45 23.56 L 50.11 23.16 L 50.41 22.55 L 50.21 22.17 L 50.09 22.48 L 49.75 22.48 L 49.93 22.85 L 49.62 23.17 L 49.30 23.09 L 48.89 22.43 L 49.30 21.17 L 50.64 20.95 L 51.58 21.16 L 51.91 21.39 L 51.71 21.46 L 52.43 21.78 L 51.78 22.05 L 51.13 22.55 L 51.27 22.63 L 51.81 22.71 L 52.27 22.41 L 53.54 22.63 L 53.47 22.87 L 54.47 22.72 L 53.93 23.17 L 54.34 23.44 L 54.52 23.41 L 54.32 23.10 L 54.97 22.94 Z M 56.74 21.25 L 57.00 21.55 L 56.83 21.66 L 56.22 21.78 L 56.20 21.52 L 55.86 21.38 L 55.72 21.64 L 55.37 21.60 L 56.02 21.16 L 55.57 20.85 L 56.08 20.78 L 56.02 20.93 L 56.48 21.00 L 56.26 21.04 L 56.35 21.25 L 56.74 21.25 Z M 52.34 21.16 L 51.51 20.99 L 51.23 20.61 L 51.67 20.38 L 52.83 20.54 L 52.62 21.10 L 52.34 21.16 Z M 54.00 20.38 L 54.42 20.38 L 54.40 19.81 L 54.66 19.76 L 54.58 19.92 L 54.97 20.07 L 54.66 20.43 L 54.91 20.93 L 54.39 20.97 L 54.00 20.38 Z M 57.65 19.30 L 57.99 19.00 L 58.17 19.38 L 57.53 19.45 L 57.10 19.97 L 56.99 19.76 L 56.41 20.07 L 56.48 19.84 L 56.15 19.84 L 55.31 20.44 L 55.35 20.14 L 56.23 19.61 L 56.08 19.30 L 56.93 19.14 L 56.54 19.61 L 57.65 19.30 Z M 51.91 18.99 L 51.65 18.83 L 52.30 18.83 L 52.71 18.53 L 52.89 18.66 L 52.50 18.99 L 53.38 19.18 L 54.00 19.76 L 53.47 20.00 L 53.61 19.69 L 52.88 19.32 L 52.62 19.30 L 52.76 19.54 L 52.30 19.54 L 51.91 18.99 Z M 73.48 4.35 L 73.73 4.44 L 73.71 4.66 L 72.66 4.66 L 72.80 4.89 L 72.01 4.20 L 73.48 4.35 Z M 70.50 6.60 L 71.10 6.21 L 70.24 6.97 L 70.78 6.82 L 70.76 7.24 L 69.79 7.37 L 70.71 7.68 L 70.11 8.02 L 70.57 8.22 L 70.02 8.49 L 69.59 8.22 L 69.67 8.53 L 69.34 8.61 L 69.72 8.68 L 69.53 9.00 L 69.93 8.76 L 69.59 9.31 L 69.95 9.13 L 69.93 9.38 L 70.25 9.61 L 69.53 9.85 L 69.62 10.02 L 69.40 10.09 L 69.86 10.62 L 69.34 10.86 L 69.51 11.46 L 69.07 11.33 L 68.81 12.95 L 68.47 12.82 L 68.56 12.56 L 67.85 12.34 L 68.04 11.92 L 68.35 11.86 L 68.10 11.56 L 68.35 11.56 L 68.93 10.00 L 68.68 9.54 L 68.86 9.21 L 68.45 9.26 L 68.88 8.53 L 68.29 9.00 L 68.02 8.54 L 67.51 8.38 L 68.10 8.92 L 68.03 9.08 L 67.64 8.92 L 67.58 9.28 L 67.44 9.15 L 67.09 9.54 L 66.41 9.12 L 66.99 8.85 L 66.63 8.55 L 66.43 8.90 L 66.21 8.71 L 65.48 8.85 L 65.05 8.60 L 64.86 8.08 L 65.35 7.78 L 66.21 7.99 L 66.14 7.84 L 66.84 7.73 L 66.99 8.15 L 67.40 7.62 L 67.96 8.07 L 68.23 7.84 L 67.96 7.68 L 68.16 7.37 L 68.95 7.29 L 68.21 7.07 L 68.16 6.83 L 67.67 6.90 L 67.77 6.52 L 67.25 6.43 L 67.18 5.74 L 66.86 6.13 L 66.68 6.00 L 66.86 5.82 L 65.63 5.84 L 66.41 5.01 L 67.09 5.55 L 67.77 5.52 L 66.86 5.21 L 67.51 4.74 L 67.44 4.43 L 68.42 4.59 L 68.34 4.28 L 68.56 4.04 L 68.65 4.53 L 68.23 5.28 L 68.42 5.28 L 68.23 5.36 L 68.42 5.44 L 68.23 5.82 L 68.62 5.74 L 67.90 6.76 L 69.20 6.29 L 68.62 5.98 L 68.84 5.83 L 68.95 6.05 L 69.36 5.67 L 69.98 6.43 L 69.33 6.68 L 69.85 6.65 L 70.05 6.91 L 70.44 6.43 L 70.50 6.60 Z M 71.55 3.42 L 71.49 4.12 L 70.83 3.81 L 71.30 4.35 L 70.77 4.35 L 71.32 4.77 L 71.03 5.05 L 71.20 5.62 L 70.47 5.48 L 70.50 5.74 L 69.96 5.56 L 69.71 4.24 L 69.80 4.00 L 70.11 3.97 L 70.19 4.30 L 70.44 4.35 L 70.34 3.22 L 70.55 2.99 L 70.77 3.19 L 71.49 3.04 L 71.55 3.42 Z M 72.34 3.57 L 71.75 3.50 L 71.88 2.80 L 72.13 2.60 L 72.01 2.26 L 72.56 1.75 L 72.80 1.99 L 72.49 2.38 L 73.12 1.72 L 73.60 1.88 L 73.71 2.11 L 73.45 2.18 L 73.71 2.26 L 73.25 2.50 L 73.32 2.72 L 73.13 2.73 L 73.32 2.88 L 72.86 3.19 L 73.12 3.56 L 72.34 3.57 Z M 70.83 9.45 L 70.73 10.09 L 70.26 9.91 L 70.14 9.28 L 70.67 9.18 L 70.83 9.45 Z";

// Accurate-enough Ireland outline (RoI + NI), same projection.
const UK_IRELAND_PATH = "M 11.93 67.04 L 10.90 67.36 L 10.43 67.79 L 9.95 69.37 L 9.11 70.17 L 9.11 70.75 L 8.10 70.71 L 6.95 71.15 L 6.23 70.87 L 5.43 71.25 L 6.22 71.99 L 7.52 72.07 L 7.54 72.30 L 5.84 73.12 L 4.74 72.99 L 4.07 73.62 L 3.11 73.91 L 4.22 74.99 L 4.74 75.08 L 5.23 75.73 L 5.90 75.89 L 6.13 76.74 L 7.57 76.87 L 8.49 77.55 L 9.50 77.72 L 10.34 77.48 L 10.53 77.75 L 11.17 77.85 L 11.33 77.83 L 11.18 77.38 L 11.47 77.26 L 11.45 77.71 L 11.62 77.70 L 11.91 76.90 L 12.83 76.60 L 12.90 76.28 L 12.29 75.81 L 12.45 75.35 L 14.12 74.46 L 15.43 75.27 L 15.65 75.82 L 15.41 76.00 L 15.83 76.19 L 16.31 76.84 L 16.72 77.05 L 17.19 76.89 L 17.71 77.23 L 17.40 78.36 L 17.80 78.66 L 20.21 78.42 L 20.43 77.88 L 21.10 77.94 L 22.79 78.98 L 22.28 79.42 L 20.38 78.95 L 20.21 79.87 L 20.47 80.47 L 21.49 80.65 L 21.38 81.14 L 21.69 81.43 L 21.44 81.89 L 21.62 83.01 L 23.07 84.17 L 22.54 85.22 L 21.95 85.22 L 22.57 85.43 L 22.60 85.92 L 23.33 86.08 L 23.22 86.28 L 22.55 86.01 L 21.73 86.51 L 22.33 87.05 L 22.89 87.21 L 22.81 87.84 L 23.52 89.18 L 23.32 90.33 L 23.87 90.92 L 22.57 92.51 L 22.40 93.30 L 21.76 94.21 L 21.82 95.57 L 20.42 97.12 L 20.32 97.85 L 19.34 97.67 L 19.40 97.47 L 19.08 97.62 L 19.91 98.47 L 20.26 98.09 L 20.10 98.40 L 20.78 99.02 L 20.50 99.51 L 20.13 99.71 L 20.06 99.33 L 19.76 99.55 L 19.31 99.40 L 18.12 99.71 L 16.99 99.29 L 16.14 99.33 L 16.53 98.79 L 15.88 99.02 L 16.01 99.63 L 14.93 100.33 L 14.77 100.26 L 15.20 99.79 L 14.31 98.47 L 14.58 99.25 L 14.48 99.64 L 14.71 99.71 L 14.12 100.17 L 13.28 100.26 L 13.60 99.87 L 13.27 99.78 L 13.28 100.02 L 12.86 99.97 L 12.50 100.24 L 10.14 100.32 L 8.90 100.79 L 8.57 100.60 L 8.31 101.03 L 9.09 101.12 L 8.74 101.42 L 8.67 101.84 L 7.53 102.03 L 7.40 102.37 L 6.39 102.27 L 6.19 101.96 L 6.00 102.54 L 5.50 102.74 L 5.90 102.96 L 5.80 103.07 L 4.68 103.37 L 4.57 103.73 L 2.42 103.97 L 2.57 103.58 L 3.09 103.35 L 2.83 103.28 L 2.98 102.95 L 0.87 102.96 L 0.67 103.04 L 1.63 103.31 L 1.45 103.66 L 1.92 103.66 L 1.98 103.89 L 1.72 103.97 L 2.05 103.97 L 1.93 104.38 L 1.47 104.85 L 0.61 105.21 L 0.15 104.97 L 0.34 105.19 L 0.15 105.37 L 0.08 105.15 L -0.56 105.06 L 0.02 105.21 L -0.37 105.71 L -0.30 106.14 L -0.69 105.75 L -2.45 105.75 L -1.81 105.91 L -1.87 106.52 L -3.37 106.31 L -4.13 106.99 L -4.68 106.68 L -5.46 106.83 L -5.91 106.68 L -5.86 106.96 L -6.60 107.11 L -6.89 107.53 L -7.28 107.53 L -7.35 107.30 L -8.39 107.69 L -8.06 107.38 L -8.31 107.49 L -8.26 107.30 L -7.81 106.99 L -8.59 107.38 L -8.59 106.87 L -8.98 106.72 L -10.58 107.46 L -11.01 107.16 L -11.46 107.69 L -12.57 108.01 L -12.70 107.53 L -9.96 106.14 L -12.83 106.83 L -10.42 105.63 L -9.13 105.31 L -8.98 104.90 L -9.77 104.83 L -10.10 104.43 L -9.96 104.90 L -10.73 105.30 L -13.09 105.63 L -14.56 106.30 L -15.77 106.45 L -15.71 106.14 L -14.86 105.91 L -14.96 105.62 L -15.25 105.59 L -15.12 105.45 L -14.32 105.38 L -13.87 105.06 L -14.26 104.97 L -14.10 104.77 L -13.22 104.43 L -13.35 104.67 L -13.03 104.58 L -12.90 104.28 L -12.24 104.36 L -12.51 104.13 L -11.79 103.58 L -10.29 103.12 L -11.98 103.47 L -12.99 103.95 L -13.16 103.73 L -15.58 104.67 L -15.52 104.52 L -16.42 104.20 L -16.06 104.12 L -15.97 103.85 L -16.52 103.42 L -17.53 104.13 L -17.53 103.51 L -17.99 103.48 L -18.05 103.04 L -16.71 102.77 L -17.21 102.27 L -16.75 102.03 L -16.82 101.87 L -14.60 101.27 L -14.01 100.72 L -13.58 101.03 L -13.41 100.26 L -12.11 100.33 L -12.31 100.17 L -11.98 100.02 L -13.87 100.10 L -13.85 100.51 L -14.26 100.17 L -16.06 100.50 L -16.94 100.20 L -17.21 100.33 L -16.88 100.48 L -17.79 100.33 L -17.66 100.48 L -18.44 100.64 L -18.74 100.44 L -18.68 99.70 L -18.18 99.48 L -18.25 99.63 L -17.83 99.75 L -17.78 99.16 L -15.92 98.50 L -15.87 99.09 L -15.25 99.02 L -14.71 98.70 L -14.63 98.46 L -14.86 98.24 L -14.41 98.28 L -14.37 98.88 L -13.79 99.05 L -13.07 99.11 L -12.62 98.82 L -12.48 99.00 L -11.79 98.93 L -13.04 98.65 L -13.15 98.39 L -12.85 98.52 L -12.70 98.47 L -12.97 98.31 L -12.63 98.24 L -12.71 97.50 L -13.81 97.08 L -11.46 96.27 L -10.81 96.39 L -11.27 96.15 L -10.94 95.29 L -7.35 95.21 L -5.26 94.60 L -4.82 94.72 L -4.38 94.37 L -2.39 94.13 L -4.39 93.90 L -4.48 93.28 L -4.22 92.98 L -4.99 93.29 L -6.16 94.69 L -7.48 95.06 L -7.93 94.98 L -7.42 94.51 L -8.90 94.82 L -10.29 94.21 L -10.03 94.51 L -11.38 94.89 L -11.49 95.18 L -13.68 95.45 L -12.61 95.01 L -10.68 93.67 L -10.75 93.52 L -9.51 93.23 L -9.44 92.66 L -8.13 91.19 L -9.31 91.11 L -8.45 90.34 L -7.35 88.78 L -6.27 89.18 L -5.46 89.10 L -5.43 88.91 L -5.98 88.63 L -4.80 88.79 L -5.20 88.47 L -4.64 88.43 L -4.16 88.79 L -4.35 88.40 L -3.76 87.94 L -5.20 87.94 L -4.41 87.78 L -4.68 87.63 L -4.22 87.48 L -4.97 87.32 L -9.64 87.85 L -10.16 87.48 L -10.04 87.15 L -10.59 87.77 L -10.64 86.80 L -10.10 86.58 L -10.49 86.31 L -10.03 86.08 L -10.68 86.16 L -10.54 86.49 L -10.81 86.70 L -10.98 85.99 L -11.84 86.88 L -12.44 87.03 L -13.35 86.77 L -13.21 86.37 L -12.24 85.99 L -12.57 85.92 L -12.37 85.69 L -12.95 85.98 L -13.15 85.84 L -12.83 85.53 L -13.44 85.62 L -13.55 86.03 L -13.92 86.14 L -14.42 86.12 L -14.89 85.77 L -15.97 85.77 L -15.64 85.40 L -14.79 85.31 L -15.12 84.99 L -14.40 84.99 L -15.31 84.85 L -15.74 84.29 L -16.22 84.29 L -16.00 84.16 L -15.31 84.22 L -15.38 83.99 L -14.96 83.99 L -14.34 84.29 L -14.01 84.07 L -14.73 83.66 L -13.03 83.46 L -11.40 83.67 L -13.41 83.13 L -13.41 81.82 L -10.16 81.43 L -10.68 81.20 L -10.10 80.65 L -10.35 80.58 L -10.16 80.27 L -11.98 80.27 L -13.44 80.73 L -13.75 80.49 L -13.41 80.03 L -13.48 79.65 L -13.03 79.57 L -12.26 80.08 L -12.24 79.73 L -12.50 79.51 L -12.68 79.62 L -12.85 79.16 L -13.32 78.84 L -13.31 78.51 L -12.70 77.86 L -13.15 77.86 L -13.50 78.34 L -14.01 78.24 L -14.20 77.95 L -13.41 77.79 L -14.07 77.09 L -13.68 77.01 L -14.39 76.66 L -14.45 77.00 L -14.79 77.01 L -14.66 77.24 L -15.12 77.33 L -14.92 77.72 L -15.19 77.79 L -14.92 78.06 L -15.40 78.05 L -15.51 77.72 L -14.86 76.62 L -15.38 76.47 L -14.26 75.69 L -14.02 76.00 L -13.15 76.16 L -13.59 76.57 L -14.07 76.39 L -14.13 76.61 L -13.43 76.82 L -13.03 76.55 L -13.10 76.23 L -12.80 76.00 L -12.05 76.24 L -12.37 75.93 L -11.98 75.93 L -12.66 75.77 L -12.82 75.50 L -12.24 75.31 L -11.49 75.54 L -7.32 75.69 L -7.12 76.00 L -6.77 76.01 L -6.77 76.67 L -6.18 77.09 L -6.11 77.48 L -6.05 76.78 L -5.62 76.57 L -5.25 75.86 L -4.18 75.85 L -3.40 76.16 L -1.68 76.06 L -0.69 76.87 L -0.11 76.78 L -1.15 76.24 L -0.89 75.93 L 0.28 76.00 L -0.66 75.67 L -0.64 75.47 L -0.30 75.62 L -0.18 75.44 L -1.54 75.31 L -1.56 75.07 L 0.25 74.27 L 0.32 73.76 L 0.54 74.07 L 2.76 73.46 L 2.18 73.21 L 2.70 72.91 L 2.68 72.69 L 3.12 72.41 L 3.09 72.13 L 3.45 72.28 L 3.61 71.82 L 1.98 72.28 L 2.09 72.01 L 1.89 71.90 L 0.41 72.75 L 1.10 72.28 L 0.95 72.02 L 0.74 72.13 L 0.77 71.88 L 0.37 72.32 L 0.06 71.98 L -0.61 72.25 L -1.64 72.13 L -1.82 71.88 L -2.78 71.67 L -2.65 71.44 L -2.84 71.31 L -1.30 70.44 L 0.41 70.58 L -0.28 70.22 L 0.87 70.51 L -0.56 69.89 L 0.09 69.50 L 1.66 69.73 L 1.13 69.45 L 1.27 69.17 L 1.78 69.19 L 1.55 68.92 L 0.86 69.10 L 0.47 68.71 L 0.47 68.43 L 1.27 68.41 L 0.41 67.79 L 0.81 67.79 L 1.45 67.10 L 1.71 67.44 L 1.71 66.64 L 2.11 66.01 L 2.79 66.17 L 3.42 66.01 L 3.27 66.42 L 4.98 65.32 L 5.24 65.45 L 4.72 65.86 L 5.63 65.70 L 5.73 66.06 L 6.09 65.93 L 5.76 66.24 L 6.13 66.25 L 6.34 65.96 L 6.04 65.40 L 6.68 64.93 L 6.52 65.63 L 7.45 65.94 L 7.60 66.71 L 7.92 66.16 L 7.67 65.48 L 7.39 65.40 L 7.40 65.84 L 6.78 65.36 L 7.04 64.93 L 8.15 64.74 L 8.46 65.10 L 8.43 65.61 L 8.83 65.78 L 9.28 66.51 L 8.18 67.25 L 8.93 67.32 L 7.80 68.26 L 7.99 68.30 L 9.94 67.19 L 9.96 66.85 L 9.74 66.74 L 9.88 66.20 L 9.05 65.39 L 9.37 64.95 L 9.29 64.54 L 9.73 64.62 L 9.82 64.39 L 10.42 64.58 L 10.98 64.27 L 11.23 64.64 L 11.84 64.62 L 10.95 64.04 L 10.92 63.77 L 10.47 63.53 L 10.62 63.46 L 12.30 63.92 L 13.06 64.59 L 14.86 65.12 L 14.83 65.36 L 12.64 66.20 L 11.93 67.04 Z M -13.94 79.65 L -13.55 79.65 L -13.89 80.48 L -14.81 80.11 L -14.92 79.50 L -16.82 79.34 L -16.37 79.29 L -16.09 78.95 L -15.57 79.13 L -14.06 78.89 L -13.68 79.25 L -13.87 79.25 L -13.94 79.65 Z M -10.94 89.29 L -11.05 89.41 L -12.49 88.88 L -11.40 88.89 L -10.94 89.29 Z";


// ---------- Small components -----------------------------------------------
function MaturityRing({ score, size = 36 }) {
  const r = size/2 - 2;
  const c = 2 * Math.PI * r;
  const pct = score / 100;
  const color = score >= 90 ? "#2a9d8f" : score >= 80 ? "#9fba3d" : score >= 70 ? "#E5A02F" : "#E27B5A";
  return (
    <svg width={size} height={size} viewBox={`0 0 ${size} ${size}`}>
      <circle cx={size/2} cy={size/2} r={r} fill="none" stroke="#EEF2F7" strokeWidth="3"/>
      <circle cx={size/2} cy={size/2} r={r} fill="none" stroke={color} strokeWidth="3"
        strokeDasharray={`${c*pct} ${c}`} strokeDashoffset={0}
        transform={`rotate(-90 ${size/2} ${size/2})`}
        strokeLinecap="round"/>
    </svg>
  );
}

function MiniMark({ stage }) {
  const isTrusted = stage === "trusted";
  return (
    <svg width="28" height="30" viewBox="0 0 40 43">
      <path d="M20 1 L38 11 L38 32 L20 42 L2 32 L2 11 Z" fill="#071e47"/>
      <circle cx="20" cy="14" r="5" fill={isTrusted?"#2a9d8f":"#b8d645"}/>
      <path d="M17 14 L19 16 L23 12" stroke="#071e47" strokeWidth="1.6" fill="none" strokeLinecap="round" strokeLinejoin="round"/>
    </svg>
  );
}

function EmptyState({ onClear }) {
  return (
    <div style={{
      border:"1px dashed #C7CEDC", borderRadius:16,
      padding:"64px 24px", textAlign:"center",
      background:"#fff",
    }}>
      <div style={{width:56, height:56, borderRadius:99, background:"#F4F7FB", margin:"0 auto 16px", display:"flex", alignItems:"center", justifyContent:"center"}}>
        <Icon name="search" size={24} color="#6B7793"/>
      </div>
      <div style={{fontSize:18, fontWeight:700, color:"#071e47"}}>No MSPs match those filters</div>
      <p style={{fontSize:13, color:"#6B7793", marginTop:8}}>Try broadening your region or clearing specialisms.</p>
      <button onClick={onClear} style={{...primaryBtn, marginTop:16}}>Clear all filters</button>
    </div>
  );
}

// ---------- formatters / styles --------------------------------------------
function fmtRel(iso) {
  const d = new Date(iso);
  const now = new Date("2026-04-17");
  const days = Math.round((now - d) / 86400000);
  if (days < 1) return "today";
  if (days < 2) return "yesterday";
  if (days < 14) return `${days} days ago`;
  if (days < 60) return `${Math.round(days/7)} wks ago`;
  return `${Math.round(days/30)} mo ago`;
}

const chipStyle = {
  fontSize:12,
  background:"#F4F7FB",
  color:"#39466A",
  padding:"3px 9px",
  borderRadius:99,
  whiteSpace:"nowrap",
  fontWeight:500,
};

const primaryBtn = {
  display:"inline-flex", alignItems:"center", gap:6,
  background:"#071e47", color:"#fff",
  border:"none", padding:"10px 16px",
  borderRadius:10,
  fontSize:13, fontWeight:600,
  cursor:"pointer",
  fontFamily:"inherit",
};

const ghostBtn = {
  display:"inline-flex", alignItems:"center", gap:6,
  background:"#fff", color:"#071e47",
  border:"1px solid #E4E9F2", padding:"9px 14px",
  borderRadius:8,
  fontSize:12, fontWeight:600,
  cursor:"pointer",
  fontFamily:"inherit",
};

const pillBtnBlack = {
  display:"inline-flex", alignItems:"center", gap:10,
  background:"#071e47", color:"#fff",
  border:"none", padding:"8px 8px 8px 20px",
  borderRadius:999,
  fontSize:13, fontWeight:600,
  cursor:"pointer",
  fontFamily:"inherit",
};
const pillBtnWhite = {
  display:"inline-flex", alignItems:"center", gap:10,
  background:"#fff", color:"#071e47",
  border:"1px solid #E4E9F2", padding:"8px 8px 8px 20px",
  borderRadius:999,
  fontSize:13, fontWeight:600,
  cursor:"pointer",
  fontFamily:"inherit",
};
const pillArrowWhite = {
  width:26, height:26, borderRadius:99, background:"#fff",
  display:"inline-flex", alignItems:"center", justifyContent:"center",
};
const pillArrowBlack = {
  width:26, height:26, borderRadius:99, background:"#071e47",
  display:"inline-flex", alignItems:"center", justifyContent:"center",
};

Object.assign(window, { DirectoryView, MaturityRing, fmtRel, chipStyle, primaryBtn, ghostBtn, pillBtnBlack, pillBtnWhite, pillArrowWhite, pillArrowBlack });
