/* global React, d3, topojson */

// Real geography. US states rendered via d3-geo + us-atlas TopoJSON,
// projected with d3.geoAlbersUsa (handles Alaska/Hawaii inset automatically).
// Market dots are placed by real lat/lng through the same projection.

const MARKETS_GEO = [
  { name: 'Seattle, WA',        lnglat: [-122.3321,  47.6062] },
  { name: 'Reno, NV',           lnglat: [-119.8138,  39.5296] },
  { name: 'Big Bear, CA',       lnglat: [-116.9114,  34.2439] },
  { name: 'Las Vegas, NV',      lnglat: [-115.1398,  36.1699] },
  { name: 'Chandler, AZ',       lnglat: [-111.8413,  33.3062] },
  { name: 'Deadwood, SD',       lnglat: [-103.7296,  44.3766] },
  { name: 'Aberdeen, SD',       lnglat: [ -98.4865,  45.4647] },
  { name: 'Webster, SD',        lnglat: [ -97.5220,  45.3330] },
  { name: 'Sioux Falls, SD',    lnglat: [ -96.7311,  43.5446] },
  { name: 'Harrisburg, SD',     lnglat: [ -96.6953,  43.4347] },
  { name: 'Lincoln, NE',        lnglat: [ -96.6852,  40.8136] },
  { name: 'Overland Park, KS',  lnglat: [ -94.6708,  38.9822] },
  { name: 'Milwaukee, WI',      lnglat: [ -87.9065,  43.0389] },
  { name: 'Wauwatosa, WI',      lnglat: [ -88.0076,  43.0495] },
  { name: 'Nashville, TN',      lnglat: [ -86.7816,  36.1627] },
  { name: 'Grand Prairie, TX',  lnglat: [ -97.0081,  32.7460] },
  { name: 'Houston, TX',        lnglat: [ -95.3698,  29.7604] },
  { name: 'Kissimmee, FL',      lnglat: [ -81.4076,  28.2920] },
  { name: 'Tampa, FL',          lnglat: [ -82.4572,  27.9506] },
  { name: 'Englewood, FL',      lnglat: [ -82.3529,  26.9620] },
  { name: 'Holly Ridge, NC',    lnglat: [ -77.5527,  34.5041] },
  { name: 'Hampton, VA',        lnglat: [ -76.3452,  37.0299] },
  { name: 'McLean, VA',         lnglat: [ -77.1775,  38.9339] },
];

// TopoJSON URL — unpkg mirror of the canonical us-atlas (Albers USA pre-projected
// to 975×610; we rescale into our 960×600 viewBox).
const US_TOPO_URL = 'https://unpkg.com/us-atlas@3.0.1/states-10m.json';

