// Tasks.jsx — Each task is a sub-screen. Auto-save on confirm.
// Plus the secondary tabs: Map, Capture, QA, Profile.

// ─────────────── Shared task shell ───────────────
function TaskShell({ children, ctaLabel, onCta, disabled, hint, secondary }) {
  return (
    <div style={{display:'flex',flexDirection:'column',minHeight:'100%'}}>
      <div style={{flex:1,padding:'16px 18px 100px',display:'flex',flexDirection:'column',gap:14}}>
        {children}
      </div>
      <div style={{position:'sticky',bottom:0,padding:'12px 18px 16px',background:'linear-gradient(180deg,rgba(246,248,247,0) 0%, #F6F8F7 30%)',display:'flex',flexDirection:'column',gap:6}}>
        {hint && <div style={{fontSize:11,color:'#6B7280',textAlign:'center'}}>{hint}</div>}
        <div style={{display:'flex',gap:10}}>
          {secondary}
          <button onClick={onCta} disabled={disabled} style={{flex:1,padding:'14px',background: disabled ? '#9CA3AF' : '#022C28',color:'#fff',border:'none',borderRadius:12,fontWeight:900,fontSize:15,cursor: disabled ? 'not-allowed':'pointer',fontFamily:'inherit',letterSpacing:'-0.01em',opacity: disabled ? 0.6 : 1}}>
            {ctaLabel}
          </button>
        </div>
      </div>
    </div>
  );
}

// Section card with eyebrow
function Field({ label, hint, children, state }) {
  // state: 'ai' | 'confirmed' | 'flagged' | 'measured' | undefined
  const stateColors = {
    ai:        { dot:'#0077B6', label:'AI suggested · review' },
    confirmed: { dot:'#2BC48A', label:'Confirmed' },
    flagged:   { dot:'#D97706', label:'Flagged · attention' },
    measured:  { dot:'#7C5CFC', label:'Measured' },
  };
  const s = state && stateColors[state];
  return (
    <div style={{background:'#fff',border:'1px solid #E5E7EB',borderRadius:12,padding:'14px 16px'}}>
      <div style={{display:'flex',justifyContent:'space-between',alignItems:'flex-start',gap:8,marginBottom:8}}>
        <div style={{flex:1,minWidth:0}}>
          <div style={{fontSize:10,fontWeight:800,letterSpacing:'0.08em',textTransform:'uppercase',color:'#6B7280'}}>{label}</div>
          {hint && <div style={{fontSize:11,color:'#9CA3AF',marginTop:2}}>{hint}</div>}
        </div>
        {s && <div style={{display:'inline-flex',alignItems:'center',gap:4,fontSize:9,fontWeight:800,letterSpacing:'0.04em',color:s.dot}}>
          <span style={{width:6,height:6,borderRadius:'50%',background:s.dot}}/>{s.label.toUpperCase()}
        </div>}
      </div>
      {children}
    </div>
  );
}

// Looks like a select, opens a bottom-sheet picker
function SelectButton({ value, placeholder, onClick }) {
  return (
    <button onClick={onClick} style={{width:'100%',padding:'12px 14px',background:'#F9FAFB',border:'1.5px solid #E5E7EB',borderRadius:10,textAlign:'left',display:'flex',alignItems:'center',gap:10,cursor:'pointer',fontFamily:'inherit'}}>
      <div style={{flex:1,fontSize:14,fontWeight:value?700:500,color:value?'#022C28':'#9CA3AF'}}>{value || placeholder}</div>
      <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="#6B7280" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><polyline points="6 9 12 15 18 9"/></svg>
    </button>
  );
}

// Inline yes/no/uncertain chip group
function ChipPicker({ value, options, onChange, compact }) {
  return (
    <div style={{display:'flex',gap:6,flexWrap:'wrap'}}>
      {options.map(([v,l])=>{
        const sel = value === v;
        return <button key={v} onClick={()=>onChange(v)} style={{padding: compact?'8px 12px':'10px 14px',background: sel ? '#022C28' : '#fff',color: sel ? '#fff' : '#022C28',border:`1.5px solid ${sel?'#022C28':'#E5E7EB'}`,borderRadius:999,fontWeight:800,fontSize:13,cursor:'pointer',fontFamily:'inherit'}}>{l}</button>;
      })}
    </div>
  );
}

// ─────────────── LOCATION TASK ───────────────
function LocationTask({ visit, data, update, onDone, ai }) {
  const [adminPick, setAdminPick] = React.useState(null);
  const [country, setCountry] = React.useState(data.country || 'Kenya');
  const [county,  setCounty]  = React.useState(data.county  || 'Busia');
  const [subCnty, setSubCnty] = React.useState(data.subCnty || (visit.sublocality.includes('Budalangi') ? 'Budalangi' : 'Budalangi'));
  const [ward,    setWard]    = React.useState(data.ward    || visit.village.split('·')[0].trim());
  const [village, setVillage] = React.useState(data.village || (visit.village.split('·')[1]?.trim() || ''));

  const adminOptions = {
    country: Object.keys(ADMIN_TREE),
    county:  Object.keys(ADMIN_TREE[country] || {}),
    subCnty: Object.keys((ADMIN_TREE[country] && ADMIN_TREE[country][county]) || {}),
    ward:    ((ADMIN_TREE[country] && ADMIN_TREE[country][county] && ADMIN_TREE[country][county][subCnty]) || []),
  };

  const confirm = () => {
    update({ locationConfirmed:true, country, county, subCnty, ward, village });
    onDone();
  };

  return (
    <TaskShell ctaLabel="Confirm location" onCta={confirm}>
      {/* GPS card */}
      <div style={{background:'#022C28',color:'#fff',borderRadius:12,padding:'16px',display:'flex',gap:14,alignItems:'flex-start'}}>
        <div style={{width:42,height:42,borderRadius:10,background:'rgba(244,195,0,0.15)',color:'#F4C300',display:'flex',alignItems:'center',justifyContent:'center',flexShrink:0}}>
          <svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M21 10c0 7-9 13-9 13s-9-6-9-13a9 9 0 0 1 18 0z"/><circle cx="12" cy="10" r="3"/></svg>
        </div>
        <div style={{flex:1,minWidth:0}}>
          <div style={{display:'flex',alignItems:'center',gap:6,marginBottom:4}}>
            <span style={{width:8,height:8,borderRadius:'50%',background:'#2BC48A',animation:'pulse 1.5s infinite'}}/>
            <span style={{fontSize:10,fontWeight:800,letterSpacing:'0.1em',color:'#2BC48A',fontFamily:"'JetBrains Mono', monospace"}}>LIVE · ±4 m</span>
          </div>
          <div style={{fontSize:16,fontWeight:900,letterSpacing:'-0.01em',fontFamily:"'JetBrains Mono', monospace"}}>0°10'06"N · 34°00'58"E</div>
          <div style={{fontSize:12,color:'rgba(255,255,255,0.7)',marginTop:4}}>0.16838, 34.01646 · alt 1,176 m · 09:42:18</div>
        </div>
      </div>

      {/* Mini map preview */}
      <div style={{position:'relative',height:140,borderRadius:12,overflow:'hidden',background:'linear-gradient(135deg,#1a3d39 0%,#022C28 100%)'}}>
        <svg width="100%" height="100%" viewBox="0 0 360 140" style={{position:'absolute',inset:0}} preserveAspectRatio="xMidYMid slice">
          <defs><pattern id="lmgrid" width="22" height="22" patternUnits="userSpaceOnUse"><path d="M 22 0 L 0 0 0 22" fill="none" stroke="rgba(255,255,255,0.05)" strokeWidth="0.5"/></pattern></defs>
          <rect width="360" height="140" fill="url(#lmgrid)"/>
          <path d="M0,50 Q90,42 180,52 T360,46" stroke="rgba(43,196,138,0.25)" strokeWidth="4" fill="none"/>
          <path d="M40,140 L65,90 L120,80 L200,95 L280,70 L320,110 L360,100" stroke="rgba(244,195,0,0.18)" strokeWidth="3" fill="none"/>
          <text x="20" y="40" fontSize="9" fill="rgba(43,196,138,0.7)" fontFamily="'JetBrains Mono', monospace">YALA RIVER</text>
          {/* Pin */}
          <g transform="translate(180,72)">
            <circle r="22" fill="rgba(244,195,0,0.15)"/>
            <circle r="12" fill="rgba(244,195,0,0.25)"/>
            <circle r="6" fill="#F4C300" stroke="#fff" strokeWidth="2"/>
          </g>
        </svg>
        <div style={{position:'absolute',bottom:8,right:8,background:'rgba(2,28,24,0.8)',color:'#F4C300',padding:'4px 8px',borderRadius:6,fontSize:9,fontWeight:800,letterSpacing:'0.08em',fontFamily:"'JetBrains Mono', monospace"}}>SATELLITE · CACHED</div>
      </div>

      {/* AI inferred banner */}
      {ai && <div style={{background:'#EFF6FF',border:'1px solid #BFDBFE',borderRadius:10,padding:'12px 14px',display:'flex',gap:10,alignItems:'flex-start'}}>
        <div style={{width:24,height:24,borderRadius:6,background:'#0077B6',color:'#fff',display:'flex',alignItems:'center',justifyContent:'center',flexShrink:0,marginTop:1}}>
          <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5"><path d="M12 2v4M12 18v4M4.93 4.93l2.83 2.83M16.24 16.24l2.83 2.83M2 12h4M18 12h4"/></svg>
        </div>
        <div style={{flex:1,minWidth:0}}>
          <div style={{fontSize:12,fontWeight:800,color:'#1E40AF'}}>Admin hierarchy inferred from GPS</div>
          <div style={{fontSize:11,color:'#1E40AF',marginTop:2,opacity:0.85}}>Kenya · Busia · Budalangi · Bunyala Central — review and confirm or tap to change.</div>
        </div>
      </div>}

      {/* Hierarchy fields — pre-filled, tap to override */}
      <Field label="Country" state="ai">
        <SelectButton value={country} onClick={()=>setAdminPick('country')}/>
      </Field>
      <Field label="County · Level 2" state="ai">
        <SelectButton value={county} onClick={()=>setAdminPick('county')}/>
      </Field>
      <Field label="Sub-county · Level 3" state="ai">
        <SelectButton value={subCnty} onClick={()=>setAdminPick('subCnty')}/>
      </Field>
      <Field label="Ward · Level 4" state="ai">
        <SelectButton value={ward} onClick={()=>setAdminPick('ward')}/>
      </Field>
      <Field label="Village (optional)">
        <input value={village} onChange={(e)=>setVillage(e.target.value)} placeholder="e.g. Mau-Mau" style={{width:'100%',padding:'12px 14px',background:'#F9FAFB',border:'1.5px solid #E5E7EB',borderRadius:10,fontSize:14,fontWeight:600,color:'#022C28',outline:'none',boxSizing:'border-box',fontFamily:'inherit'}}/>
      </Field>

      {/* Admin picker bottom sheets */}
      <ListPicker open={adminPick==='country'} onClose={()=>setAdminPick(null)} title="Country" options={adminOptions.country} value={country} onPick={(v)=>{setCountry(v); setCounty(''); setSubCnty(''); setWard('');}}/>
      <ListPicker open={adminPick==='county'}  onClose={()=>setAdminPick(null)} title="County" subtitle="Level 2 · Province / Region / County" options={adminOptions.county} value={county} onPick={(v)=>{setCounty(v); setSubCnty(''); setWard('');}}/>
      <ListPicker open={adminPick==='subCnty'} onClose={()=>setAdminPick(null)} title="Sub-county" subtitle="Level 3 · District / Zone / Sub-county / Constituency" options={adminOptions.subCnty} value={subCnty} onPick={(v)=>{setSubCnty(v); setWard('');}}/>
      <ListPicker open={adminPick==='ward'}    onClose={()=>setAdminPick(null)} title="Ward" subtitle="Level 4 · Commune / Woreda / Ward" options={adminOptions.ward} value={ward} onPick={setWard}/>

      <style>{`@keyframes pulse { 0%,100%{opacity:1} 50%{opacity:0.4} }`}</style>
    </TaskShell>
  );
}

