(function() {
  var useState = React.useState;
  var useEffect = React.useEffect;
  var useRef = React.useRef;

  var STEPS = ['Basics', 'Location', 'Media', 'Description', 'Requirements', 'Challenge', 'Publish'];
  var TYPES = window.CBOpportunities ? window.CBOpportunities.PROPERTY_TYPES : [];

  // Each publisher role gets its own identity + capability-specific tabs.
  var ROLE_PROFILES = {
    property_owner: {
      title: 'Owner Dashboard',
      sub: 'Publish your properties, review builder concepts, crowdfund the build, and hand off to construction partners.',
      entity: 'My Properties',
      publishLabel: 'Publish Property',
      accent: 'var(--violet)',
      extra: [],
    },
    municipality: {
      title: 'Civic Dashboard',
      sub: 'Publish public sites, moderate community proposals across the city, and steer civic redevelopment.',
      entity: 'Civic Sites',
      publishLabel: 'Publish Civic Site',
      accent: 'var(--cyan)',
      extra: ['moderation'],
    },
    developer: {
      title: 'Developer Dashboard',
      sub: 'Discover approved projects, take over construction contracts, and manage your build pipeline.',
      entity: 'My Listings',
      publishLabel: 'List a Project',
      accent: 'var(--lime)',
      extra: ['available'],
    },
  };

  function OwnerDashboardPage() {
    var params = window.UserRouter.getParams() || {};
    var user = window.AuthState && window.AuthState.getUser();
    var role = (user && user.role) || 'citizen';
    var profile = ROLE_PROFILES[role] || ROLE_PROFILES.property_owner;
    var _tab = useState(params.tab || 'dashboard'); var tab = _tab[0], setTab = _tab[1];
    var _mine = useState([]); var mine = _mine[0], setMine = _mine[1];
    var _modQueue = useState([]); var modQueue = _modQueue[0], setModQueue = _modQueue[1];
    var _avail = useState([]); var avail = _avail[0], setAvail = _avail[1];
    var _busyId = useState(null); var busyId = _busyId[0], setBusyId = _busyId[1];
    var _analytics = useState(null); var analytics = _analytics[0], setAnalytics = _analytics[1];
    var _verifyType = useState('property_owner'); var verifyType = _verifyType[0], setVerifyType = _verifyType[1];
    var _org = useState(''); var org = _org[0], setOrg = _org[1];
    var _notes = useState(''); var notes = _notes[0], setNotes = _notes[1];

    // wizard state
    var _step = useState(0); var step = _step[0], setStep = _step[1];
    var _name = useState(''); var name = _name[0], setName = _name[1];
    var _ptype = useState('mixed_use'); var ptype = _ptype[0], setPtype = _ptype[1];
    var _address = useState(''); var address = _address[0], setAddress = _address[1];
    var _city = useState('CityBuildRR'); var city = _city[0], setCity = _city[1];
    var _lat = useState(40.7128); var lat = _lat[0], setLat = _lat[1];
    var _lng = useState(-74.006); var lng = _lng[0], setLng = _lng[1];
    var _radius = useState(500); var radius = _radius[0], setRadius = _radius[1];
    var _files = useState([]); var files = _files[0], setFiles = _files[1];
    var _desc = useState(''); var desc = _desc[0], setDesc = _desc[1];
    var _req = useState(''); var req = _req[0], setReq = _req[1];
    var _reward = useState(''); var reward = _reward[0], setReward = _reward[1];
    var _deadline = useState(''); var deadline = _deadline[0], setDeadline = _deadline[1];
    var _maxSub = useState(50); var maxSub = _maxSub[0], setMaxSub = _maxSub[1];
    var _goal = useState(100); var goal = _goal[0], setGoal = _goal[1];
    var _publishing = useState(false); var publishing = _publishing[0], setPublishing = _publishing[1];
    var mapRef = useRef(null);
    var searchInputRef = useRef(null);
    var markerRef = useRef(null);
    var pickerRef = useRef(null);
    var _mapReady = useState(false); var mapReady = _mapReady[0], setMapReady = _mapReady[1];
    var _mapError = useState(''); var mapError = _mapError[0], setMapError = _mapError[1];

    useEffect(function() {
      if (!window.AuthState || !window.AuthState.isLoggedIn()) return;
      window.CBOpportunities.mine().then(function(r){ setMine(r.opportunities || []); }).catch(function(){});
      window.CBOpportunities.analytics().then(setAnalytics).catch(function(){});
    }, [tab]);

    // Municipality: pull the city-wide moderation queue (pending proposals).
    useEffect(function() {
      if (tab !== 'moderation' || role !== 'municipality') return;
      window.CBOpportunities.list({ status: 'pending_approval', limit: 50 })
        .then(function(r){ setModQueue((r && (r.opportunities || r.items)) || []); })
        .catch(function(){});
    }, [tab]);

    // Developer: approved/open projects available to take over for construction.
    useEffect(function() {
      if (tab !== 'available' || role !== 'developer') return;
      window.CBOpportunities.list({ status: 'open', limit: 50 })
        .then(function(r){
          var list = (r && (r.opportunities || r.items)) || [];
          setAvail(list.filter(function(o){ return String(o.owner && (o.owner._id || o.owner)) !== String(user && user._id); }));
        })
        .catch(function(){});
    }, [tab]);

    function moderateOpp(id, status) {
      setBusyId(id);
      window.CBOpportunities.moderate(id, status).then(function() {
        setModQueue(function(q){ return q.filter(function(o){ return o._id !== id; }); });
        window.showUserToast(status === 'open' ? 'Approved & published to the map' : 'Proposal rejected', status === 'open' ? 'lime' : 'rose');
      }).catch(function(e) {
        window.showUserToast(e.message || 'Action failed', 'rose');
      }).finally(function(){ setBusyId(null); });
    }

    function takeoverProject(id) {
      setBusyId(id);
      window.CBOpportunities.takeover(id, 'Construction takeover requested').then(function() {
        setAvail(function(a){ return a.filter(function(o){ return o._id !== id; }); });
        window.showUserToast('Construction takeover submitted', 'lime');
      }).catch(function(e) {
        window.showUserToast(e.message || 'Takeover failed', 'rose');
      }).finally(function(){ setBusyId(null); });
    }

    useEffect(function() {
      if (tab !== 'publish' || step !== 1) {
        pickerRef.current = null;
        markerRef.current = null;
        setMapReady(false);
        return;
      }
      if (!mapRef.current || !window.CBMaps) return;
      var cancelled = false;

      window.CBMaps.createPinPicker(mapRef.current, {
        center: { lat: Number(lat) || 40.7128, lng: Number(lng) || -74.006 },
        zoom: 16,
        searchInput: searchInputRef.current || document.getElementById('opp-places-input'),
        onChange: function(pos) {
          setLat(Number(pos.lat.toFixed(6)));
          setLng(Number(pos.lng.toFixed(6)));
          if (pos.address) setAddress(pos.address);
        },
      }).then(function(picker) {
        if (cancelled) return;
        pickerRef.current = picker;
        markerRef.current = picker.marker;
        setMapReady(true);
        setMapError('');
      }).catch(function(e) {
        if (cancelled) return;
        setMapReady(false);
        setMapError(e.message || 'Google Maps unavailable');
      });

      return function() { cancelled = true; };
    }, [tab, step]);

    function applyVerify() {
      window.CBOpportunities.applyVerification({
        type: verifyType,
        organizationName: org,
        notes: notes,
      }).then(function() {
        window.showUserToast('Verification submitted — pending review', 'lime');
        if (window.AuthState) window.AuthState.init();
      }).catch(function(e) {
        window.showUserToast(e.message || 'Verification failed', 'rose');
      });
    }

    function useMyLocation() {
      if (pickerRef.current && pickerRef.current.goToMyLocation) {
        pickerRef.current.goToMyLocation().then(function() {
          window.showUserToast('Pin placed at your location', 'lime');
        }).catch(function() {
          window.showUserToast('Allow location access to drop a pin here', 'rose');
        });
        return;
      }
      if (!navigator.geolocation) return;
      navigator.geolocation.getCurrentPosition(function(pos) {
        setLat(Number(pos.coords.latitude.toFixed(6)));
        setLng(Number(pos.coords.longitude.toFixed(6)));
        if (markerRef.current) {
          markerRef.current.setPosition({ lat: pos.coords.latitude, lng: pos.coords.longitude });
        }
      });
    }

    async function publishOpportunity() {
      if (!window.CBOpportunities.canPublish(user)) {
        window.showUserToast('Get verified before publishing', 'rose');
        setTab('settings');
        return;
      }
      if (!name.trim()) { window.showUserToast('Property name required', 'rose'); return; }
      setPublishing(true);
      try {
        var created = await window.CBOpportunities.create({
          name: name,
          propertyType: ptype,
          description: desc,
          requirements: req,
          address: address,
          city: city,
          lat: Number(lat),
          lng: Number(lng),
          challengeRadiusMeters: Number(radius),
          reward: reward,
          deadline: deadline || undefined,
          maxSubmissions: Number(maxSub),
          fundingGoal: Number(goal) * 1000,
          publish: true,
          status: 'open',
        });
        if (files.length && created._id) {
          await window.CBOpportunities.uploadMedia(created._id, files, { kind: 'image' });
        }
        window.showUserToast('Opportunity published on the map!', 'lime');
        window.navigate('opportunity-detail', { id: created._id });
      } catch (e) {
        window.showUserToast(e.message || 'Publish failed', 'rose');
      } finally {
        setPublishing(false);
      }
    }

    var menu = [{ id: 'dashboard', label: 'Dashboard' }];
    menu.push({ id: 'properties', label: profile.entity });
    menu.push({ id: 'publish', label: profile.publishLabel });
    menu.push({ id: 'challenges', label: 'Active Challenges' });
    if (profile.extra.indexOf('moderation') > -1) menu.push({ id: 'moderation', label: 'Moderation Queue' });
    if (profile.extra.indexOf('available') > -1) menu.push({ id: 'available', label: 'Available Projects' });
    if (role === 'property_owner') menu.push({ id: 'saved', label: 'Saved Concepts' });
    menu.push({ id: 'analytics', label: 'Analytics' });
    menu.push({ id: 'settings', label: 'Settings / Verify' });

    var hover = function(){ document.body.classList.add('hov'); };
    var leave = function(){ document.body.classList.remove('hov'); };

    return (
      <div className="sites-dash" data-role={role}>
        <div className="sites-dash__fx" aria-hidden="true">
          <div className="sites-dash__aurora" />
        </div>
        <div className="sites-dash__inner">
          <header className="sites-hero" data-tour="owner-hero" style={{ '--role-accent': profile.accent }}>
            <div className="sites-hero__top">
              <button type="button" className="sites-hero__back"
                onMouseEnter={hover} onMouseLeave={leave}
                onClick={function(){ window.navigate('opportunities'); }}>
                ← Sites
              </button>
              <div className="sites-hero__badge">
                <span className="sites-hero__badge-dot" />
                {role === 'municipality' ? 'Municipality' : role === 'developer' ? 'Developer' : 'Owner'}
              </div>
            </div>
            <div className="sites-hero__row">
              <div className="sites-hero__copy">
                <h1 className="sites-hero__title">{profile.title}</h1>
                <p className="sites-hero__sub">{profile.sub}</p>
              </div>
              <div className="sites-hero__actions">
                <button type="button" className="sites-btn sites-btn--ghost"
                  onMouseEnter={hover} onMouseLeave={leave}
                  onClick={function(){ window.navigate('opportunities'); }}>
                  Browse map
                </button>
                {window.CBOpportunities.canPublish(user) && (
                  <button type="button" className="sites-btn sites-btn--primary"
                    onMouseEnter={hover} onMouseLeave={leave}
                    onClick={function(){ setTab('publish'); }}>
                    {profile.publishLabel}
                  </button>
                )}
              </div>
            </div>
          </header>
          <div className="owner-shell">
          <aside className="owner-side">
            {menu.map(function(m) {
              return (
                <button key={m.id} type="button" className={tab === m.id ? 'on' : ''} onClick={function(){ setTab(m.id); }}>
                  {m.label}
                </button>
              );
            })}
          </aside>
          <main>
            {tab === 'dashboard' && (
              <div>
                <div className="opp-stat-grid" style={{ marginBottom:18 }}>
                  <div className="opp-stat"><div className="v">{(analytics && analytics.count) || mine.length}</div><div className="l">Sites</div></div>
                  <div className="opp-stat"><div className="v">{(analytics && analytics.totals && analytics.totals.views) || 0}</div><div className="l">Views</div></div>
                  <div className="opp-stat"><div className="v">{(analytics && analytics.totals && analytics.totals.submissions) || 0}</div><div className="l">Submissions</div></div>
                  <div className="opp-stat"><div className="v">${Math.round(((analytics && analytics.totals && analytics.totals.raised) || 0) / 1000)}K</div><div className="l">Raised</div></div>
                </div>
                {!window.CBOpportunities.canPublish(user) && (
                  <div className="opp-section">
                    <h3>Get Verified to Publish</h3>
                    <p style={{ color:'var(--text-dim)' }}>Only verified property owners, municipalities, and developers can publish opportunities.</p>
                    <button className="btn btn-v" onClick={function(){ setTab('settings'); }}>Start Verification</button>
                  </div>
                )}
                <div className="opp-section">
                  <h3>Quick Actions</h3>
                  <div style={{ display:'flex', gap:8, flexWrap:'wrap' }}>
                    <button className="btn btn-v" onClick={function(){ setTab('publish'); }}>Publish site</button>
                    <button className="btn btn-o" onClick={function(){ window.navigate('opportunities'); }}>Browse map</button>
                  </div>
                </div>
              </div>
            )}

            {tab === 'properties' && (
              <div className="opp-feed">
                {mine.length === 0 && (
                  <div className="empty-state">
                    <img src="/assets/gamification/app/empty-projects.webp" alt="" />
                    <div className="es-title">No properties listed yet</div>
                    <div className="es-sub">Post your first opportunity and let the city's designers compete for it.</div>
                  </div>
                )}
                {mine.map(function(o) {
                  return (
                    <div key={o._id} className="opp-card" onClick={function(){ window.navigate('opportunity-detail', { id: o._id }); }}>
                      <div className="opp-card-thumb" style={{ background:'oklch(0.22 0.04 295)' }} />
                      <div>
                        <div className="opp-card-meta">{o.status} · {o.stats && o.stats.submissions || 0} concepts</div>
                        <div className="opp-card-title">{o.name}</div>
                        <div className="opp-card-req">{o.location && o.location.address}</div>
                      </div>
                    </div>
                  );
                })}
              </div>
            )}

            {tab === 'challenges' && (
              <div className="opp-feed">
                {mine.filter(function(o){ return o.status === 'open' || o.status === 'closing_soon'; }).map(function(o) {
                  return (
                    <div key={o._id} className="opp-section">
                      <div className="opp-card-title">{o.challenge && o.challenge.title || o.name}</div>
                      <div className="opp-card-meta">
                        Deadline {o.challenge && o.challenge.deadline ? new Date(o.challenge.deadline).toLocaleDateString() : '—'}
                        {' · '}{o.stats && o.stats.submissions || 0} submissions
                      </div>
                      <button className="btn btn-o" style={{ marginTop:10 }} onClick={function(){ window.navigate('opportunity-detail', { id: o._id }); }}>
                        Review Concepts
                      </button>
                    </div>
                  );
                })}
                {!mine.filter(function(o){ return o.status === 'open' || o.status === 'closing_soon'; }).length && (
                  <div className="opp-section">No active challenges.</div>
                )}
              </div>
            )}

            {tab === 'moderation' && (
              <div className="opp-feed">
                <div className="opp-section" style={{ marginBottom: 12 }}>
                  <h3 style={{ marginTop: 0 }}>City Moderation Queue</h3>
                  <p style={{ color:'var(--text-dim)' }}>Community and owner proposals awaiting municipal approval before they go public on the map.</p>
                </div>
                {modQueue.length === 0 && (
                  <div className="empty-state">
                    <img src="/assets/gamification/app/empty-search.webp" alt="" />
                    <div className="es-title">Queue is clear</div>
                    <div className="es-sub">No proposals are waiting for review right now.</div>
                  </div>
                )}
                {modQueue.map(function(o) {
                  return (
                    <div key={o._id} className="opp-section" style={{ marginBottom: 10 }}>
                      <div className="opp-card-meta">{o.propertyType} · {(o.owner && o.owner.name) || 'Proposer'}</div>
                      <div className="opp-card-title">{o.name}</div>
                      <div className="opp-card-req">{o.location && o.location.address}</div>
                      <div style={{ display:'flex', gap:8, marginTop:10, flexWrap:'wrap' }}>
                        <button className="btn btn-v" disabled={busyId === o._id} onClick={function(){ moderateOpp(o._id, 'open'); }}>
                          {busyId === o._id ? '…' : 'Approve & Publish'}
                        </button>
                        <button className="btn btn-o" disabled={busyId === o._id} onClick={function(){ moderateOpp(o._id, 'suspended'); }}>Reject</button>
                        <button className="btn btn-o" onClick={function(){ window.navigate('opportunity-detail', { id: o._id }); }}>Review</button>
                      </div>
                    </div>
                  );
                })}
              </div>
            )}

            {tab === 'available' && (
              <div className="opp-feed">
                <div className="opp-section" style={{ marginBottom: 12 }}>
                  <h3 style={{ marginTop: 0 }}>Projects Open for Construction</h3>
                  <p style={{ color:'var(--text-dim)' }}>Approved, funded opportunities ready for a verified developer to take over and build.</p>
                </div>
                {avail.length === 0 && (
                  <div className="empty-state">
                    <img src="/assets/gamification/app/empty-projects.webp" alt="" />
                    <div className="es-title">No projects available</div>
                    <div className="es-sub">Approved projects open for takeover will appear here.</div>
                  </div>
                )}
                {avail.map(function(o) {
                  return (
                    <div key={o._id} className="opp-section" style={{ marginBottom: 10 }}>
                      <div className="opp-card-meta">{o.propertyType} · {(o.funding && Math.round((o.funding.raised || 0) / 1000)) || 0}K raised</div>
                      <div className="opp-card-title">{o.name}</div>
                      <div className="opp-card-req">{o.location && o.location.address}</div>
                      <div style={{ display:'flex', gap:8, marginTop:10, flexWrap:'wrap' }}>
                        <button className="btn btn-v" disabled={busyId === o._id} onClick={function(){ takeoverProject(o._id); }}>
                          {busyId === o._id ? '…' : 'Take Over Build'}
                        </button>
                        <button className="btn btn-o" onClick={function(){ window.navigate('opportunity-detail', { id: o._id }); }}>View Details</button>
                      </div>
                    </div>
                  );
                })}
              </div>
            )}

            {tab === 'saved' && (
              <div className="opp-section">
                <h3>Saved Concepts</h3>
                <p style={{ color:'var(--text-dim)' }}>Shortlisted and bookmarked concepts appear on each opportunity’s review panel.</p>
              </div>
            )}

            {tab === 'analytics' && (
              <div className="opp-stat-grid">
                <div className="opp-stat"><div className="v">{(analytics && analytics.totals && analytics.totals.views) || 0}</div><div className="l">Views</div></div>
                <div className="opp-stat"><div className="v">{(analytics && analytics.totals && analytics.totals.bookmarks) || 0}</div><div className="l">Bookmarks</div></div>
                <div className="opp-stat"><div className="v">{(analytics && analytics.totals && analytics.totals.participants) || 0}</div><div className="l">Participants</div></div>
                <div className="opp-stat"><div className="v">{(analytics && analytics.totals && analytics.totals.submissions) || 0}</div><div className="l">Submissions</div></div>
              </div>
            )}

            {tab === 'settings' && (
              <div className="wizard-panel">
                <h3 style={{ marginTop:0 }}>Verification</h3>
                <p style={{ color:'var(--text-dim)' }}>
                  Status: <strong>{(user && user.verificationStatus) || 'none'}</strong>
                  {user && user.verificationType ? ' · ' + user.verificationType : ''}
                </p>
                <label>Apply as</label>
                <select value={verifyType} onChange={function(e){ setVerifyType(e.target.value); }}>
                  <option value="property_owner">Property Owner</option>
                  <option value="developer">Developer / Private Firm</option>
                  <option value="municipality">Municipality</option>
                </select>
                <label>Organization name</label>
                <input value={org} onChange={function(e){ setOrg(e.target.value); }} placeholder="Acme Holdings / City Planning" />
                <label>Notes</label>
                <textarea value={notes} onChange={function(e){ setNotes(e.target.value); }} placeholder="Ownership proof, business license, municipal department…" />
                <button className="btn btn-v" onClick={applyVerify}>Submit Verification Request</button>
              </div>
            )}

            {tab === 'publish' && (
              <div>
                <div className="wizard-steps">
                  {STEPS.map(function(s, i) {
                    return (
                      <span key={s} className={'wizard-step-pill' + (i === step ? ' on' : i < step ? ' done' : '')}>{i + 1}. {s}</span>
                    );
                  })}
                </div>
                <div className="wizard-panel">
                  {step === 0 && (
                    <>
                      <label>Property / Opportunity Name</label>
                      <input value={name} onChange={function(e){ setName(e.target.value); }} placeholder="West Square Redevelopment" />
                      <label>Property Type</label>
                      <select value={ptype} onChange={function(e){ setPtype(e.target.value); }}>
                        {TYPES.map(function(t){ return <option key={t.id} value={t.id}>{t.label}</option>; })}
                      </select>
                    </>
                  )}
                  {step === 1 && (
                    <>
                      <label>Search address</label>
                      <input
                        id="opp-places-input"
                        ref={searchInputRef}
                        value={address}
                        onChange={function(e){ setAddress(e.target.value); }}
                        placeholder="Search address, place, or landmark…"
                        autoComplete="off"
                      />
                      <div className="wizard-map wizard-map--tall" style={{ position:'relative' }}>
                        <div ref={mapRef} style={{ position:'absolute', inset:0 }} />
                        {!mapReady && (
                          <div className="opp-map-fallback">
                            {mapError
                              ? (
                                <div>
                                  <div style={{ marginBottom: 8, color: 'var(--rose)' }}>{mapError}</div>
                                  <div>Map failed to load — you can still type lat/lng below.</div>
                                </div>
                              )
                              : 'Loading interactive map…'}
                          </div>
                        )}
                      </div>
                      <p className="opp-map-hint" style={{ marginTop: 0 }}>
                        Tap the map to drop a pin · drag the pin to fine-tune · search like Google Maps · Use Current Location
                      </p>
                      <div style={{ display:'grid', gridTemplateColumns:'1fr 1fr 1fr', gap:10 }}>
                        <div><label>Latitude</label><input value={lat} onChange={function(e){
                          setLat(e.target.value);
                          if (pickerRef.current) pickerRef.current.setPosition(e.target.value, lng, false);
                        }} /></div>
                        <div><label>Longitude</label><input value={lng} onChange={function(e){
                          setLng(e.target.value);
                          if (pickerRef.current) pickerRef.current.setPosition(lat, e.target.value, false);
                        }} /></div>
                        <div><label>Challenge radius (m)</label><input type="number" value={radius} onChange={function(e){ setRadius(e.target.value); }} /></div>
                      </div>
                      <label>City</label>
                      <input value={city} onChange={function(e){ setCity(e.target.value); }} />
                      <button className="btn btn-o" type="button" onClick={useMyLocation}>Use Current Location</button>
                    </>
                  )}
                  {step === 2 && (
                    <>
                      <label>Upload site photos / drone / street / blueprints</label>
                      <input type="file" multiple accept="image/*,.pdf,video/*" onChange={function(e){
                        setFiles(Array.from(e.target.files || []));
                      }} />
                      <div className="opp-card-meta">{files.length} file(s) selected</div>
                    </>
                  )}
                  {step === 3 && (
                    <>
                      <label>Property description</label>
                      <textarea value={desc} onChange={function(e){ setDesc(e.target.value); }}
                        placeholder="Current condition, issues, history, utilities, accessibility…" />
                    </>
                  )}
                  {step === 4 && (
                    <>
                      <label>Landlord requirements</label>
                      <textarea value={req} onChange={function(e){ setReq(e.target.value); }}
                        placeholder="We need a modern shopping complex / children’s park / sustainable architecture…" />
                    </>
                  )}
                  {step === 5 && (
                    <>
                      <label>Reward</label>
                      <input value={reward} onChange={function(e){ setReward(e.target.value); }} placeholder="Featured on city portal + $5K stipend" />
                      <label>Deadline</label>
                      <input type="date" value={deadline} onChange={function(e){ setDeadline(e.target.value); }} />
                      <label>Max submissions</label>
                      <input type="number" value={maxSub} onChange={function(e){ setMaxSub(e.target.value); }} />
                      <label>Crowdfunding goal ($K)</label>
                      <input type="number" value={goal} onChange={function(e){ setGoal(e.target.value); }} />
                    </>
                  )}
                  {step === 6 && (
                    <>
                      <h3 style={{ marginTop:0 }}>Ready to publish</h3>
                      <p style={{ color:'var(--text-dim)' }}>
                        <strong>{name || 'Untitled'}</strong> · {ptype} · {address || (lat + ', ' + lng)}
                      </p>
                      <p style={{ color:'var(--text-dim)' }}>This opportunity will appear on the public map immediately for verified publishers.</p>
                    </>
                  )}
                  <div className="wizard-actions">
                    {step > 0 && <button className="btn btn-o" onClick={function(){ setStep(step - 1); }}>Back</button>}
                    {step < STEPS.length - 1 && (
                      <button className="btn btn-v" onClick={function(){ setStep(step + 1); }}>Continue</button>
                    )}
                    {step === STEPS.length - 1 && (
                      <button className="btn btn-v" disabled={publishing} onClick={publishOpportunity}>
                        {publishing ? 'Publishing…' : 'Publish Opportunity'}
                      </button>
                    )}
                  </div>
                </div>
              </div>
            )}
          </main>
          </div>
        </div>
      </div>
    );
  }

  window.UserOwnerDashboardPage = OwnerDashboardPage;
})();