function MarketsLux() {
  const isMobile = useIsMobile();
  const [hover, setHover] = React.useState(null);
  const [paths, setPaths] = React.useState(null);   // string[] — one per state
  const [dots, setDots] = React.useState(null);     // {name, x, y}[]
  const [geo, setGeo] = React.useState(null);       // {biomes, contours, riverPaths}
  const [err, setErr] = React.useState(null);

  React.useEffect(() => {
    let live = true;
    (async () => {
      try {
        // Wait for d3 + topojson globals (pinned in index.html)
        for (let i = 0; i < 200 && (!window.d3 || !window.topojson); i++) {
          await new Promise(r => setTimeout(r, 30));
        }
        if (!window.d3 || !window.topojson) throw new Error('d3/topojson not loaded');

        const topo = await fetch(US_TOPO_URL).then(r => r.json());
        if (!live) return;

        // us-atlas 10m is unprojected WGS84 — we must project it ourselves.
        const projection = d3.geoAlbersUsa().scale(1300).translate([487.5, 305]);
        const pathGen = d3.geoPath(projection);
        const statesFc = topojson.feature(topo, topo.objects.states);
        const ps = statesFc.features.map(f => {
          const c = pathGen.centroid(f);
          return { d: pathGen(f), name: (f.properties && f.properties.name) || '', cx: c[0], cy: c[1] };
        });

        // Market dots reuse the same projection so they line up with the states.
        const ds = MARKETS_GEO.map(m => {
          const p = projection(m.lnglat);
          return p ? { name: m.name, x: p[0], y: p[1] } : null;
        }).filter(Boolean);

        // Real geographic anchors, projected — used to position biome tints,
        // contour rings, and river lines so they actually land in the right place.
        const proj = (lng, lat) => {
          const p = projection([lng, lat]);
          return p ? { x: p[0], y: p[1] } : null;
        };
        const biomes = {
          pnw:     proj(-121.5, 45.5),   // Cascades
          basin:   proj(-116.0, 40.0),   // NV/UT
          rockies: proj(-106.0, 40.0),   // CO
          rockiesN:proj(-112.0, 46.0),   // MT/ID
          swDesert:proj(-111.0, 33.5),   // AZ/NM
          plains:  proj( -98.0, 40.0),   // KS/NE
          midwest: proj( -90.0, 41.0),   // IL/IA
          app:     proj( -82.0, 37.0),   // VA/NC/KY ridge
          gulf:    proj( -82.5, 28.5),   // FL
          bh:      proj(-103.7, 44.1),   // Black Hills
          ozarks:  proj( -92.5, 36.0),   // AR/MO
        };
        const contours = {
          rockies:   proj(-106.0, 40.0),
          sierras:   proj(-119.0, 39.0),
          appalach:  proj(-81.5,  37.0),
          blackhills:proj(-103.7, 44.1),
          ozarks:    proj(-92.5,  36.0),
        };
        const rivers = {
          // Mississippi: MN headwaters → Gulf (New Orleans)
          mississippi: [[-95.2,47.2],[-93.5,44.9],[-91.1,41.5],[-90.2,38.6],[-91.1,35.1],[-91.2,32.3],[-90.1,30.0],[-89.2,29.0]].map(([a,b])=>proj(a,b)),
          // Missouri: MT → StL
          missouri:    [[-111.5,46.6],[-106.4,46.8],[-101.3,46.9],[-96.4,41.3],[-92.2,38.6]].map(([a,b])=>proj(a,b)),
          // Ohio: Pittsburgh → Cairo IL
          ohio:        [[-80.0,40.4],[-84.5,39.1],[-87.5,38.3],[-89.2,37.0]].map(([a,b])=>proj(a,b)),
          // Colorado: CO → Gulf of CA
          colorado:    [[-106.4,40.0],[-109.5,38.5],[-112.6,36.1],[-114.5,34.5],[-114.7,32.7]].map(([a,b])=>proj(a,b)),
          // Rio Grande: CO → Brownsville
          rioGrande:   [[-106.2,37.8],[-106.6,35.2],[-103.0,29.7],[-97.5,25.9]].map(([a,b])=>proj(a,b)),
          // Columbia: headwaters → mouth
          columbia:    [[-117.2,48.0],[-119.8,46.0],[-123.8,46.2]].map(([a,b])=>proj(a,b)),
        };
        // Convert to SVG path d-strings
        const toPath = (pts) => {
          const f = pts.filter(Boolean);
          if (f.length < 2) return null;
          return 'M ' + f.map(p => `${p.x.toFixed(1)} ${p.y.toFixed(1)}`).join(' L ');
        };
        const riverPaths = Object.fromEntries(Object.entries(rivers).map(([k, v]) => [k, toPath(v)]));

        setPaths(ps);
        setDots(ds);
        setGeo({ biomes, contours, riverPaths });
      } catch (e) {
        console.warn('Map load failed:', e);
        setErr(String(e));
      }
    })();
    return () => { live = false; };
  }, []);

  return (
    <section id="markets" data-screen-label="07 Markets" style={{
      background: 'var(--cream-100)',
      padding: isMobile ? '120px 0' : '180px 0',
      position: 'relative',
    }}>
      <div style={{ maxWidth: 1320, margin: '0 auto', padding: isMobile ? '0 20px' : '0 48px' }}>
        <SectionHeader eyebrow="· Local presence ·">
          Local teams, in every market we serve.
        </SectionHeader>

        <FadeIn delay={120} style={{ maxWidth: 660, margin: '36px auto 0', textAlign: 'center' }}>
          <p style={{
            fontFamily: 'var(--font-body)', fontSize: 16, lineHeight: 1.75,
            color: 'var(--clay-700)', margin: 0,
          }}>
            Fifty-six properties across thirteen states. Local cleaners, local vendors, local response. National coverage without the franchise feel.
          </p>
        </FadeIn>

        <div style={{
          display: 'grid',
          gridTemplateColumns: isMobile ? '1fr' : '1.55fr 1fr',
          gap: isMobile ? 56 : 80,
          marginTop: isMobile ? 64 : 120,
          alignItems: 'start',
        }}>
          <FadeIn>
            <div style={{
              position: 'relative',
              background: 'var(--cream-100)',
              border: '1px solid rgba(74,63,48,0.18)',
              padding: 28,
              boxShadow: '0 40px 80px -40px rgba(74,63,48,0.28)',
            }}>
              <svg viewBox="0 0 975 610" style={{ width: '100%', height: 'auto', display: 'block' }}>
                <defs>
                  <filter id="dotGlow">
                    <feGaussianBlur stdDeviation="3" result="b"/>
                    <feMerge>
                      <feMergeNode in="b"/>
                      <feMergeNode in="SourceGraphic"/>
                    </feMerge>
                  </filter>

                  {/* Paper grain — warm bronze fleck, the whole canvas */}
                  <filter id="paperGrain" x="0" y="0" width="100%" height="100%">
                    <feTurbulence type="fractalNoise" baseFrequency="1.1" numOctaves="2" seed="3"/>
                    <feColorMatrix values="0 0 0 0 0.29  0 0 0 0 0.21  0 0 0 0 0.12  0 0 0 0.07 0"/>
                  </filter>

                  {/* Terrain grain — coarser, for landmass relief */}
                  <filter id="terrainTexture" x="0" y="0" width="100%" height="100%">
                    <feTurbulence type="fractalNoise" baseFrequency="0.022 0.028" numOctaves="4" seed="12"/>
                    <feColorMatrix values="0 0 0 0 0.29  0 0 0 0 0.21  0 0 0 0 0.12  0 0 0 0.22 0"/>
                  </filter>

                  {/* Relief blobs — soft warm shadow */}
                  <filter id="reliefBlobs" x="-10%" y="-10%" width="120%" height="120%">
                    <feTurbulence type="fractalNoise" baseFrequency="0.005" numOctaves="2" seed="7"/>
                    <feColorMatrix values="0 0 0 0 0.29  0 0 0 0 0.18  0 0 0 0 0.10  0 0 0 0.32 0"/>
                  </filter>

                  {/* Ocean / backdrop — cream paper, slightly darker at edges */}
                  <radialGradient id="oceanBg" cx="50%" cy="50%" r="80%">
                    <stop offset="0%"  stopColor="#F5EFE3"/>
                    <stop offset="70%" stopColor="#EDE4D0"/>
                    <stop offset="100%" stopColor="#E3D8BE"/>
                  </radialGradient>

                  {/* Landmass base — warm cream/bronze, vellum */}
                  <linearGradient id="landBase" x1="0" y1="0" x2="1" y2="1">
                    <stop offset="0%"  stopColor="#FBF8F2"/>
                    <stop offset="50%" stopColor="#F3EAD4"/>
                    <stop offset="100%" stopColor="#E7D8B5"/>
                  </linearGradient>

                  {/* REGIONAL SHADING — earthy, on-brand tints, anchored to real geography */}
                  {geo && (() => {
                    const pct = (g, dx=0, dy=0) => g ? { cx: `${((g.x+dx)/975*100).toFixed(2)}%`, cy: `${((g.y+dy)/610*100).toFixed(2)}%` } : { cx:'50%', cy:'50%' };
                    const b = geo.biomes;
                    return (
                      <>
                        {/* Pacific NW — moss forest */}
                        <radialGradient id="biomePNW" {...pct(b.pnw)} r="14%" gradientTransform="scale(1.1 2.0)">
                          <stop offset="0%" stopColor="#5E6B3A" stopOpacity="0.55"/>
                          <stop offset="100%" stopColor="#5E6B3A" stopOpacity="0"/>
                        </radialGradient>
                        {/* Great Basin — bronze tint */}
                        <radialGradient id="biomeBasin" {...pct(b.basin)} r="13%" gradientTransform="scale(1.3 1.4)">
                          <stop offset="0%" stopColor="#B85C3C" stopOpacity="0.32"/>
                          <stop offset="100%" stopColor="#B85C3C" stopOpacity="0"/>
                        </radialGradient>
                        {/* Rockies — espresso band (tall + narrow, rotated slightly) */}
                        <radialGradient id="biomeRockies" {...pct(b.rockies)} r="18%" gradientTransform="scale(1.0 2.6)">
                          <stop offset="0%"  stopColor="#4A2F1A" stopOpacity="0.48"/>
                          <stop offset="55%" stopColor="#9A4A2E" stopOpacity="0.22"/>
                          <stop offset="100%" stopColor="#9A4A2E" stopOpacity="0"/>
                        </radialGradient>
                        {/* Northern Rockies */}
                        <radialGradient id="biomeRockiesN" {...pct(b.rockiesN)} r="10%" gradientTransform="scale(1.4 1.6)">
                          <stop offset="0%"  stopColor="#5A3D22" stopOpacity="0.4"/>
                          <stop offset="100%" stopColor="#5A3D22" stopOpacity="0"/>
                        </radialGradient>
                        {/* SW desert — ochre */}
                        <radialGradient id="biomeSWDesert" {...pct(b.swDesert)} r="12%" gradientTransform="scale(1.5 1.1)">
                          <stop offset="0%" stopColor="#C78A3D" stopOpacity="0.38"/>
                          <stop offset="100%" stopColor="#C78A3D" stopOpacity="0"/>
                        </radialGradient>
                        {/* Plains — warm straw */}
                        <radialGradient id="biomePlains" {...pct(b.plains)} r="22%" gradientTransform="scale(1.4 1.15)">
                          <stop offset="0%" stopColor="#D9CDB4" stopOpacity="0.55"/>
                          <stop offset="70%" stopColor="#C9B98E" stopOpacity="0.22"/>
                          <stop offset="100%" stopColor="#C9B98E" stopOpacity="0"/>
                        </radialGradient>
                        {/* Midwest — sage */}
                        <radialGradient id="biomeMidwest" {...pct(b.midwest)} r="13%" gradientTransform="scale(1.4 1.1)">
                          <stop offset="0%" stopColor="#8A9973" stopOpacity="0.38"/>
                          <stop offset="100%" stopColor="#8A9973" stopOpacity="0"/>
                        </radialGradient>
                        {/* Appalachians — moss (tall and rotated along the ridge) */}
                        <radialGradient id="biomeApp" {...pct(b.app)} r="14%" gradientTransform="scale(0.9 2.3)">
                          <stop offset="0%" stopColor="#5E6B3A" stopOpacity="0.45"/>
                          <stop offset="100%" stopColor="#5E6B3A" stopOpacity="0"/>
                        </radialGradient>
                        {/* Florida / Gulf — sage-moss */}
                        <radialGradient id="biomeGulf" {...pct(b.gulf)} r="9%" gradientTransform="scale(0.9 1.8)">
                          <stop offset="0%" stopColor="#7A8A5E" stopOpacity="0.42"/>
                          <stop offset="100%" stopColor="#7A8A5E" stopOpacity="0"/>
                        </radialGradient>
                        {/* Black Hills */}
                        <radialGradient id="biomeBH" {...pct(b.bh)} r="2.6%">
                          <stop offset="0%" stopColor="#4A2F1A" stopOpacity="0.55"/>
                          <stop offset="100%" stopColor="#4A2F1A" stopOpacity="0"/>
                        </radialGradient>
                        {/* Ozarks */}
                        <radialGradient id="biomeOzarks" {...pct(b.ozarks)} r="5%">
                          <stop offset="0%" stopColor="#9A4A2E" stopOpacity="0.32"/>
                          <stop offset="100%" stopColor="#9A4A2E" stopOpacity="0"/>
                        </radialGradient>
                      </>
                    );
                  })()}

                  {/* Vignette — warm espresso edge */}
                  <radialGradient id="vignette" cx="50%" cy="50%" r="75%">
                    <stop offset="60%" stopColor="rgba(74,47,26,0)"/>
                    <stop offset="100%" stopColor="rgba(74,47,26,0.22)"/>
                  </radialGradient>

                  {/* Clip = landmass union — only draw terrain inside states */}
                  {paths && (
                    <clipPath id="landClip">
                      {paths.map((p, i) => <path key={'c'+i} d={p.d}/>)}
                    </clipPath>
                  )}
                </defs>

                {/* Ocean / backdrop — cream paper */}
                <rect x="0" y="0" width="975" height="610" fill="url(#oceanBg)"/>
                <rect x="0" y="0" width="975" height="610" fill="url(#oceanBg)" filter="url(#paperGrain)" opacity="0.5"/>

                {/* Graticule — faint bronze */}
                <g stroke="rgba(184,92,60,0.10)" strokeWidth="0.5" fill="none">
                  <line x1="0" y1="152" x2="975" y2="152"/>
                  <line x1="0" y1="305" x2="975" y2="305"/>
                  <line x1="0" y1="458" x2="975" y2="458"/>
                  <line x1="244" y1="0" x2="244" y2="610"/>
                  <line x1="487" y1="0" x2="487" y2="610"/>
                  <line x1="731" y1="0" x2="731" y2="610"/>
                </g>

                {/* LAND — clipped to actual state geography, editorial topo layers */}
                {paths && (
                  <g clipPath="url(#landClip)">
                    {/* 1. Base vellum */}
                    <rect x="0" y="0" width="975" height="610" fill="url(#landBase)"/>
                    {/* 2. Plains straw */}
                    <rect x="0" y="0" width="975" height="610" fill="url(#biomePlains)"/>
                    {/* 3. Regional biome tints */}
                    <rect x="0" y="0" width="975" height="610" fill="url(#biomePNW)"/>
                    <rect x="0" y="0" width="975" height="610" fill="url(#biomeBasin)"/>
                    <rect x="0" y="0" width="975" height="610" fill="url(#biomeSWDesert)"/>
                    <rect x="0" y="0" width="975" height="610" fill="url(#biomeRockies)"/>
                    <rect x="0" y="0" width="975" height="610" fill="url(#biomeRockiesN)"/>
                    <rect x="0" y="0" width="975" height="610" fill="url(#biomeMidwest)"/>
                    <rect x="0" y="0" width="975" height="610" fill="url(#biomeApp)"/>
                    <rect x="0" y="0" width="975" height="610" fill="url(#biomeGulf)"/>
                    <rect x="0" y="0" width="975" height="610" fill="url(#biomeBH)"/>
                    <rect x="0" y="0" width="975" height="610" fill="url(#biomeOzarks)"/>

                    {/* 4. Low-freq relief shadow */}
                    <rect x="0" y="0" width="975" height="610" filter="url(#reliefBlobs)" opacity="0.75"/>
                    {/* 5. Fine terrain texture */}
                    <rect x="0" y="0" width="975" height="610" filter="url(#terrainTexture)" opacity="0.55"/>

                    {/* 6. Contour lines — nested rings over real mountain anchors */}
                    {geo && (
                      <g fill="none" stroke="rgba(74,47,26,0.24)" strokeWidth="0.4">
                        {geo.contours.rockies && [0,1,2,3].map(i => (
                          <ellipse key={'rk'+i}
                            cx={geo.contours.rockies.x} cy={geo.contours.rockies.y}
                            rx={38 - i*7} ry={95 - i*16}
                            transform={`rotate(-8 ${geo.contours.rockies.x} ${geo.contours.rockies.y})`}/>
                        ))}
                        {geo.contours.sierras && [0,1,2].map(i => (
                          <ellipse key={'sn'+i}
                            cx={geo.contours.sierras.x} cy={geo.contours.sierras.y}
                            rx={18 - i*4} ry={120 - i*28}
                            transform={`rotate(6 ${geo.contours.sierras.x} ${geo.contours.sierras.y})`}/>
                        ))}
                        {geo.contours.appalach && [0,1,2,3].map(i => (
                          <ellipse key={'ap'+i}
                            cx={geo.contours.appalach.x} cy={geo.contours.appalach.y}
                            rx={22 - i*5} ry={120 - i*24}
                            transform={`rotate(-38 ${geo.contours.appalach.x} ${geo.contours.appalach.y})`}/>
                        ))}
                        {geo.contours.blackhills && [0,1].map(i => (
                          <ellipse key={'bh'+i}
                            cx={geo.contours.blackhills.x} cy={geo.contours.blackhills.y}
                            rx={13 - i*5} ry={16 - i*6}/>
                        ))}
                        {geo.contours.ozarks && [0,1].map(i => (
                          <ellipse key={'oz'+i}
                            cx={geo.contours.ozarks.x} cy={geo.contours.ozarks.y}
                            rx={26 - i*7} ry={18 - i*5}
                            transform={`rotate(-15 ${geo.contours.ozarks.x} ${geo.contours.ozarks.y})`}/>
                        ))}
                      </g>
                    )}

                    {/* 7. Major rivers — projected from real lat/lng */}
                    {geo && (
                      <g fill="none" stroke="rgba(74,47,26,0.38)" strokeWidth="0.9"
                         strokeLinejoin="round" strokeLinecap="round">
                        {Object.entries(geo.riverPaths).map(([k, d]) => d ? <path key={k} d={d}/> : null)}
                      </g>
                    )}
                  </g>
                )}

                {/* State outlines — crisp espresso on cream */}
                {paths && (
                  <g fill="none" stroke="rgba(74,47,26,0.55)" strokeWidth="0.9"
                     strokeLinejoin="round" strokeLinecap="round">
                    {paths.map((p, i) => <path key={'s'+i} d={p.d}/>)}
                  </g>
                )}

                {/* Outer US border — slightly heavier */}
                {paths && (
                  <g fill="none" stroke="rgba(74,47,26,0.75)" strokeWidth="1.6"
                     strokeLinejoin="round" strokeLinecap="round" opacity="0.6">
                    {paths.map((p, i) => <path key={'co'+i} d={p.d}/>)}
                  </g>
                )}

                {/* Warm vignette */}
                <rect x="0" y="0" width="975" height="610" fill="url(#vignette)" pointerEvents="none"/>

                {!paths && !err && (
                  <text x="487" y="305" textAnchor="middle"
                    style={{ fontFamily:'var(--font-display)', fontStyle:'italic', fontSize:14, fill:'var(--stone-500)' }}>
                    surveying the territory…
                  </text>
                )}

                {/* Market dots — espresso ring / bronze core over cream paper */}
                {dots && dots.map((m, i) => {
                  const active = hover === i;
                  return (
                    <g key={m.name}
                      onMouseEnter={() => setHover(i)}
                      onMouseLeave={() => setHover(null)}
                      style={{ cursor: 'default' }}>
                      {active && (
                        <circle cx={m.x} cy={m.y} r="8"
                          fill="none"
                          stroke="rgba(184,92,60,0.85)"
                          strokeWidth="1.2">
                          <animate attributeName="r" from="5" to="22" dur="1.8s" repeatCount="indefinite"/>
                          <animate attributeName="opacity" from="0.85" to="0" dur="1.8s" repeatCount="indefinite"/>
                        </circle>
                      )}
                      {/* cream halo */}
                      <circle cx={m.x} cy={m.y} r={active ? 7.2 : 5}
                        fill="rgba(251,248,242,0.95)"
                        stroke="rgba(74,47,26,0.35)" strokeWidth="0.6"
                        style={{ transition: 'r 260ms ease' }}/>
                      {/* bronze core */}
                      <circle cx={m.x} cy={m.y} r={active ? 4.2 : 2.6}
                        fill="var(--bronze-500)"
                        filter={active ? 'url(#dotGlow)' : undefined}
                        style={{ transition: 'r 260ms ease' }}/>
                      <circle cx={m.x} cy={m.y} r="20"
                        fill="transparent"
                        style={{ pointerEvents: 'all' }}/>
                    </g>
                  );
                })}

                {dots && hover !== null && (
                  <g>
                    <rect
                      x={dots[hover].x + 12}
                      y={dots[hover].y - 28}
                      width={dots[hover].name.length * 8.2 + 20}
                      height="22"
                      fill="var(--ink-900)"
                    />
                    <text
                      x={dots[hover].x + 22}
                      y={dots[hover].y - 12}
                      style={{
                        fontFamily: 'var(--font-display)', fontStyle: 'italic',
                        fontSize: 14, fill: 'var(--cream-50)',
                        letterSpacing: '0.02em',
                      }}>
                      {dots[hover].name}
                    </text>
                  </g>
                )}

                <text x="32" y="40"
                  style={{
                    fontFamily: 'var(--font-body)', fontSize: 10,
                    letterSpacing: '0.3em', textTransform: 'uppercase',
                    fill: 'rgba(74,47,26,0.6)',
                  }}>
                  The Territory &nbsp;·&nbsp; 2026
                </text>
                <text x="943" y="40" textAnchor="end"
                  style={{
                    fontFamily: 'var(--font-body)', fontSize: 10,
                    letterSpacing: '0.3em', textTransform: 'uppercase',
                    fill: 'rgba(74,47,26,0.6)',
                  }}>
                  23 markets &nbsp;·&nbsp; 13 states
                </text>
                <text x="32" y="594"
                  style={{
                    fontFamily: 'var(--font-display)', fontStyle: 'italic',
                    fontSize: 11, fill: 'rgba(74,47,26,0.58)',
                  }}>
                  Stylized terrain · shaded relief · Albers equal-area
                </text>
                <text x="943" y="594" textAnchor="end"
                  style={{
                    fontFamily: 'var(--font-body)', fontSize: 10,
                    letterSpacing: '0.28em', textTransform: 'uppercase',
                    fill: 'rgba(74,47,26,0.5)',
                  }}>
                  N &nbsp;·&nbsp; ↑
                </text>
              </svg>

              <div style={{
                textAlign: 'center', marginTop: 20,
                fontFamily: 'var(--font-display)', fontStyle: 'italic',
                fontSize: 14, color: 'var(--stone-500)',
              }}>
                {dots && hover !== null ? `Hovering · ${dots[hover].name}` : 'Hover any mark for the market'}
              </div>
            </div>
          </FadeIn>

          <FadeIn delay={120}>
            <div style={{
              fontFamily: 'var(--font-body)', fontSize: 10,
              letterSpacing: '0.3em', textTransform: 'uppercase',
              color: 'var(--stone-500)', marginBottom: 24,
            }}>The index, by region</div>

            <div style={{ display: 'flex', flexDirection: 'column', gap: 28 }}>
              <MarketGroup label="West" items={['Seattle, WA', 'Reno, NV', 'Las Vegas, NV', 'Big Bear, CA', 'Chandler, AZ']}/>
              <MarketGroup label="Great Plains" items={['Aberdeen, SD', 'Webster, SD', 'Sioux Falls, SD', 'Harrisburg, SD', 'Deadwood, SD', 'Lincoln, NE', 'Overland Park, KS']}/>
              <MarketGroup label="Midwest" items={['Milwaukee, WI', 'Wauwatosa, WI']}/>
              <MarketGroup label="South" items={['Nashville, TN', 'Houston, TX', 'Grand Prairie, TX']}/>
              <MarketGroup label="Southeast" items={['Tampa, FL', 'Kissimmee, FL', 'Englewood, FL', 'Holly Ridge, NC']}/>
              <MarketGroup label="Mid-Atlantic" items={['Hampton, VA', 'McLean, VA']}/>
            </div>
          </FadeIn>
        </div>
      </div>
    </section>
  );
}

function MarketGroup({ label, items }) {
  const isMobile = useIsMobile();
  return (
    <div style={{
      display: 'grid',
      gridTemplateColumns: isMobile ? '1fr' : '120px 1fr',
      gap: isMobile ? 8 : 24,
      paddingTop: 16, borderTop: '1px solid rgba(28,26,23,0.1)',
    }}>
      <div style={{
        fontFamily: 'var(--font-display)', fontStyle: 'italic',
        fontSize: 16, color: 'var(--bronze-500)',
      }}>{label}</div>
      <div style={{
        fontFamily: 'var(--font-body)', fontSize: 14,
        color: 'var(--ink-900)', lineHeight: 1.7,
      }}>
        {items.join(' · ')}
      </div>
    </div>
  );
}

Object.assign(window, { MarketsLux, MarketGroup });