// ─────────────── OWNER TASK ───────────────
function OwnerTask({ visit, data, update, onDone }) {
  const [name, setName] = React.useState(data.ownerName || visit.participant);
  const [phone, setPhone] = React.useState(data.ownerPhone || '+254 7');
  const [role, setRole] = React.useState(data.role || 'owner');
  const [tenure, setTenure] = React.useState(data.tenure || 'yes');
  const [tenurePick, setTenurePick] = React.useState(false);
  const [tenureType, setTenureType] = React.useState(data.tenureType || 'Title deed');
  const [docNo, setDocNo] = React.useState(data.docNo || '');
  const [consent, setConsent] = React.useState(data.consent ?? true);

  const showDocFields = tenure === 'yes' || tenure === 'pending';
  const canSave = !!name && !!phone && phone.replace(/\D/g,'').length >= 9 && !!tenure && (!showDocFields || !!tenureType) && consent;

  const save = () => {
    update({ ownerConfirmed:true, ownerName:name, ownerPhone:phone, role, tenure, tenureType, docNo, consent });
    onDone();
  };

  return (
    <TaskShell ctaLabel="Save owner & consent" onCta={save} disabled={!canSave} hint={!consent ? 'Consent required before submit' : null}>
      <Field label="Land owner full name" state={name?'confirmed':undefined}>
        <input value={name} onChange={(e)=>setName(e.target.value)} placeholder="Family name, First" style={{width:'100%',padding:'12px 14px',background:'#F9FAFB',border:'1.5px solid #E5E7EB',borderRadius:10,fontSize:15,fontWeight:700,color:'#022C28',outline:'none',boxSizing:'border-box',fontFamily:'inherit'}}/>
      </Field>
      <Field label="Phone number" hint="Used only for verification callbacks">
        <input value={phone} onChange={(e)=>setPhone(e.target.value)} inputMode="tel" placeholder="+254 7…" style={{width:'100%',padding:'12px 14px',background:'#F9FAFB',border:'1.5px solid #E5E7EB',borderRadius:10,fontSize:15,fontWeight:700,color:'#022C28',outline:'none',boxSizing:'border-box',fontFamily:"'JetBrains Mono', monospace"}}/>
      </Field>
      <Field label="Participant role">
        <ChipPicker value={role} onChange={setRole} options={[['owner','Owner'],['tenant','Tenant'],['manager','Manager'],['coop','Co-op rep'],['community','Community rep']]}/>
      </Field>
      <Field label="Land tenure or certificate" hint="Does the participant hold proof of right to the land?">
        <ChipPicker value={tenure} onChange={setTenure} options={[['yes','Yes'],['no','No'],['pending','Pending'],['unclear','Unclear']]}/>
      </Field>
      {showDocFields && <>
        <Field label="Tenure type" state="confirmed">
          <SelectButton value={tenureType} onClick={()=>setTenurePick(true)}/>
        </Field>
        <Field label="Document reference (optional)">
          <input value={docNo} onChange={(e)=>setDocNo(e.target.value)} placeholder="e.g. LR/BSA/004217" style={{width:'100%',padding:'12px 14px',background:'#F9FAFB',border:'1.5px solid #E5E7EB',borderRadius:10,fontSize:14,fontWeight:600,color:'#022C28',outline:'none',boxSizing:'border-box',fontFamily:"'JetBrains Mono', monospace"}}/>
        </Field>
      </>}
      {tenure === 'no' && <div style={{background:'#FEF2F2',border:'1px solid #FCA5A5',borderRadius:10,padding:'12px 14px',fontSize:12,color:'#7F1D1D',display:'flex',gap:10,alignItems:'flex-start'}}>
        <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="#DC2626" strokeWidth="2.2" strokeLinecap="round" strokeLinejoin="round" style={{flexShrink:0,marginTop:1}}><circle cx="12" cy="12" r="10"/><path d="M12 8v4M12 16h.01"/></svg>
        <div><b>Soft flag:</b> tenure status “No” will trigger supervisor review before enrollment is approved. Notes encouraged.</div>
      </div>}

      {/* Consent */}
      <div style={{background:'#FFF8E0',border:'1px solid #FDE68A',borderRadius:12,padding:'14px 16px'}}>
        <div style={{fontSize:10,fontWeight:800,letterSpacing:'0.08em',color:'#B8960A',textTransform:'uppercase'}}>Consent</div>
        <div style={{fontSize:14,fontWeight:700,color:'#022C28',marginTop:6,lineHeight:1.4}}>I read the project terms to the participant in their language. They agreed to share their data with Pamoja and the verifier.</div>
        <button onClick={()=>setConsent(c=>!c)} style={{marginTop:12,display:'flex',alignItems:'center',gap:10,background:'transparent',border:'none',padding:0,cursor:'pointer',fontFamily:'inherit'}}>
          <div style={{width:22,height:22,borderRadius:6,border:`2px solid ${consent?'#022C28':'#9CA3AF'}`,background:consent?'#022C28':'#fff',display:'flex',alignItems:'center',justifyContent:'center'}}>
            {consent && <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="#F4C300" strokeWidth="3.5" strokeLinecap="round" strokeLinejoin="round"><polyline points="20 6 9 17 4 12"/></svg>}
          </div>
          <div style={{fontSize:13,fontWeight:800,color:'#022C28'}}>Spoken consent captured</div>
        </button>
      </div>

      <ListPicker open={tenurePick} onClose={()=>setTenurePick(false)} title="Tenure type" options={TENURE_TYPES} value={tenureType} onPick={setTenureType}/>
    </TaskShell>
  );
}

