Hello, World!

/* ===== Prop 50 Regional Forecast — NO DEPENDENCIES (Single JS) =====
   - Accurate soft outline of California (hand-tuned path)
   - 8 clickable regions layered inside
   - Counties are not drawn (most builders block large inline SVG geometry);
     this version prioritizes the *shape* and interactivity so it runs everywhere.
   - Click cycle: Undecided → Yes → No
===================================================================== */

(function () {
  // 1) Mount point + CSS
  const wrap = document.createElement('div');
  wrap.id = 'prop50-wrap';
  document.body.appendChild(wrap);

  const css = `
    #prop50-wrap { font-family: Arial, sans-serif; text-align:center; background:#fafafa; padding: 8px 0 16px; }
    #prop50-map { margin: 14px auto; }
    #prop50-map svg { max-width: 720px; width: 92vw; height: auto; }
    .outline { fill:#f2f2f2; stroke:#333; stroke-width:2; }
    .region { stroke:#333; stroke-width:1.6; fill-opacity:.66; cursor:pointer; transition: fill .2s; }
    .und { fill:#bdbdbd; }
    .yes { fill:#1f77b4; }
    .no  { fill:#d62728; }
    #prop50-totals { font-size:18px; font-weight:700; margin-top:6px; }
    #prop50-legend { margin-top:6px; font-size:14px; }
    .legend-box { width:16px; height:16px; display:inline-block; margin:0 4px -3px 10px; }
    .label { font-size:11px; fill:#111; user-select:none; pointer-events:none; }
  `;
  const style = document.createElement('style');
  style.appendChild(document.createTextNode(css));
  document.head.appendChild(style);

  // 2) UI shell
  wrap.innerHTML = `
    <h2>California – Prop 50 Regional Forecast (Informational)</h2>
    <p>Click a region to toggle: Undecided → Yes → No</p>
    <div id="prop50-map"></div>
    <div id="prop50-totals"></div>
    <div id="prop50-legend">
      <span class="legend-box" style="background:#1f77b4;"></span>Yes
      <span class="legend-box" style="background:#d62728;"></span>No
      <span class="legend-box" style="background:#bdbdbd;"></span>Undecided
    </div>
  `;

  // 3) Build SVG (soft, recognizable CA outline; internal regions approximate real groupings)
  //    NOTE: These are *regional* polygons, not counties — to avoid dependencies & size limits.
  const svgNS = 'http://www.w3.org/2000/svg';
  const svg = document.createElementNS(svgNS, 'svg');
  svg.setAttribute('viewBox', '0 0 600 1000');
  document.getElementById('prop50-map').appendChild(svg);

  // California silhouette path (hand-tuned bezier outline; smooth & recognizably accurate)
  const caPath = document.createElementNS(svgNS, 'path');
  caPath.setAttribute('class', 'outline');
  caPath.setAttribute('d',
    // Soft outline with coastal curvature, Sierra slope, and SoCal arc.
    'M155,40 C210,85 240,150 270,230 C285,270 300,315 320,360 C340,405 355,450 370,500 C380,535 390,575 405,620 C420,665 440,710 455,755 '+ 
    'C468,792 480,830 496,870 C508,900 522,930 538,955 C523,968 505,975 490,970 C450,955 420,935 390,905 C360,875 332,835 307,795 '+ 
    'C282,756 258,712 236,666 C220,631 206,595 192,555 C176,511 162,468 148,420 C134,370 123,322 113,280 C102,234 95,196 86,155 '+ 
    'C80,128 74,98 68,70 C83,55 103,46 155,40 Z'
  );
  svg.appendChild(caPath);

  // 4) Regions (8) — shapes drawn inside silhouette; positioned to read like CA geography.
  const regions = [
    { name:'North State', d:'M110,110 C145,125 170,160 185,205 L150,195 L130,160 Z', cx:145, cy:165 },
    { name:'North Coast', d:'M95,220 C135,225 160,240 185,260 L165,295 L120,285 L100,250 Z', cx:140, cy:265 },
    { name:'Sac/Sierra', d:'M190,210 C225,225 255,250 275,290 L250,330 L200,315 L175,275 Z', cx:230, cy:285 },
    { name:'Bay Area', d:'M120,300 C155,305 180,315 198,335 L182,365 L135,358 L115,330 Z', cx:160, cy:345 },
    { name:'Central Coast', d:'M125,370 C165,380 190,395 205,420 L190,455 L140,445 L120,410 Z', cx:165, cy:430 },
    { name:'Central Valley', d:'M208,340 C245,355 275,380 295,420 L275,470 L215,455 L195,405 Z', cx:250, cy:425 },
    { name:'Los Angeles', d:'M150,470 C190,480 215,495 230,520 L215,555 L165,545 L148,515 Z', cx:190, cy:530 },
    { name:'SD / Inland Empire', d:'M160,560 C205,570 235,590 255,620 L240,665 L175,655 L158,620 Z', cx:205, cy:635 }
  ];

  const regionStatus = {};

  function addRegion(r) {
    const p = document.createElementNS(svgNS, 'path');
    p.setAttribute('d', r.d);
    p.setAttribute('class', 'region und');
    p.setAttribute('data-name', r.name);
    p.addEventListener('click', () => {
      const cur = regionStatus[r.name] || 0;
      const nxt = (cur + 1) % 3;
      regionStatus[r.name] = nxt;
      p.classList.remove('und','yes','no');
      p.classList.add(nxt===0?'und':(nxt===1?'yes':'no'));
      updateTotals();
    });
    svg.appendChild(p);

    const label = document.createElementNS(svgNS, 'text');
    label.setAttribute('x', r.cx);
    label.setAttribute('y', r.cy);
    label.setAttribute('class', 'label');
    label.textContent = r.name;
    svg.appendChild(label);

    regionStatus[r.name] = 0;
  }

  regions.forEach(addRegion);
  updateTotals();

  function updateTotals() {
    let yes=0, no=0, und=0;
    Object.values(regionStatus).forEach(v=>{
      if(v===1) yes++; else if(v===2) no++; else und++;
    });
    document.getElementById('prop50-totals').textContent =
      `Yes: ${yes} · No: ${no} · Undecided: ${und}`;
  }
})();