// ─────────────── STAND TASK ───────────────
function StandTask({ visit, data, update, onDone, defaultKind }) {
  const [kind, setKind] = React.useState(data.standKind || visit.standKind || defaultKind);
  const [plantPick, setPlantPick] = React.useState(false);
  const [plantType, setPlantType] = React.useState(data.plantType || 'Farm boundary planting');
  const [form, setForm] = React.useState(data.bambooForm || 'clump'); // bamboo only
  const [agePick, setAgePick] = React.useState(false);
  const [age, setAge] = React.useState(data.age || (visit.type.includes('Y2') ? '2 years' : '1 year'));
  const [soilPick, setSoilPick] = React.useState(false);
  const [soil, setSoil] = React.useState(data.soil || 'Loam');
  const [speciesOpen, setSpeciesOpen] = React.useState(false);
  const [species, setSpecies] = React.useState(data.species || (kind==='Bamboo' ? ['sp_bbalcooa'] : (kind==='Tree' ? ['sp_grevillea'] : [])));
  const [dominant, setDominant] = React.useState(data.dominant || (species[0] || null));

  const isBamboo = kind === 'Bamboo';
  const canSave = !!kind && !!plantType && species.length > 0 && !!age && !!soil;

  const save = () => {
    update({ standConfirmed:true, standKind:kind, plantType, bambooForm:form, age, soil, species, dominant });
    onDone();
  };

  return (
    <TaskShell ctaLabel="Save stand details" onCta={save} disabled={!canSave}>
      <Field label="What is growing here?" hint="Pick the closest match for what you see on the plot">
        <div style={{display:'grid',gridTemplateColumns:'1fr 1fr',gap:8}}>
          {STAND_KINDS.map(sk => {
            const sel = kind === sk.id;
            return (
              <button key={sk.id} onClick={()=>setKind(sk.id)} style={{padding:'12px 12px',background: sel?'#022C28':'#fff',color: sel?'#fff':'#022C28',border: `1.5px solid ${sel?'#022C28':'#E5E7EB'}`,borderRadius:10,textAlign:'left',cursor:'pointer',fontFamily:'inherit'}}>
                <div style={{fontSize:14,fontWeight:800,letterSpacing:'-0.01em'}}>{sk.label}</div>
                <div style={{fontSize:11,color: sel?'rgba(255,255,255,0.7)':'#6B7280',marginTop:3,lineHeight:1.3}}>{sk.hint}</div>
              </button>
            );
          })}
        </div>
      </Field>

      <Field label="Where is it planted?" hint="On the homestead, along a fence, in a block, etc.">
        <SelectButton value={plantType} onClick={()=>setPlantPick(true)}/>
      </Field>

      {isBamboo && <Field label="Bamboo type" hint="Clump bamboo grows in a circle · running bamboo spreads sideways">
        <ChipPicker value={form} onChange={setForm} options={[['clump','Clump bamboo'],['running','Running bamboo']]}/>
      </Field>}

      {/* Species — biggest improvement vs legacy long-list modal */}
      <div style={{background:'#fff',border:'1px solid #E5E7EB',borderRadius:12,padding:'14px 16px'}}>
        <div style={{display:'flex',justifyContent:'space-between',alignItems:'flex-start',gap:8,marginBottom:8}}>
          <div>
            <div style={{fontSize:10,fontWeight:800,letterSpacing:'0.08em',textTransform:'uppercase',color:'#6B7280'}}>Which species are growing?</div>
            <div style={{fontSize:11,color:'#9CA3AF',marginTop:2}}>Search common or scientific name · pick all you see · mark the main one</div>
          </div>
          {species.length > 0 && <div style={{display:'inline-flex',alignItems:'center',gap:4,fontSize:9,fontWeight:800,letterSpacing:'0.04em',color:'#2BC48A'}}>
            <span style={{width:6,height:6,borderRadius:'50%',background:'#2BC48A'}}/>CONFIRMED
          </div>}
        </div>
        {species.length > 0 ? (
          <div style={{display:'flex',flexDirection:'column',gap:6}}>
            {species.map(id => {
              const s = speciesById(id);
              const isDom = dominant === id;
              return (
                <div key={id} style={{display:'flex',alignItems:'center',gap:10,padding:'8px 10px',background:'#F9FAFB',borderRadius:8}}>
                  <div style={{flex:1,minWidth:0}}>
                    <div style={{fontSize:13,fontWeight:800,color:'#022C28',display:'flex',gap:6,alignItems:'baseline'}}>
                      {s.common}
                      {isDom && <span style={{fontSize:9,fontWeight:800,letterSpacing:'0.06em',padding:'1px 5px',borderRadius:3,background:'#022C28',color:'#F4C300'}}>★ MAIN</span>}
                    </div>
                    <div style={{fontSize:11,color:'#6B7280',fontStyle:'italic'}}>{s.sci}</div>
                  </div>
                </div>
              );
            })}
            <button onClick={()=>setSpeciesOpen(true)} style={{marginTop:4,padding:'10px',background:'#fff',color:'#022C28',border:'1.5px dashed #E5E7EB',borderRadius:10,fontWeight:800,fontSize:13,cursor:'pointer',fontFamily:'inherit'}}>+ Edit species ({species.length})</button>
          </div>
        ) : (
          <button onClick={()=>setSpeciesOpen(true)} style={{width:'100%',padding:'14px',background:'#F9FAFB',color:'#022C28',border:'1.5px dashed #D1D5DB',borderRadius:10,fontWeight:800,fontSize:14,cursor:'pointer',fontFamily:'inherit'}}>+ Pick species</button>
        )}
      </div>

      <Field label="How old are the plants?" hint="Years since planting · pick a range if the exact year is unknown">
        <SelectButton value={age} onClick={()=>setAgePick(true)}/>
      </Field>
      <Field label="Soil type">
        <SelectButton value={soil} onClick={()=>setSoilPick(true)}/>
      </Field>

      <ListPicker open={plantPick} onClose={()=>setPlantPick(false)} title="Planting type" options={PLANTATION_TYPES} value={plantType} onPick={setPlantType}/>
      <ListPicker open={agePick} onClose={()=>setAgePick(false)} title="Age band" options={AGE_BANDS} value={age} onPick={setAge}/>
      <ListPicker open={soilPick} onClose={()=>setSoilPick(false)} title="Soil type" options={SOIL_TYPES} value={soil} onPick={setSoil}/>
      <SpeciesPicker open={speciesOpen} onClose={()=>setSpeciesOpen(false)} value={species} dominant={dominant} onChange={setSpecies} onDominantChange={setDominant} standKind={kind}/>
    </TaskShell>
  );
}

// ─────────────── MEASUREMENT TASK ───────────────
function MeasureTask({ visit, data, update, onDone, defaultGeom }) {
  const isBamboo = (data.standKind || visit.standKind) === 'Bamboo';
  const unitWord = isBamboo ? 'clumps' : 'plants';
  const [geom, setGeom] = React.useState(data.geometry || defaultGeom);
  const [polyPoints, setPolyPoints] = React.useState(data.polyPoints || 0);
  const [walking, setWalking] = React.useState(false);
  const [area, setArea] = React.useState(data.area || (visit.plotLabel.match(/[\d.]+/)?.[0] || '1.0'));
  const [unit, setUnit] = React.useState(data.unit || 'ha');
  const [method, setMethod] = React.useState(data.method || (defaultGeom==='Polygon' ? 'gps_polygon' : 'estimate'));
  const [density, setDensity] = React.useState(data.density || '450');
  const [survival, setSurvival] = React.useState(data.survival || '85');

  const startWalk = () => {
    setWalking(true);
    let n = polyPoints;
    const iv = setInterval(()=>{ n += 1; setPolyPoints(n); if (n >= 7) { clearInterval(iv); setWalking(false); setMethod('gps_polygon'); } }, 450);
  };

  const canSave = !!area && !!unit && !!method;
  const save = () => {
    update({ measureConfirmed:true, geometry:geom, polyPoints, area, unit, method, density, survival });
    onDone();
  };

  return (
    <TaskShell ctaLabel="Save measurements" onCta={save} disabled={!canSave}>
      {/* Plot shape choice */}
      <Field label="How will you mark the plot?" hint="One GPS pin in the middle, or walk the boundary">
        <ChipPicker value={geom} onChange={setGeom} options={[['Point','One GPS pin'],['Polygon','Walk the boundary']]}/>
      </Field>

      {/* Map canvas */}
      <div style={{position:'relative',height:200,borderRadius:12,overflow:'hidden',background:'linear-gradient(135deg,#1a3d39 0%,#022C28 100%)'}}>
        <svg width="100%" height="100%" viewBox="0 0 360 200" style={{position:'absolute',inset:0}} preserveAspectRatio="xMidYMid slice">
          <defs><pattern id="mgrid" width="22" height="22" patternUnits="userSpaceOnUse"><path d="M 22 0 L 0 0 0 22" fill="none" stroke="rgba(255,255,255,0.05)" strokeWidth="0.5"/></pattern></defs>
          <rect width="360" height="200" fill="url(#mgrid)"/>
          <path d="M0,80 Q90,72 180,82 T360,76" stroke="rgba(43,196,138,0.18)" strokeWidth="3" fill="none"/>
          {geom === 'Point' ? (
            <g transform="translate(180,100)">
              <circle r="24" fill="rgba(244,195,0,0.15)"/>
              <circle r="14" fill="rgba(244,195,0,0.3)"/>
              <circle r="7" fill="#F4C300" stroke="#fff" strokeWidth="2"/>
            </g>
          ) : (
            <>
              {/* Polygon points */}
              {[[120,60],[230,55],[280,110],[260,160],[170,170],[100,150],[80,100]].slice(0, polyPoints).map((p,i,arr)=>{
                const next = arr[(i+1)%arr.length];
                return (
                  <g key={i}>
                    {next && i < arr.length-1 && <line x1={p[0]} y1={p[1]} x2={next[0]} y2={next[1]} stroke="#F4C300" strokeWidth="2" strokeDasharray="4 3"/>}
                    <circle cx={p[0]} cy={p[1]} r="5" fill="#F4C300" stroke="#fff" strokeWidth="1.5"/>
                  </g>
                );
              })}
              {polyPoints >= 3 && <polygon
                points={[[120,60],[230,55],[280,110],[260,160],[170,170],[100,150],[80,100]].slice(0, polyPoints).map(p=>p.join(',')).join(' ')}
                fill="rgba(244,195,0,0.18)" stroke="#F4C300" strokeWidth="1.5"/>}
            </>
          )}
        </svg>
        <div style={{position:'absolute',top:10,left:12,fontSize:10,fontWeight:800,letterSpacing:'0.1em',color:'#F4C300',fontFamily:"'JetBrains Mono', monospace"}}>
          {geom==='Point' ? 'POINT · 0.16838, 34.01646' : `POLYGON · ${polyPoints} pts captured`}
        </div>
        {geom === 'Polygon' && (
          <button onClick={startWalk} disabled={walking} style={{position:'absolute',bottom:10,right:10,background: walking ? 'rgba(220,38,38,0.9)' : '#F4C300',color: walking ? '#fff' : '#022C28',border:'none',padding:'8px 14px',borderRadius:8,fontWeight:900,fontSize:12,cursor:walking?'not-allowed':'pointer',fontFamily:'inherit',letterSpacing:'-0.01em'}}>
            {walking ? `Walking… ${polyPoints} pts` : (polyPoints > 0 ? 'Continue walk' : 'Start boundary walk')}
          </button>
        )}
      </div>

      <Field label="Total area" state={method==='gps_polygon'?'measured':undefined}>
        <div style={{display:'flex',gap:8}}>
          <input value={area} onChange={(e)=>setArea(e.target.value)} inputMode="decimal" style={{flex:2,padding:'12px 14px',background:'#F9FAFB',border:'1.5px solid #E5E7EB',borderRadius:10,fontSize:18,fontWeight:900,color:'#022C28',outline:'none',boxSizing:'border-box',fontFamily:"'JetBrains Mono', monospace"}}/>
          <button onClick={()=>setUnit(u=>u==='ha'?'m²':u==='m²'?'acres':'ha')} style={{flex:1,padding:'12px',background:'#022C28',color:'#fff',border:'none',borderRadius:10,fontSize:13,fontWeight:800,cursor:'pointer',fontFamily:'inherit',letterSpacing:'0.04em'}}>{unit}</button>
        </div>
      </Field>

      <Field label="How was the area measured?">
        <ChipPicker value={method} onChange={setMethod} compact options={[
          ['estimate','Household told me'],
          ['tape','Tape measure'],
          ['gps_polygon','GPS walk'],
          ['parcel','From land record'],
        ]}/>
      </Field>

      <Field label={isBamboo ? 'Clumps per hectare' : 'Plants per hectare'} hint={`Roughly how many living ${unitWord} in one hectare. VM0047 §1.2 caps this at 50 / ha for census-based sites.`}>
        <input value={density} onChange={(e)=>setDensity(e.target.value)} inputMode="numeric" style={{width:'100%',padding:'12px 14px',background:'#F9FAFB',border:'1.5px solid #E5E7EB',borderRadius:10,fontSize:18,fontWeight:900,color:'#022C28',outline:'none',boxSizing:'border-box',fontFamily:"'JetBrains Mono', monospace"}}/>
      </Field>

      {/* VM0047 §1.2 / §4.3: census-based REQUIRES a complete one-by-one census.
          If a site is too large or hilly for full census, the project lead must set
          it up as area-based (plot-based sampling) — not a census-with-sampling. */}
      <div style={{background:'#EFF6FF',border:'1px solid #BFDBFE',borderRadius:12,padding:'14px 16px'}}>
        <div style={{display:'flex',alignItems:'flex-start',gap:10}}>
          <div style={{width:26,height:26,borderRadius:6,background:'#0077B6',color:'#fff',display:'flex',alignItems:'center',justifyContent:'center',flexShrink:0,marginTop:1}}>
            <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round"><circle cx="12" cy="12" r="10"/><line x1="12" y1="8" x2="12" y2="12"/><line x1="12" y1="16" x2="12.01" y2="16"/></svg>
          </div>
          <div style={{flex:1,minWidth:0}}>
            <div style={{fontSize:12,fontWeight:900,color:'#1E40AF',letterSpacing:'-0.01em'}}>How do I count this site?</div>
            <div style={{fontSize:12,color:'#1E40AF',marginTop:4,lineHeight:1.5}}>
              Census sites need <b>every {isBamboo?'clump':'plant'} tapped one-by-one</b> at t = 0. That's a Verra rule for census-based projects (VM0047 §1.2 and §4.3).
            </div>
            <div style={{fontSize:12,color:'#1E40AF',marginTop:8,lineHeight:1.5}}>
              If the site is too big or too hilly to walk every {isBamboo?'clump':'plant'}, tell your supervisor — they will switch this site to the <b>area-based approach</b>, where you walk a few sample plots instead. You can't mix the two on the same site.
            </div>
          </div>
        </div>
      </div>

      <Field label="How many are alive?" hint="Out of every 100 planted, how many are still living">
        <div style={{display:'flex',alignItems:'center',gap:12}}>
          <input type="range" min="0" max="100" value={survival} onChange={(e)=>setSurvival(e.target.value)} style={{flex:1,accentColor:'#F4C300'}}/>
          <div style={{minWidth:48,textAlign:'right',fontSize:18,fontWeight:900,color:'#022C28',fontFamily:"'JetBrains Mono', monospace"}}>{survival}%</div>
        </div>
      </Field>
    </TaskShell>
  );
}

// ─────────────── SHUTTER PHOTOS BOARD ───────────────
// Fullscreen, camera-style multi-shot capture. Shared by:
//   • PhotosTask (census site: site, closeup, species, document)
//   • PlotPhotosTask (area cardinals: N, E, S, W, centre, panorama)
function ShutterPhotosBoard({ slots, value, onChange, onCancel, onDone, renderScene, ai }) {
  const pickNextPending = (val) => {
    const critical = slots.find(s => s.critical && !val[s.id]);
    if (critical) return critical.id;
    const any = slots.find(s => !val[s.id]);
    return any ? any.id : slots[0].id;
  };
  const [activeId, setActiveId] = React.useState(() => pickNextPending(value));
  const [flash, setFlash] = React.useState(false);
  const [aiReview, setAiReview] = React.useState(null);

  const active = slots.find(s => s.id === activeId) || slots[0];
  const criticalLeft = slots.filter(s => s.critical && !value[s.id]);
  const allCriticalDone = criticalLeft.length === 0;

  const shoot = () => {
    if (value[activeId]) return; // already captured
    setFlash(true);
    setTimeout(()=>setFlash(false), 380);
    const newValue = { ...value, [activeId]: true };
    onChange(newValue);
    if (ai) {
      setAiReview('checking');
      setTimeout(()=>{ setAiReview('ok'); setTimeout(()=>setAiReview(null), 900); }, 700);
    }
    setTimeout(() => {
      const next = pickNextPending(newValue);
      if (next !== activeId) setActiveId(next);
    }, 280);
  };

  return (
    <div style={{position:'relative',height:'100%',display:'flex',flexDirection:'column',background:'#0e1f15',overflow:'hidden'}}>
      {/* Top bar */}
      <div style={{padding:'12px 16px',background:'rgba(2,28,24,0.9)',display:'flex',alignItems:'center',gap:10,flexShrink:0,position:'relative',zIndex:3}}>
        <button onClick={onCancel} aria-label="Back" style={{background:'rgba(255,255,255,0.08)',border:'none',color:'#fff',padding:6,borderRadius:8,cursor:'pointer',display:'flex'}}>
          <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.2" strokeLinecap="round" strokeLinejoin="round"><path d="M19 12H5M12 19l-7-7 7-7"/></svg>
        </button>
        <div style={{flex:1,minWidth:0,color:'#fff'}}>
          <div style={{fontSize:10,fontWeight:800,letterSpacing:'0.1em',color:'#F4C300',fontFamily:"'JetBrains Mono', monospace"}}>SHOT {slots.findIndex(s=>s.id===activeId)+1} OF {slots.length} · {Object.values(value).filter(Boolean).length} CAPTURED</div>
          <div style={{fontSize:16,fontWeight:900,letterSpacing:'-0.01em',marginTop:1,whiteSpace:'nowrap',overflow:'hidden',textOverflow:'ellipsis'}}>{active.label}</div>
        </div>
        {allCriticalDone && (
          <button onClick={onDone} style={{padding:'10px 16px',background:'#F4C300',color:'#022C28',border:'none',borderRadius:10,fontWeight:900,fontSize:13,cursor:'pointer',fontFamily:'inherit',letterSpacing:'-0.01em'}}>
            Save
          </button>
        )}
      </div>

      {/* Viewfinder */}
      <div style={{flex:1,position:'relative',overflow:'hidden'}}>
        {renderScene ? renderScene(active) : <DefaultScene active={active}/>}
        {/* HUD */}
        <div style={{position:'absolute',top:12,left:12,right:12,display:'flex',justifyContent:'space-between',pointerEvents:'none'}}>
          <div style={{fontSize:10,fontWeight:800,letterSpacing:'0.1em',color:'#F4C300',background:'rgba(2,28,24,0.7)',padding:'5px 9px',borderRadius:6,fontFamily:"'JetBrains Mono', monospace"}}>
            {value[activeId] ? 'CAPTURED · 09:42' : `LIVE · ${active.hudLabel || active.label.toUpperCase()}`}
          </div>
          <div style={{fontSize:10,fontWeight:800,letterSpacing:'0.08em',color:'#fff',background:'rgba(2,28,24,0.7)',padding:'5px 9px',borderRadius:6,fontFamily:"'JetBrains Mono', monospace"}}>
            ±3.4 m · {active.bearing != null ? `MAG ${active.bearing}°` : 'GPS'}
          </div>
        </div>
        {!value[activeId] && (
          <>
            <div style={{position:'absolute',inset:'15% 11%',border:'2px dashed rgba(244,195,0,0.55)',borderRadius:8,pointerEvents:'none'}}/>
            {active.sub && <div style={{position:'absolute',bottom:18,left:18,right:18,textAlign:'center',pointerEvents:'none',fontSize:12,fontWeight:700,color:'rgba(255,255,255,0.85)',textShadow:'0 2px 8px rgba(0,0,0,0.8)',lineHeight:1.4}}>
              {active.sub}
            </div>}
          </>
        )}
        {flash && <div style={{position:'absolute',inset:0,background:'rgba(255,255,255,0.85)',animation:'flash .4s ease-out',pointerEvents:'none'}}/>}
        {aiReview && (
          <div style={{position:'absolute',bottom:60,left:14,right:14,background:'rgba(245,240,255,0.95)',border:'1px solid #DDD6FE',borderRadius:10,padding:'8px 12px',display:'flex',alignItems:'center',gap:8,backdropFilter:'blur(8px)'}}>
            {aiReview === 'checking' ? (
              <>
                <div style={{width:14,height:14,borderRadius:'50%',border:'2px solid #7C3AED',borderTopColor:'transparent',animation:'spin 0.8s linear infinite'}}/>
                <div style={{fontSize:11,fontWeight:700,color:'#5B21B6'}}>AI checking shot…</div>
              </>
            ) : (
              <>
                <div style={{width:16,height:16,borderRadius:'50%',background:'#059669',color:'#fff',display:'flex',alignItems:'center',justifyContent:'center',fontSize:10,fontWeight:900}}>✓</div>
                <div style={{fontSize:11,fontWeight:700,color:'#5B21B6'}}>Sharp · framed · GPS in range</div>
              </>
            )}
          </div>
        )}
      </div>

      {/* Thumbnail strip */}
      <div style={{padding:'10px 16px',background:'rgba(2,28,24,0.9)',display:'flex',gap:8,overflowX:'auto',flexShrink:0,scrollbarWidth:'none'}}>
        {slots.map(s => {
          const done = !!value[s.id];
          const isActive = s.id === activeId;
          return (
            <button key={s.id} onClick={()=>setActiveId(s.id)} style={{flexShrink:0,minWidth:64,padding:'8px 10px',background: done ? 'rgba(43,196,138,0.18)' : isActive ? 'rgba(244,195,0,0.18)' : 'rgba(255,255,255,0.05)',border:`1.5px solid ${done ? 'rgba(43,196,138,0.5)' : isActive ? '#F4C300' : 'rgba(255,255,255,0.1)'}`,borderRadius:10,cursor:'pointer',fontFamily:'inherit',color:'#fff',display:'flex',flexDirection:'column',alignItems:'center',gap:3}}>
              <div style={{width:24,height:24,borderRadius:'50%',background: done ? '#2BC48A' : 'transparent',border: !done ? `2px solid ${isActive?'#F4C300':'rgba(255,255,255,0.3)'}` : 'none',display:'flex',alignItems:'center',justifyContent:'center',color: done?'#022C28':isActive?'#F4C300':'rgba(255,255,255,0.6)',fontWeight:900,fontSize:11,fontFamily:"'JetBrains Mono', monospace"}}>
                {done ? '✓' : (s.thumb || s.id.charAt(0).toUpperCase())}
              </div>
              <div style={{fontSize:9,fontWeight:800,letterSpacing:'0.04em',color: done ? '#2BC48A' : isActive ? '#F4C300' : 'rgba(255,255,255,0.55)',whiteSpace:'nowrap'}}>
                {s.shortLabel || s.label.split(' ')[0]}
                {s.critical && !done && <span style={{color:'#DC2626',marginLeft:3}}>•</span>}
              </div>
            </button>
          );
        })}
      </div>

      {/* Shutter */}
      <div style={{position:'relative',background:'#022C28',padding:'18px 18px 22px',display:'flex',alignItems:'center',justifyContent:'center',gap:18,flexShrink:0}}>
        <button onClick={shoot} disabled={!!value[activeId]} aria-label="Take photo" style={{width:80,height:80,borderRadius:'50%',background: value[activeId] ? 'rgba(43,196,138,0.3)' : '#fff',border:`5px solid ${value[activeId] ? 'rgba(43,196,138,0.5)' : 'rgba(244,195,0,0.4)'}`,cursor: value[activeId]?'default':'pointer',fontFamily:'inherit',position:'relative',padding:0,boxShadow: value[activeId] ? 'none' : '0 0 0 4px rgba(255,255,255,0.1), 0 12px 36px rgba(244,195,0,0.3)',transition:'all .2s ease'}}>
          {value[activeId] ? (
            <svg width="34" height="34" viewBox="0 0 24 24" fill="none" stroke="#2BC48A" strokeWidth="3" strokeLinecap="round" strokeLinejoin="round" style={{position:'absolute',top:'50%',left:'50%',transform:'translate(-50%,-50%)'}}><polyline points="20 6 9 17 4 12"/></svg>
          ) : (
            <div style={{position:'absolute',inset:6,borderRadius:'50%',background:'#fff',border:'2px solid #022C28'}}/>
          )}
        </button>
      </div>
      {/* Hint line below shutter */}
      <div style={{position:'absolute',bottom:8,left:0,right:0,textAlign:'center',color:'rgba(255,255,255,0.45)',fontSize:10,fontFamily:"'JetBrains Mono', monospace",letterSpacing:'0.04em',pointerEvents:'none'}}>
        {value[activeId] ? 'Tap another shot above to continue' : criticalLeft.length > 0 ? `${criticalLeft.length} required shot${criticalLeft.length>1?'s':''} left` : 'All required shots done — tap save'}
      </div>

      <style>{`
        @keyframes flash { 0%{opacity:1} 100%{opacity:0} }
        @keyframes spin  { to { transform: rotate(360deg) } }
      `}</style>
    </div>
  );
}

function DefaultScene({ active }) {
  return (
    <svg width="100%" height="100%" viewBox="0 0 360 600" preserveAspectRatio="xMidYMid slice" style={{position:'absolute',inset:0}}>
      <rect width="360" height="260" fill="#243826"/>
      <rect y="260" width="360" height="340" fill="#0e1f15"/>
      {[[60,420],[140,440],[230,420],[310,430]].map(([x,y],i)=>(
        <g key={i}>
          <rect x={x-3} y={y} width="6" height="100" fill="#3a2818"/>
          <ellipse cx={x} cy={y-30} rx="38" ry="48" fill="rgba(43,196,138,0.55)"/>
          <ellipse cx={x-12} cy={y-50} rx="26" ry="32" fill="rgba(43,196,138,0.4)"/>
        </g>
      ))}
      {/* Faint horizon line */}
      <path d="M0 360 Q 180 350 360 358" stroke="rgba(255,255,255,0.06)" strokeWidth="1" fill="none"/>
    </svg>
  );
}

// ─────────────── PHOTOS TASK ───────────────
function PhotosTask({ visit, data, update, onDone, ai }) {
  const [photos, setPhotos] = React.useState(data.photos || {});
  const slots = [
    { id:'site',     label:'Wide photo of the plot', sub:'Stand back and show the whole plot and what is around it', critical:true,  shortLabel:'Wide',    thumb:'W' },
    { id:'closeup',  label:'Close-up of the plants', sub:'Show stems, leaves, growth — close enough to identify',     critical:true,  shortLabel:'Close',   thumb:'C' },
    { id:'species',  label:'Species photo',          sub:'Only if you marked species unknown or saw a second species', critical:false, shortLabel:'Species', thumb:'S' },
    { id:'document', label:'Photo of the land paper',sub:'Only if the owner has a title deed or other paper',          critical:false, shortLabel:'Paper',   thumb:'D' },
  ];
  const requiredDone = slots.filter(s=>s.critical).every(s=>photos[s.id]);
  return (
    <ShutterPhotosBoard
      slots={slots}
      value={photos}
      onChange={setPhotos}
      onCancel={onDone}
      onDone={()=>{ update({ photosConfirmed:true, photos }); onDone(); }}
      ai={ai}
    />
  );
}

// ─────────────── REVIEW TASK ───────────────
function ReviewTask({ visit, data, onSubmit }) {
  const items = [
    { ok:!!data.locationConfirmed, label:'Location confirmed',     val: data.locationConfirmed ? `${data.country} · ${data.county} · ${data.ward}` : 'Missing' },
    { ok:!!data.ownerConfirmed,    label:'Owner & consent',        val: data.ownerConfirmed    ? `${data.ownerName} · ${data.tenure==='yes'?'titled':'no doc'}` : 'Missing' },
    { ok:!!data.standConfirmed,    label:'What grows here',        val: data.standConfirmed    ? `${data.standKind || visit.standKind} · ${(data.species||[]).length || 0} species` : 'Missing' },
    { ok:!!data.measureConfirmed,  label:'Area & how many',        val: data.measureConfirmed  ? `${data.area} ${data.unit} · ${({estimate:'household told me',tape:'tape',gps_polygon:'GPS walk',parcel:'land record'})[data.method]||data.method}` : 'Missing' },
    { ok:!!data.photosConfirmed,   label:'Photos for proof',       val: data.photosConfirmed   ? `${Object.values(data.photos||{}).filter(Boolean).length} photos` : 'Missing' },
  ];
  const allGood = items.every(i => i.ok);

  return (
    <TaskShell ctaLabel={allGood ? 'Submit · sign locally' : `Fix ${items.filter(i=>!i.ok).length} task${items.filter(i=>!i.ok).length>1?'s':''}`} onCta={allGood?onSubmit:()=>{}} disabled={!allGood} hint={allGood ? 'Hashed and signed on this device. Syncs on Wi‑Fi.' : 'Open the brief to finish remaining tasks.'}>
      {/* Readiness ring */}
      <div style={{background:'#022C28',color:'#fff',borderRadius:14,padding:'18px',display:'flex',alignItems:'center',gap:16}}>
        <div style={{position:'relative',width:72,height:72,flexShrink:0}}>
          <svg width="72" height="72" viewBox="0 0 72 72">
            <circle cx="36" cy="36" r="30" fill="none" stroke="rgba(255,255,255,0.12)" strokeWidth="6"/>
            <circle cx="36" cy="36" r="30" fill="none" stroke={allGood?'#2BC48A':'#F4C300'} strokeWidth="6" strokeDasharray={`${(items.filter(i=>i.ok).length/items.length)*188.5} 188.5`} strokeLinecap="round" transform="rotate(-90 36 36)"/>
          </svg>
          <div style={{position:'absolute',inset:0,display:'flex',alignItems:'center',justifyContent:'center',fontSize:18,fontWeight:900,color:allGood?'#2BC48A':'#F4C300',letterSpacing:'-0.02em'}}>{Math.round((items.filter(i=>i.ok).length/items.length)*100)}%</div>
        </div>
        <div style={{flex:1,minWidth:0}}>
          <div style={{fontSize:10,fontWeight:800,letterSpacing:'0.1em',color:'#F4C300',fontFamily:"'JetBrains Mono', monospace"}}>READINESS · {visit.id}</div>
          <div style={{fontSize:16,fontWeight:900,letterSpacing:'-0.01em',marginTop:3,lineHeight:1.25}}>{allGood ? 'Ready to submit' : 'Almost there'}</div>
          <div style={{fontSize:12,color:'rgba(255,255,255,0.7)',marginTop:3}}>{allGood ? 'Hard checks pass. Hash will anchor to Hedera on sync.' : `${items.filter(i=>!i.ok).length} required task${items.filter(i=>!i.ok).length>1?'s':''} still open.`}</div>
        </div>
      </div>

      <div style={{background:'#fff',border:'1px solid #E5E7EB',borderRadius:12,overflow:'hidden'}}>
        {items.map((it,i)=>(
          <div key={i} style={{display:'flex',gap:10,padding:'12px 14px',borderBottom: i<items.length-1?'1px solid #F3F4F6':'none',alignItems:'center'}}>
            <div style={{width:24,height:24,borderRadius:'50%',background: it.ok?'#059669':'#DC2626',color:'#fff',display:'flex',alignItems:'center',justifyContent:'center',flexShrink:0}}>
              {it.ok ? <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="3" strokeLinecap="round" strokeLinejoin="round"><polyline points="20 6 9 17 4 12"/></svg>
                     : <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="3"><line x1="6" y1="6" x2="18" y2="18"/><line x1="6" y1="18" x2="18" y2="6"/></svg>}
            </div>
            <div style={{flex:1,minWidth:0}}>
              <div style={{fontSize:13,fontWeight:800,color:'#022C28'}}>{it.label}</div>
              <div style={{fontSize:11,color:'#6B7280',marginTop:2}}>{it.val}</div>
            </div>
          </div>
        ))}
      </div>

      {/* Transparency footer */}
      <div style={{background:'#F5F0FF',border:'1px solid #DDD6FE',borderRadius:10,padding:'12px 14px'}}>
        <div style={{fontSize:10,fontWeight:800,letterSpacing:'0.08em',color:'#5B21B6',fontFamily:"'JetBrains Mono', monospace"}}>TRANSPARENCY · SIGNED LOCALLY</div>
        <div style={{display:'flex',justifyContent:'space-between',fontSize:11,color:'#5B21B6',marginTop:6,fontFamily:"'JetBrains Mono', monospace"}}><span>Agent</span><span>0042 · Mary Wanjiru</span></div>
        <div style={{display:'flex',justifyContent:'space-between',fontSize:11,color:'#5B21B6',marginTop:2,fontFamily:"'JetBrains Mono', monospace"}}><span>Device</span><span>tecno-ka7-002a</span></div>
        <div style={{display:'flex',justifyContent:'space-between',fontSize:11,color:'#5B21B6',marginTop:2,fontFamily:"'JetBrains Mono', monospace"}}><span>SHA-256</span><span>9c4f…b821</span></div>
        <div style={{display:'flex',justifyContent:'space-between',fontSize:11,color:'#5B21B6',marginTop:2,fontFamily:"'JetBrains Mono', monospace"}}><span>Hedera</span><span>queued · anchors on sync</span></div>
      </div>

      {/* What we send to verifiers — Verra payload preview */}
      <VerraPayloadPreview visit={visit} data={data}/>
    </TaskShell>
  );
}

function VerraPayloadPreview({ visit, data }) {
  const isBamboo = (data.standKind || visit.standKind) === 'Bamboo';
  const unitWord = isBamboo ? 'clumps' : 'plants';
  const photoCount = Object.values(data.photos || {}).filter(Boolean).length;
  const density = parseFloat(data.density) || 0;
  const overDensity = density > 50;
  const speciesCount = (data.species || []).length;

  return (
    <div style={{background:'#fff',border:'1.5px solid #022C28',borderRadius:12,overflow:'hidden'}}>
      <div style={{padding:'12px 14px',background:'#022C28',color:'#fff',display:'flex',alignItems:'center',gap:10}}>
        <div style={{width:26,height:26,borderRadius:6,background:'#F4C300',color:'#022C28',display:'flex',alignItems:'center',justifyContent:'center',flexShrink:0}}>
          <svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.2" strokeLinecap="round" strokeLinejoin="round"><path d="M9 11l3 3L22 4"/><path d="M21 12v7a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11"/></svg>
        </div>
        <div style={{flex:1,minWidth:0}}>
          <div style={{fontSize:10,fontWeight:800,letterSpacing:'0.1em',color:'#F4C300',fontFamily:"'JetBrains Mono', monospace"}}>WHAT WE SEND TO VERIFIERS</div>
          <div style={{fontSize:13,fontWeight:800,letterSpacing:'-0.01em',marginTop:1}}>Verra VM0047 v1.1 · census-based package</div>
        </div>
      </div>
      <div style={{padding:'4px 0'}}>
        {[
          { l:'Site',           v:`${visit.id} · ${visit.participant}` },
          { l:'Project',        v:visit.project },
          { l:'Total area',     v:`${data.area} ${data.unit}` },
          { l:`Total ${unitWord} (N)`, v:`Complete census · t=0`, bold:true, sub:`VM0047 §4.3 \u2014 every ${isBamboo?'clump':'plant'} tapped` },
          { l:'Density check',  v:`${density} / ha · ${overDensity ? 'OVER 50/ha' : 'within 50/ha cap'}`, warn: overDensity, sub:'VM0047 §1.2 — census-based density ceiling' },
          { l:'Species',        v:`${speciesCount} unique`, sub:'Per-species allometric equations applied server-side (§9.2.2)' },
          { l:'Sampling subset',v:'DBH + height on subset · field method recorded' },
          { l:'Survival',       v:`${data.survival || '—'} %` },
          { l:'Photos attached',v:`${photoCount} of 4` },
          { l:'GPS quality',    v:'±4 m at capture · WGS84' },
          { l:'Signed',         v:'SHA-256 locally · Hedera on sync' },
        ].map((row,i,a) => (
          <div key={i} style={{padding:'9px 14px',borderBottom: i<a.length-1 ? '1px solid #F3F4F6' : 'none',display:'flex',justifyContent:'space-between',alignItems:'flex-start',gap:10}}>
            <div style={{fontSize:11,fontWeight:700,color:'#6B7280',flexShrink:0,minWidth:110}}>{row.l}</div>
            <div style={{textAlign:'right',minWidth:0,flex:1}}>
              <div style={{fontSize:12.5,fontWeight: row.bold?900:700,color: row.warn ? '#DC2626' : '#022C28',letterSpacing:'-0.01em',wordBreak:'break-word',fontFamily: row.bold ? "'JetBrains Mono', monospace" : 'inherit'}}>{row.v}</div>
              {row.sub && <div style={{fontSize:10.5,color:'#6B7280',marginTop:2,fontFamily:"'JetBrains Mono', monospace"}}>{row.sub}</div>}
            </div>
          </div>
        ))}
      </div>
      <div style={{padding:'10px 14px',background:'#F6F8F7',fontSize:11,color:'#6B7280',lineHeight:1.5}}>
        This is exactly the data Verra and the VVB receive after sync. If the density is over 50/ha or anything else looks wrong, fix it before submitting — once signed, the record is locked.
      </div>
    </div>
  );
}

// ─────────────── ROUTE MAP ───────────────
function RefoRouteMap({ onOpen }) {
  const [selected, setSelected] = React.useState(VISITS[0].id);
  const colors = { critical:'#DC2626', partial:'#F59E0B', ready:'#059669', callback:'#7C3AED' };
  const pins = VISITS.map((v,i) => ({
    ...v,
    x: 50 + i * 60 + (i%2===0 ? -10 : 10),
    y: 70 + (i%2===0 ? 0 : 50) + Math.sin(i)*15,
    order: i+1,
  }));
  const sel = pins.find(p=>p.id===selected) || pins[0];
  const routeD = 'M ' + pins.map(p=>`${p.x},${p.y}`).join(' L ');

  return (
    <div style={{display:'flex',flexDirection:'column',height:'100%'}}>
      <div style={{position:'relative',flex:1,background:'linear-gradient(135deg,#1a3d39 0%,#022C28 100%)',overflow:'hidden'}}>
        <svg width="100%" height="100%" viewBox="0 0 360 220" preserveAspectRatio="xMidYMid slice">
          <defs><pattern id="rmgrid" width="24" height="24" patternUnits="userSpaceOnUse"><path d="M 24 0 L 0 0 0 24" fill="none" stroke="rgba(255,255,255,0.05)" strokeWidth="0.5"/></pattern></defs>
          <rect width="360" height="220" fill="url(#rmgrid)"/>
          <path d="M0,40 Q60,55 120,45 T260,60 T360,50" stroke="rgba(43,196,138,0.18)" strokeWidth="3" fill="none"/>
          <text x="20" y="36" fontSize="9" fill="rgba(43,196,138,0.6)" fontFamily="'JetBrains Mono', monospace">YALA RIVER · WETLAND</text>
          <path d="M0,90 L360,110" stroke="rgba(244,195,0,0.18)" strokeWidth="4" fill="none"/>
          <path d={routeD} stroke="#F4C300" strokeWidth="2" fill="none" strokeDasharray="4 4" opacity="0.85"/>
          {pins.map(p=>{
            const c = colors[p.status];
            const isSel = p.id===selected;
            return (
              <g key={p.id} transform={`translate(${p.x},${p.y})`} style={{cursor:'pointer'}} onClick={()=>setSelected(p.id)}>
                {isSel && <circle r="16" fill={c} opacity="0.25"/>}
                <circle r="11" fill={c} stroke="#fff" strokeWidth="2"/>
                <text x="0" y="4" textAnchor="middle" fontSize="10" fontWeight="900" fill="#fff" fontFamily="'JetBrains Mono', monospace">{p.order}</text>
              </g>
            );
          })}
          <g transform="translate(20,200)">
            <circle r="14" fill="#F4C300" opacity="0.25"/>
            <circle r="7" fill="#F4C300" stroke="#022C28" strokeWidth="2"/>
          </g>
        </svg>
        <div style={{position:'absolute',top:12,left:12,right:12,display:'flex',gap:6,flexWrap:'wrap'}}>
          {['critical','partial','ready','callback'].map(s=>(
            <div key={s} style={{display:'inline-flex',alignItems:'center',gap:5,background:'rgba(2,28,24,0.7)',padding:'4px 8px',borderRadius:6,fontSize:10,color:'#fff',fontFamily:"'JetBrains Mono', monospace",fontWeight:700,letterSpacing:'0.04em',textTransform:'uppercase'}}>
              <span style={{width:7,height:7,borderRadius:'50%',background:colors[s]}}/>{s}
            </div>
          ))}
        </div>
        <div style={{position:'absolute',bottom:12,right:12,background:'rgba(2,28,24,0.85)',padding:'6px 10px',borderRadius:6,fontSize:10,color:'#F4C300',fontFamily:"'JetBrains Mono', monospace",fontWeight:800,letterSpacing:'0.06em'}}>6.7 KM · ≈75 MIN</div>
      </div>
      <div style={{padding:'14px 16px 16px',background:'#fff',borderTop:'1px solid #E5E7EB'}}>
        <div style={{display:'flex',alignItems:'baseline',justifyContent:'space-between'}}>
          <div>
            <div style={{fontSize:10,fontWeight:800,letterSpacing:'0.1em',color:colors[sel.status],fontFamily:"'JetBrains Mono', monospace"}}>STOP {sel.order} · {sel.id}</div>
            <div style={{fontSize:17,fontWeight:900,color:'#022C28',letterSpacing:'-0.01em',marginTop:2}}>{sel.participant}</div>
            <div style={{fontSize:12,color:'#6B7280',marginTop:2}}>{sel.distance} · {sel.standKind} · {sel.plotLabel}</div>
          </div>
          <span style={{fontSize:9,fontWeight:800,letterSpacing:'0.1em',padding:'3px 7px',borderRadius:4,background:`${colors[sel.status]}15`,color:colors[sel.status]}}>{sel.status.toUpperCase()}</span>
        </div>
        <div style={{display:'grid',gridTemplateColumns:'1fr 1fr',gap:8,marginTop:12}}>
          <button onClick={()=>onOpen(sel.id)} style={{padding:'12px',background:'#022C28',color:'#fff',border:'none',borderRadius:10,fontWeight:800,fontSize:13,cursor:'pointer',fontFamily:'inherit'}}>Open visit</button>
          <button style={{padding:'12px',background:'#fff',color:'#022C28',border:'1.5px solid #E5E7EB',borderRadius:10,fontWeight:800,fontSize:13,cursor:'pointer',fontFamily:'inherit',display:'inline-flex',alignItems:'center',justifyContent:'center',gap:6}}>
            <svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.2" strokeLinecap="round" strokeLinejoin="round"><polygon points="3 11 22 2 13 21 11 13 3 11"/></svg>
            Navigate
          </button>
        </div>
      </div>
    </div>
  );
}

// ─────────────── CAPTURE HUB (Quick photo/scan) ───────────────
function CaptureHub({ onPhoto, onScan }) {
  const recents = [
    { kind:'PHOTO', label:'Site overview',    value:'VST-0438 · 0.16, 34.02', t:'8 min ago' },
    { kind:'QR',    label:'Parcel tag scan',  value:'PCL-BSA-0492',           t:'22 min ago' },
    { kind:'AUDIO', label:'Household note',      value:'0:34 · Swahili',         t:'1 hr ago' },
  ];
  return (
    <div style={{padding:'16px 18px 24px',display:'flex',flexDirection:'column',gap:14}}>
      <div style={{background:'#022C28',color:'#fff',borderRadius:12,padding:'14px 16px'}}>
        <div style={{fontSize:10,fontWeight:800,letterSpacing:'0.1em',color:'#F4C300',fontFamily:"'JetBrains Mono', monospace"}}>QUICK CAPTURE</div>
        <div style={{fontSize:14,fontWeight:700,marginTop:6,lineHeight:1.4}}>Snap a photo or scan a tag now — attach to a visit later. GPS + time stamped automatically.</div>
      </div>
      <div style={{display:'grid',gridTemplateColumns:'1fr 1fr',gap:10}}>
        <button onClick={onPhoto} style={{padding:'24px 14px',background:'#fff',border:'1.5px solid #E5E7EB',borderRadius:12,display:'flex',flexDirection:'column',alignItems:'flex-start',gap:8,cursor:'pointer',fontFamily:'inherit'}}>
          <div style={{width:38,height:38,borderRadius:8,background:'#FFF8E0',color:'#B8960A',display:'flex',alignItems:'center',justifyContent:'center'}}>
            <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"><path d="M23 19a2 2 0 0 1-2 2H3a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h4l2-3h6l2 3h4a2 2 0 0 1 2 2z"/><circle cx="12" cy="13" r="4"/></svg>
          </div>
          <div style={{fontSize:15,fontWeight:900,color:'#022C28',letterSpacing:'-0.01em'}}>Photo</div>
          <div style={{fontSize:11,color:'#6B7280'}}>Site, stand, species</div>
        </button>
        <button onClick={onScan} style={{padding:'24px 14px',background:'#fff',border:'1.5px solid #E5E7EB',borderRadius:12,display:'flex',flexDirection:'column',alignItems:'flex-start',gap:8,cursor:'pointer',fontFamily:'inherit'}}>
          <div style={{width:38,height:38,borderRadius:8,background:'#EFF6FF',color:'#0077B6',display:'flex',alignItems:'center',justifyContent:'center'}}>
            <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"><path d="M3 7V5a2 2 0 0 1 2-2h2"/><path d="M17 3h2a2 2 0 0 1 2 2v2"/><path d="M21 17v2a2 2 0 0 1-2 2h-2"/><path d="M7 21H5a2 2 0 0 1-2-2v-2"/><path d="M7 12h10"/></svg>
          </div>
          <div style={{fontSize:15,fontWeight:900,color:'#022C28',letterSpacing:'-0.01em'}}>Scan QR</div>
          <div style={{fontSize:11,color:'#6B7280'}}>Parcel · seedling batch</div>
        </button>
        <button style={{padding:'18px 14px',background:'#fff',border:'1.5px solid #E5E7EB',borderRadius:12,display:'flex',flexDirection:'column',alignItems:'flex-start',gap:8,cursor:'pointer',fontFamily:'inherit'}}>
          <div style={{width:34,height:34,borderRadius:8,background:'#ECFDF5',color:'#059669',display:'flex',alignItems:'center',justifyContent:'center'}}>
            <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"><path d="M12 1a3 3 0 0 0-3 3v8a3 3 0 0 0 6 0V4a3 3 0 0 0-3-3z"/><path d="M19 10v2a7 7 0 0 1-14 0v-2"/><line x1="12" y1="19" x2="12" y2="23"/></svg>
          </div>
          <div style={{fontSize:14,fontWeight:900,color:'#022C28',letterSpacing:'-0.01em'}}>Audio note</div>
          <div style={{fontSize:11,color:'#6B7280'}}>Voice memo</div>
        </button>
        <button style={{padding:'18px 14px',background:'#fff',border:'1.5px solid #E5E7EB',borderRadius:12,display:'flex',flexDirection:'column',alignItems:'flex-start',gap:8,cursor:'pointer',fontFamily:'inherit'}}>
          <div style={{width:34,height:34,borderRadius:8,background:'#F5F0FF',color:'#7C3AED',display:'flex',alignItems:'center',justifyContent:'center'}}>
            <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"><circle cx="12" cy="12" r="10"/><line x1="12" y1="8" x2="12" y2="12"/><line x1="12" y1="16" x2="12.01" y2="16"/></svg>
          </div>
          <div style={{fontSize:14,fontWeight:900,color:'#022C28',letterSpacing:'-0.01em'}}>Issue · flag</div>
          <div style={{fontSize:11,color:'#6B7280'}}>Report a problem</div>
        </button>
      </div>

      <div>
        <div style={{display:'flex',justifyContent:'space-between',alignItems:'baseline',marginBottom:8}}>
          <div style={{fontSize:14,fontWeight:900,letterSpacing:'-0.01em'}}>Unattached today</div>
          <div style={{fontSize:11,color:'#6B7280',fontFamily:"'JetBrains Mono', monospace",fontWeight:700}}>Tap to attach</div>
        </div>
        <div style={{background:'#fff',border:'1px solid #E5E7EB',borderRadius:12,overflow:'hidden'}}>
          {recents.map((r,i)=>(
            <div key={i} style={{display:'flex',gap:12,padding:'12px 14px',alignItems:'center',borderBottom: i<recents.length-1 ? '1px solid #F3F4F6' : 'none'}}>
              <div style={{width:34,height:34,borderRadius:8,background:'#F6F8F7',color:'#022C28',display:'flex',alignItems:'center',justifyContent:'center',fontSize:10,fontWeight:900,fontFamily:"'JetBrains Mono', monospace",flexShrink:0}}>{r.kind}</div>
              <div style={{flex:1,minWidth:0}}>
                <div style={{fontSize:13,fontWeight:800,color:'#022C28',letterSpacing:'-0.01em'}}>{r.label}</div>
                <div style={{fontSize:11,color:'#6B7280',fontFamily:"'JetBrains Mono', monospace"}}>{r.value}</div>
              </div>
              <div style={{fontSize:10,fontWeight:700,color:'#9CA3AF',fontFamily:"'JetBrains Mono', monospace"}}>{r.t}</div>
            </div>
          ))}
        </div>
      </div>
    </div>
  );
}

// ─────────────── QA SCREEN ───────────────
function RefoQAScreen() {
  const flags = [
    { sev:'high', vid:'VST-0427', label:'GPS outside expected polygon', detail:'Captured 140 m from parcel boundary' },
    { sev:'high', vid:'VST-0442', label:'Disturbance · evidence missing', detail:'Photo of cut stems not yet attached' },
    { sev:'med',  vid:'VST-0431', label:'Species count inconsistent', detail:'Picker shows 1, photo suggests 2 species' },
    { sev:'med',  vid:'VST-0451', label:'Callback overdue', detail:'5 days past project callback window' },
    { sev:'low',  vid:'VST-0427', label:'Survival outside expected range', detail:'85% for year 1 boundary planting' },
  ];
  const sevC = { high:'#DC2626', med:'#F59E0B', low:'#6B7280' };
  return (
    <div style={{padding:'16px 18px 24px',display:'flex',flexDirection:'column',gap:14}}>
      <div style={{background:'#022C28',color:'#fff',borderRadius:14,padding:'18px',display:'flex',alignItems:'center',gap:18}}>
        <div style={{position:'relative',width:80,height:80,flexShrink:0}}>
          <svg width="80" height="80" viewBox="0 0 80 80">
            <circle cx="40" cy="40" r="34" fill="none" stroke="rgba(255,255,255,0.12)" strokeWidth="7"/>
            <circle cx="40" cy="40" r="34" fill="none" stroke="#F4C300" strokeWidth="7" strokeDasharray={`${0.78*213.6} 213.6`} strokeLinecap="round" transform="rotate(-90 40 40)"/>
          </svg>
          <div style={{position:'absolute',inset:0,display:'flex',flexDirection:'column',alignItems:'center',justifyContent:'center'}}>
            <div style={{fontSize:22,fontWeight:900,color:'#F4C300',letterSpacing:'-0.02em',lineHeight:1}}>78</div>
            <div style={{fontSize:8,fontWeight:700,letterSpacing:'0.1em',color:'rgba(255,255,255,0.6)',fontFamily:"'JetBrains Mono', monospace"}}>SCORE</div>
          </div>
        </div>
        <div style={{flex:1,minWidth:0}}>
          <div style={{fontSize:10,fontWeight:800,letterSpacing:'0.1em',color:'#F4C300',fontFamily:"'JetBrains Mono', monospace"}}>MY QA · MAY 2026</div>
          <div style={{fontSize:16,fontWeight:900,letterSpacing:'-0.01em',marginTop:3,lineHeight:1.25}}>Good practice tier</div>
          <div style={{fontSize:12,color:'rgba(255,255,255,0.7)',marginTop:3}}>Fix 2 high flags before period lock to keep enrollment eligibility.</div>
        </div>
      </div>
      <div style={{display:'grid',gridTemplateColumns:'1fr 1fr 1fr',gap:8}}>
        <RefoKPI label="Visits" value="42" color="#022C28"/>
        <RefoKPI label="Polygons" value="18" color="#059669"/>
        <RefoKPI label="Flags" value="5" color="#DC2626"/>
      </div>
      <div>
        <div style={{display:'flex',justifyContent:'space-between',alignItems:'baseline',marginBottom:10,paddingTop:4}}>
          <div style={{fontSize:14,fontWeight:900,letterSpacing:'-0.01em'}}>Open flags</div>
          <div style={{fontSize:11,color:'#6B7280',fontFamily:"'JetBrains Mono', monospace",fontWeight:700}}>By severity</div>
        </div>
        <div style={{display:'flex',flexDirection:'column',gap:8}}>
          {flags.map((f,i)=>(
            <div key={i} style={{background:'#fff',border:'1px solid #E5E7EB',borderRadius:12,padding:'12px 14px',display:'flex',gap:12,alignItems:'flex-start',position:'relative',overflow:'hidden'}}>
              <div style={{position:'absolute',top:0,bottom:0,left:0,width:3,background:sevC[f.sev]}}/>
              <div style={{paddingLeft:6,flex:1,minWidth:0}}>
                <div style={{display:'flex',alignItems:'center',gap:8,flexWrap:'wrap'}}>
                  <span style={{fontSize:9,fontWeight:800,letterSpacing:'0.1em',padding:'2px 6px',borderRadius:4,background:`${sevC[f.sev]}15`,color:sevC[f.sev]}}>{f.sev.toUpperCase()}</span>
                  <span style={{fontSize:10,fontWeight:800,letterSpacing:'0.08em',color:'#6B7280',fontFamily:"'JetBrains Mono', monospace"}}>{f.vid}</span>
                </div>
                <div style={{fontSize:14,fontWeight:800,color:'#022C28',marginTop:4,letterSpacing:'-0.01em'}}>{f.label}</div>
                <div style={{fontSize:12,color:'#6B7280',marginTop:2}}>{f.detail}</div>
              </div>
              <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="#9CA3AF" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" style={{flexShrink:0,marginTop:6}}><polyline points="9 18 15 12 9 6"/></svg>
            </div>
          ))}
        </div>
      </div>
      <div style={{padding:'12px 14px',background:'#fff',border:'1px dashed #E5E7EB',borderRadius:10,fontSize:11,color:'#6B7280',lineHeight:1.5}}>
        Flags map to project monitoring rules. Supervisors and VVB auditors see the same scoreboard.
      </div>
    </div>
  );
}

// ─────────────── PROFILE ───────────────
function RefoProfileScreen({ onSync, workspace, onSwitchWorkspace }) {
  const w = workspace && window.workspaceById ? window.workspaceById(workspace) : null;
  return (
    <div style={{padding:'16px 18px 40px',display:'flex',flexDirection:'column',gap:14}}>
      <div style={{background:'#022C28',color:'#fff',borderRadius:14,padding:'18px',display:'flex',alignItems:'center',gap:14}}>
        <div style={{width:54,height:54,borderRadius:'50%',background:'#F4C300',color:'#022C28',display:'flex',alignItems:'center',justifyContent:'center',fontWeight:900,fontSize:20,flexShrink:0}}>MW</div>
        <div style={{flex:1,minWidth:0}}>
          <div style={{fontSize:10,fontWeight:800,letterSpacing:'0.1em',color:'#F4C300',fontFamily:"'JetBrains Mono', monospace"}}>AGENT · ID 0042</div>
          <div style={{fontSize:18,fontWeight:900,letterSpacing:'-0.01em',marginTop:2}}>Mary Wanjiru</div>
          <div style={{fontSize:12,color:'rgba(255,255,255,0.7)',marginTop:2}}>Busia · since Aug 2024</div>
        </div>
      </div>
      <div style={{display:'grid',gridTemplateColumns:'1fr 1fr',gap:8}}>
        <RefoKPI label="Plots enrolled" value="142" color="#022C28"/>
        <RefoKPI label="Visits · May" value="42" color="#059669"/>
        <RefoKPI label="Polygons" value="18" color="#022C28"/>
        <RefoKPI label="Avg score" value="78" color="#F4C300"/>
      </div>

      {/* Workspace row */}
      {w && (
        <button onClick={onSwitchWorkspace} style={{background:'#fff',border:'1px solid #E5E7EB',borderRadius:12,padding:'14px 16px',display:'flex',alignItems:'center',gap:14,cursor:'pointer',fontFamily:'inherit',textAlign:'left'}}>
          <div style={{width:42,height:42,borderRadius:10,background: w.accent,color:'#fff',display:'flex',alignItems:'center',justifyContent:'center',flexShrink:0}}>
            <svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.7" strokeLinecap="round" strokeLinejoin="round"><path d={w.iconPath}/></svg>
          </div>
          <div style={{flex:1,minWidth:0}}>
            <div style={{fontSize:11,fontWeight:800,letterSpacing:'0.08em',color:'#6B7280',fontFamily:"'JetBrains Mono', monospace"}}>WORKSPACE</div>
            <div style={{fontSize:15,fontWeight:900,color:'#022C28',letterSpacing:'-0.01em',marginTop:2}}>{w.name}</div>
            <div style={{fontSize:11,color:'#6B7280',marginTop:1}}>Tap to switch — {w.id === 'reforestation' ? 'Cookstoves' : 'Reforestation'}</div>
          </div>
          <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="#9CA3AF" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" style={{flexShrink:0}}><polyline points="9 18 15 12 9 6"/></svg>
        </button>
      )}
      <div style={{background:'#fff',border:'1px solid #E5E7EB',borderRadius:12,padding:'14px 16px'}}>
        <div style={{display:'flex',justifyContent:'space-between',alignItems:'center'}}>
          <div>
            <div style={{fontSize:11,fontWeight:800,letterSpacing:'0.08em',color:'#6B7280',fontFamily:"'JetBrains Mono', monospace"}}>SYNC QUEUE</div>
            <div style={{fontSize:16,fontWeight:900,color:'#022C28',letterSpacing:'-0.01em',marginTop:3}}>5 records pending</div>
            <div style={{fontSize:12,color:'#6B7280',marginTop:2}}>Auto-syncs on Wi‑Fi · last attempt 09:14</div>
          </div>
          <button onClick={onSync} style={{padding:'10px 18px',background:'#F4C300',color:'#022C28',border:'none',borderRadius:8,fontWeight:900,fontSize:13,cursor:'pointer',fontFamily:'inherit',whiteSpace:'nowrap',flexShrink:0}}>Sync now</button>
        </div>
      </div>
      <div style={{background:'#fff',border:'1px solid #E5E7EB',borderRadius:12,overflow:'hidden'}}>
        {[
          { l:'Language', v:'English · Swahili · Luhya', i:'M2 12h20M12 2a14 14 0 0 1 0 20M12 2a14 14 0 0 0 0 20 M12 2a10 10 0 1 0 0 20 10 10 0 0 0 0-20z' },
          { l:'Offline maps', v:'Busia · 68 MB cached', i:'M9 20l-5.4-1.8a2 2 0 0 1-1.4-1.9V5.6a2 2 0 0 1 2.6-1.9L9 5m0 15l6-2m-6 2V5m6 13l5.4 1.8a2 2 0 0 0 2.6-1.9V6.4a2 2 0 0 0-1.4-1.9L15 3M15 18V3M9 5l6-2' },
          { l:'Species library', v:'19 species · 5 native', i:'M11 20A7 7 0 0 1 4 13 7 7 0 0 1 11 6h9v3a11 11 0 0 1-9 11z M2 22c0-7 5-12 12-12' },
          { l:'Data · tamper-evidence', v:'Signed at capture · SHA-256', i:'M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z' },
          { l:'About · v0.5.0-beta', v:'pamojadmrv.earth', i:'M12 2a10 10 0 1 0 0 20 10 10 0 0 0 0-20zM12 16v-4M12 8h.01' },
        ].map((s,i,a)=>(
          <div key={s.l} style={{display:'flex',alignItems:'center',gap:14,padding:'14px 16px',borderBottom: i<a.length-1 ? '1px solid #F3F4F6' : 'none'}}>
            <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="#022C28" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round" style={{flexShrink:0}}><path d={s.i}/></svg>
            <div style={{flex:1,minWidth:0}}>
              <div style={{fontSize:13,fontWeight:700,color:'#022C28',letterSpacing:'-0.01em'}}>{s.l}</div>
              <div style={{fontSize:11,color:'#6B7280',marginTop:1}}>{s.v}</div>
            </div>
            <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="#9CA3AF" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><polyline points="9 18 15 12 9 6"/></svg>
          </div>
        ))}
      </div>
      <button style={{padding:'14px',background:'#fff',color:'#022C28',border:'1.5px solid #E5E7EB',borderRadius:12,fontWeight:800,fontSize:14,cursor:'pointer',fontFamily:'inherit'}}>Sign out</button>
      <div style={{fontSize:11,color:'#9CA3AF',textAlign:'center',fontFamily:"'JetBrains Mono', monospace",letterSpacing:'0.02em',lineHeight:1.5}}>
        Pamoja dMRV Field · operator of pamojadmrv.earth<br/>By Consuming Carbon Corporation
      </div>
    </div>
  );
}

Object.assign(window, {
  TaskShell, Field, SelectButton, ChipPicker,
  LocationTask, OwnerTask, StandTask, MeasureTask, PhotosTask, ReviewTask,
  RefoRouteMap, CaptureHub, RefoQAScreen, RefoProfileScreen,
  ShutterPhotosBoard,
});
