// ======== components.js ========
const { useState, useEffect, useRef } = React;

const S = {
  card:{background:"var(--card)",border:"1px solid var(--border)",borderRadius:14,padding:16,marginBottom:12},
  ct:{fontSize:12,fontWeight:800,color:"var(--accent)",textTransform:"uppercase",letterSpacing:"0.12em",marginBottom:12,fontFamily:"var(--font)"},
  lb:{fontSize:10,color:"var(--muted)",textTransform:"uppercase",letterSpacing:"0.08em",fontWeight:700,marginBottom:4,display:"block",fontFamily:"var(--font)"},
  inp:{background:"#ffffff",border:"1px solid rgba(0,0,0,0.15)",borderRadius:8,padding:"10px 14px",color:"var(--text)",fontSize:14,fontFamily:"var(--font)",width:"100%",boxSizing:"border-box",outline:"none"},
  bp:{background:"linear-gradient(135deg,var(--accent),var(--accent2))",color:"#fff",border:"none",borderRadius:12,padding:"14px 28px",fontSize:14,fontWeight:800,fontFamily:"var(--font)",cursor:"pointer",width:"100%",boxShadow:"0 4px 20px rgba(180,70,0,0.25)"},
  bs:{background:"rgba(0,0,0,0.05)",color:"var(--muted)",border:"1px solid var(--border)",borderRadius:12,padding:"14px 20px",fontSize:14,fontWeight:600,fontFamily:"var(--font)",cursor:"pointer"},
  ba:{background:"rgba(180,70,0,0.08)",color:"var(--accent)",border:"1px solid rgba(180,70,0,0.25)",borderRadius:12,padding:"14px 20px",fontSize:14,fontWeight:700,fontFamily:"var(--font)",cursor:"pointer"},
  td:{padding:"8px 4px",whiteSpace:"nowrap",color:"var(--text)",fontSize:11,borderBottom:"1px solid var(--border)"},
  rl:{fontSize:10,color:"var(--muted)",textTransform:"uppercase",letterSpacing:"0.06em",fontWeight:600},
  rv:{fontSize:15,fontWeight:800,color:"var(--text)",fontFamily:"var(--mono)"},
};

const CSS = `
:root{--bg:#f5f6f8;--card:#ffffff;--border:rgba(0,0,0,0.10);--highlight:rgba(180,70,0,0.07);--accent:#b84600;--accent2:#cc2200;--text:#111827;--muted:#4b5563;--dim:#9ca3af;--picker-bg:rgba(245,246,248,0.97);--font:'Outfit',sans-serif;--display:'Outfit',sans-serif;--mono:'JetBrains Mono',monospace}
::-webkit-scrollbar{width:0;height:0}*{scrollbar-width:none;box-sizing:border-box}
input::-webkit-outer-spin-button,input::-webkit-inner-spin-button{-webkit-appearance:none}
input[type=number]{-moz-appearance:textfield}body{margin:0;background:#f5f6f8}`;


// ======== pin-login.js ========
function PinEntry({prompt, onSuccess, pinSource, subtitle}) {
  const [entered, setEntered] = React.useState("");
  const [error, setError] = React.useState(false);

  const tap = (d) => {
    if (entered.length >= 4) return;
    const next = entered + d;
    setEntered(next);
    setError(false);
    if (next.length === 4) {
      setTimeout(async () => {
        const correct = typeof pinSource === "function" ? await pinSource(next) : pinSource;
        if (correct === "__PASSTHROUGH__") {
          // Validation happens in onSuccess — it returns false to signal wrong PIN
          const ok = await onSuccess(next);
          if (ok === false) { setError(true); setEntered(""); }
        } else if (next === correct) { onSuccess(next); }
        else { setError(true); setEntered(""); }
      }, 120);
    }
  };
  const del = () => setEntered(p => p.slice(0,-1));
  const dots = [0,1,2,3].map(i => (
    <div key={i} style={{width:16,height:16,borderRadius:"50%",background:i<entered.length?"var(--accent)":"transparent",border:"2px solid "+(i<entered.length?"var(--accent)":"var(--dim)"),transition:"background 0.15s"}} />
  ));
  const PAD = ["1","2","3","4","5","6","7","8","9","","0","⌫"];
  return (
    <div style={{minHeight:"100vh",background:"var(--bg)",display:"flex",flexDirection:"column",alignItems:"center",justifyContent:"center",padding:24}}>
      <style>{CSS}</style>
      <link href="https://fonts.googleapis.com/css2?family=Outfit:wght@400;500;600;700;800;900&family=JetBrains+Mono:wght@400;700&display=swap" rel="stylesheet" />
      {typeof LOGO_DATA_URL!=="undefined"&&<img src={LOGO_DATA_URL} alt="IPS" style={{width:72,height:72,marginBottom:16}} />}
      <div style={{fontSize:22,fontWeight:900,fontFamily:"var(--display)",marginBottom:4}}>IPS-PROJECT</div>
      <div style={{fontSize:12,color:"var(--muted)",marginBottom:4}}>{prompt||"Enter PIN to continue"}</div>
      {subtitle&&<div style={{fontSize:11,color:"var(--accent)",marginBottom:24,fontWeight:700}}>{subtitle}</div>}
      {!subtitle&&<div style={{marginBottom:24}}/>}
      <div style={{display:"flex",gap:16,marginBottom:32}}>{dots}</div>
      {error&&<div style={{fontSize:13,color:"#ff4444",fontWeight:700,marginBottom:16}}>Incorrect PIN</div>}
      <div style={{display:"grid",gridTemplateColumns:"repeat(3,72px)",gap:12}}>
        {PAD.map((k,i) => k===""
          ? <div key={i} />
          : <button key={i} onClick={()=>k==="⌫"?del():tap(k)}
              style={{width:72,height:72,borderRadius:36,background:k==="⌫"?"transparent":"rgba(0,0,0,0.06)",border:"1px solid var(--border)",color:"var(--text)",fontSize:k==="⌫"?22:24,fontWeight:700,cursor:"pointer",fontFamily:"var(--mono)",display:"flex",alignItems:"center",justifyContent:"center"}}>
              {k}
            </button>
        )}
      </div>
    </div>
  );
}

// First-time name entry screen
function NameEntry({onDone}) {
  const [name, setName] = React.useState("");
  return (
    <div style={{minHeight:"100vh",background:"var(--bg)",display:"flex",flexDirection:"column",alignItems:"center",justifyContent:"center",padding:24}}>
      <style>{CSS}</style>
      <link href="https://fonts.googleapis.com/css2?family=Outfit:wght@400;500;600;700;800;900&family=JetBrains+Mono:wght@400;700&display=swap" rel="stylesheet" />
      {typeof LOGO_DATA_URL!=="undefined"&&<img src={LOGO_DATA_URL} alt="IPS" style={{width:72,height:72,marginBottom:16}} />}
      <div style={{fontSize:22,fontWeight:900,fontFamily:"var(--display)",marginBottom:4}}>IPS-PROJECT</div>
      <div style={{fontSize:12,color:"var(--muted)",marginBottom:32}}>Internal Pipeline Services</div>
      <div style={{width:"100%",maxWidth:300}}>
        <div style={{fontSize:13,color:"var(--muted)",fontWeight:700,textTransform:"uppercase",letterSpacing:"0.08em",marginBottom:8}}>Your Name</div>
        <input
          autoFocus
          value={name}
          onChange={e=>setName(e.target.value)}
          onKeyDown={e=>e.key==="Enter"&&name.trim()&&onDone(name.trim())}
          placeholder="Enter your name..."
          style={{background:"#ffffff",border:"1px solid rgba(0,0,0,0.15)",borderRadius:8,padding:"12px 14px",color:"var(--text)",fontSize:16,fontFamily:"var(--font)",width:"100%",boxSizing:"border-box",outline:"none",marginBottom:14}}
        />
        <button
          onClick={()=>name.trim()&&onDone(name.trim())}
          disabled={!name.trim()}
          style={{background:"linear-gradient(135deg,var(--accent),var(--accent2))",color:"#fff",border:"none",borderRadius:12,padding:"14px 28px",fontSize:14,fontWeight:800,fontFamily:"var(--font)",cursor:"pointer",width:"100%",opacity:name.trim()?1:0.4}}>
          Continue →
        </button>
      </div>
    </div>
  );
}

// ======== SECTION SELECT PAGE ========
function SectionSelectPage({project, onSelectSection, onBack}) {
  const numSections = project.numSections || 1;
  const sections = Array.from({length: numSections}, (_, i) => i + 1);
  const [loading, setLoading] = React.useState(false);

  const handleSelect = async (n) => {
    setLoading(true);
    await onSelectSection(n);
    // loading will clear when component unmounts (stage changes)
  };

  return (
    <div style={{minHeight:"100vh",background:"var(--bg)",display:"flex",flexDirection:"column",alignItems:"center",justifyContent:"center",padding:24}}>
      <style>{CSS}</style>
      <link href="https://fonts.googleapis.com/css2?family=Outfit:wght@400;500;600;700;800;900&family=JetBrains+Mono:wght@400;700&display=swap" rel="stylesheet" />
      {typeof LOGO_DATA_URL!=="undefined"&&<img src={LOGO_DATA_URL} alt="IPS" style={{width:64,height:64,marginBottom:16}} />}
      <div style={{fontSize:22,fontWeight:900,fontFamily:"var(--display)",marginBottom:4}}>IPS-PROJECT</div>
      <div style={{fontSize:13,color:"var(--accent)",fontWeight:800,marginBottom:2}}>{project.projectNumber}</div>
      <div style={{fontSize:12,color:"var(--muted)",marginBottom:32}}>{project.client||""}{project.location?" · "+project.location:""}</div>

      {loading ? (
        <div style={{color:"var(--muted)",fontSize:13,fontFamily:"var(--font)"}}>Loading section…</div>
      ) : (
        <div style={{width:"100%",maxWidth:320}}>
          <div style={{fontSize:12,color:"var(--muted)",fontWeight:700,textTransform:"uppercase",letterSpacing:"0.1em",textAlign:"center",marginBottom:16}}>Select Your Section</div>
          <div style={{display:"flex",flexDirection:"column",gap:10}}>
            {sections.map(n => (
              <button key={n} onClick={() => handleSelect(n)}
                style={{background:"rgba(255,165,0,0.08)",border:"1px solid rgba(255,165,0,0.3)",borderRadius:14,padding:"18px 24px",cursor:"pointer",display:"flex",alignItems:"center",justifyContent:"space-between",fontFamily:"var(--font)"}}>
                <div>
                  <div style={{fontSize:18,fontWeight:900,color:"var(--accent)"}}>Section {n}</div>
                </div>
                <span style={{fontSize:20,color:"var(--accent)"}}>→</span>
              </button>
            ))}
          </div>
          <button onClick={onBack} style={{...S.bs,width:"100%",marginTop:20,padding:"12px"}}>← Wrong Project?</button>
        </div>
      )}
    </div>
  );
}

// ======== CREW MANAGEMENT PAGE ========
function CrewManagementPage({onBack}) {
  const ALL_TABS = ["runs","runsheet","results","notes","report","final","archive","coating","jsa","deliveries","comps","inspect","checklist","photos","manhours","setup"];
  const TAB_LABELS = {runs:"Runs",runsheet:"Sheet",results:"Results",notes:"Notes",report:"Daily",final:"Final",archive:"Archive",coating:"Coat",jsa:"JSA",deliveries:"Deliveries",comps:"Comps",inspect:"DFT",checklist:"Check",photos:"Photos",manhours:"Hours",setup:"Setup"};
  const [users, setUsers] = React.useState([]);
  const [pinModal, setPinModal] = React.useState(false);
  const [newPin, setNewPin] = React.useState("");
  const [saving, setSaving] = React.useState(false);
  const [msg, setMsg] = React.useState("");

  React.useEffect(() => { loadUsers(); }, []);

  const loadUsers = async () => {
    const u = await Storage.getUsers();
    setUsers(u.sort((a,b) => (a.joinedAt||0)-(b.joinedAt||0)));
  };

  const toggleTab = async (userDeviceId, tab) => {
    const user = users.find(u => u.deviceId === userDeviceId);
    if (!user) return;
    const perms = { ...(user.tabPermissions||{}) };
    perms[tab] = perms[tab] === false ? true : false;
    await Storage.updateUserPermissions(userDeviceId, perms);
    setUsers(prev => prev.map(u => u.deviceId===userDeviceId ? {...u, tabPermissions: perms} : u));
  };

  const deleteUser = async (deviceId) => {
    if (!window.confirm("Remove this crew member?")) return;
    await Storage.deleteUser(deviceId);
    setUsers(prev => prev.filter(u => u.deviceId !== deviceId));
  };

  const savePin = async () => {
    if (newPin.length !== 4) return;
    setSaving(true);
    await Storage.setManagerPin(newPin);
    setPinModal(false); setNewPin(""); setSaving(false);
    setMsg("Manager PIN updated"); setTimeout(()=>setMsg(""),2500);
  };

  return (
    <div style={{padding:"12px 16px",maxWidth:CONTAINER_MAX,margin:"0 auto",paddingBottom:80,background:"var(--bg)",minHeight:"100vh"}}>
      <style>{CSS}</style>
      <link href="https://fonts.googleapis.com/css2?family=Outfit:wght@400;500;600;700;800;900&family=JetBrains+Mono:wght@400;700&display=swap" rel="stylesheet" />
      <div style={{display:"flex",alignItems:"center",gap:12,marginBottom:20}}>
        <button onClick={onBack} style={{...S.bs,padding:"8px 14px",fontSize:12,width:"auto"}}>← Back</button>
        <div style={{fontSize:16,fontWeight:900,fontFamily:"var(--display)"}}>CREW MANAGEMENT</div>
      </div>

      {msg&&<div style={{background:"rgba(0,230,118,0.1)",border:"1px solid rgba(0,230,118,0.3)",borderRadius:10,padding:"10px 14px",marginBottom:12,color:"#00e676",fontSize:13,fontWeight:700}}>{msg}</div>}

      {/* Manager PIN */}
      <div style={{...S.card,marginBottom:16}}>
        <div style={{...S.ct}}>Manager PIN</div>
        <div style={{fontSize:11,color:"var(--muted)",marginBottom:10}}>
          This PIN gives full app access on any device. Crew log in with their project number instead.
        </div>
        <button onClick={()=>{setPinModal(true);setNewPin("");}} style={{...S.ba,width:"100%",padding:"10px 12px",fontSize:12}}>
          🔑 Change Manager PIN
        </button>
      </div>

      {/* Crew list */}
      <div style={{fontSize:11,color:"var(--muted)",fontWeight:700,textTransform:"uppercase",marginBottom:10}}>Crew Members ({users.length})</div>
      {users.length===0&&<div style={{textAlign:"center",color:"var(--dim)",padding:24}}>No crew members have logged in yet</div>}
      {users.map(u => {
        const perms = u.tabPermissions || {};
        return (
          <div key={u.deviceId} style={{...S.card,marginBottom:10}}>
            <div style={{display:"flex",justifyContent:"space-between",alignItems:"center",marginBottom:10}}>
              <div>
                <div style={{fontWeight:800,fontSize:14,color:"var(--text)"}}>{u.name}</div>
                <div style={{fontSize:10,color:"var(--muted)"}}>Joined {new Date(u.joinedAt||0).toLocaleDateString()}</div>
              </div>
              <div style={{display:"flex",alignItems:"center",gap:8}}>
                <div style={{fontSize:10,color:"var(--muted)",fontWeight:700,textTransform:"uppercase"}}>Tab Access</div>
                <button onClick={()=>deleteUser(u.deviceId)} style={{background:"none",border:"1px solid rgba(255,68,68,0.3)",borderRadius:6,padding:"3px 8px",color:"#ff4444",fontSize:10,fontWeight:700,cursor:"pointer",fontFamily:"var(--font)"}}>✕ Remove</button>
              </div>
            </div>
            <div style={{display:"grid",gridTemplateColumns:"repeat(4,1fr)",gap:6}}>
              {ALL_TABS.map(tab => {
                const allowed = perms[tab] !== false;
                return (
                  <button key={tab} onClick={()=>toggleTab(u.deviceId,tab)}
                    style={{padding:"6px 4px",borderRadius:8,border:`1px solid ${allowed?"rgba(0,230,118,0.4)":"rgba(255,68,68,0.3)"}`,background:allowed?"rgba(0,230,118,0.08)":"rgba(255,68,68,0.08)",color:allowed?"#00e676":"#ff4444",fontSize:9,fontWeight:800,cursor:"pointer",fontFamily:"var(--font)",textTransform:"uppercase"}}>
                    {TAB_LABELS[tab]}
                  </button>
                );
              })}
            </div>
          </div>
        );
      })}

      {/* Manager PIN modal */}
      {pinModal&&<div style={{position:"fixed",inset:0,background:"rgba(0,0,0,0.7)",zIndex:400,display:"flex",alignItems:"center",justifyContent:"center",padding:24}}>
        <div style={{background:"var(--card)",borderRadius:16,padding:24,width:"100%",maxWidth:320,border:"1px solid var(--border)"}}>
          <div style={{fontSize:15,fontWeight:800,marginBottom:8}}>Change Manager PIN</div>
          <div style={{fontSize:12,color:"var(--muted)",marginBottom:14}}>Full access on any device. Keep this private.</div>
          <input type="password" inputMode="numeric" maxLength={4} value={newPin}
            onChange={e=>setNewPin(e.target.value.replace(/\D/g,"").slice(0,4))}
            placeholder="4-digit PIN"
            style={{...S.inp,marginBottom:12,fontSize:22,letterSpacing:"0.4em",textAlign:"center"}} />
          <button onClick={savePin} disabled={newPin.length!==4||saving}
            style={{...S.bp,marginBottom:8,opacity:newPin.length===4?1:0.4}}>
            {saving?"Saving…":"Save PIN"}
          </button>
          <button onClick={()=>{setPinModal(false);setNewPin("")}} style={{...S.bs,width:"100%"}}>Cancel</button>
        </div>
      </div>}
    </div>
  );
}

// ═══ SCROLL PICKER ═══
function ScrollPicker({options,value,onChange,label,width=120,height=150,fontSize=15}) {
  const ref=useRef(null),IH=40,pad=Math.floor(height/IH/2);
  const idx=options.findIndex(o=>String(o)===String(value));
  const dm=useRef(false),st=useRef(null),lv=useRef(value);
  useEffect(()=>{if(ref.current&&idx>=0&&!dm.current){ref.current.scrollTop=idx*IH;dm.current=true}},[]);
  useEffect(()=>{if(ref.current&&dm.current&&String(value)!==String(lv.current)){const n=options.findIndex(o=>String(o)===String(value));if(n>=0)ref.current.scrollTo({top:n*IH,behavior:"smooth"});lv.current=value}},[value]);
  const hs=()=>{if(!ref.current)return;clearTimeout(st.current);st.current=setTimeout(()=>{if(!ref.current)return;const i=Math.round(ref.current.scrollTop/IH),c=Math.max(0,Math.min(i,options.length-1));ref.current.scrollTo({top:c*IH,behavior:"smooth"});if(String(options[c])!==String(value)){lv.current=options[c];onChange(options[c])}},80)};
  return (
    <div style={{display:"flex",flexDirection:"column",alignItems:"center",width}}>
      {label&&<div style={{fontSize:9,color:"var(--muted)",textTransform:"uppercase",letterSpacing:"0.08em",fontWeight:700,marginBottom:6,fontFamily:"var(--font)"}}>{label}</div>}
      <div style={{position:"relative",width:"100%",height}}>
        <div style={{position:"absolute",top:"50%",left:0,right:0,height:IH,marginTop:-IH/2,background:"var(--highlight)",borderTop:"1px solid var(--accent)",borderBottom:"1px solid var(--accent)",pointerEvents:"none",zIndex:2,borderRadius:4}} />
        <div ref={ref} onScroll={hs} style={{height:"100%",overflowY:"scroll",scrollSnapType:"y mandatory",WebkitOverflowScrolling:"touch",position:"relative"}}>
          {Array(pad).fill(null).map((_,i)=><div key={"p"+i} style={{height:IH}} />)}
          {options.map((o,i)=>(
            <div key={i} onClick={()=>{if(ref.current)ref.current.scrollTo({top:i*IH,behavior:"smooth"});onChange(o)}} style={{height:IH,display:"flex",alignItems:"center",justifyContent:"center",scrollSnapAlign:"center",fontSize,fontWeight:String(o)===String(value)?800:400,color:String(o)===String(value)?"var(--text)":"var(--dim)",fontFamily:"var(--mono)",cursor:"pointer",transition:"all 0.1s"}}>
              {o}
            </div>
          ))}
          {Array(pad).fill(null).map((_,i)=><div key={"pp"+i} style={{height:IH}} />)}
        </div>
      </div>
    </div>
  );
}

function WeightInput({value, onChange, label}) {
  return (
    <div>
      {label&&<label style={S.lb}>{label}</label>}
      <input type="number" inputMode="decimal" value={value||""} onChange={e=>onChange(parseFloat(e.target.value)||0)} style={{...S.inp,fontSize:20,textAlign:"center",fontFamily:"var(--mono)",fontWeight:800}} placeholder="0" />
    </div>
  );
}

function QuickPick({options,value,onChange,label,width="100%"}) {
  return (
    <div style={{width}}>
      {label&&<label style={S.lb}>{label}</label>}
      <div style={{display:"flex",gap:6,flexWrap:"wrap"}}>
        {options.map(o=>(
          <button key={o} onClick={()=>onChange(o)} style={{padding:"7px 14px",borderRadius:8,border:`1px solid ${value===o?"var(--accent)":"var(--border)"}`,background:value===o?"rgba(255,165,0,0.15)":"transparent",color:value===o?"var(--accent)":"var(--muted)",fontSize:12,fontWeight:700,cursor:"pointer",fontFamily:"var(--font)"}}>
            {o}
          </button>
        ))}
      </div>
    </div>
  );
}

function Inp({label:lb,type,value:v,onChange:oc,placeholder:ph,inputMode:im,style:sx}) {
  return (
    <div style={sx}>
      {lb&&<label style={S.lb}>{lb}</label>}
      <input type={type||"text"} inputMode={im} value={v||""} onChange={e=>oc(e.target.value)} placeholder={ph||""} style={S.inp} />
    </div>
  );
}

function VolumePicker({value, onChange, label}) {
  return <ScrollPicker options={VOLUMES} value={value} onChange={onChange} label={label||"Volume (gal)"} width={130} />;
}

function HCLConcentrationPicker({value, onChange, label}) {
  return <ScrollPicker options={HCL_PERCENTS} value={value} onChange={onChange} label={label||"HCL Conc."} width={110} fontSize={13} />;
}

// ═══ SWIPEABLE ROW — Apple-Mail-style swipe to reveal, tap to confirm delete ═══
function SwipeRow({onDelete, children, style:sx}) {
  const [offset, setOffset] = useState(0);
  const [open, setOpen] = useState(false);
  const [swiping, setSwiping] = useState(false);
  const [confirmOpen, setConfirmOpen] = useState(false);
  const startX = useRef(null);
  const startY = useRef(null);
  const rowRef = useRef(null);
  const snapWidth = 88;
  const threshold = 50;

  // Close if user taps outside this row
  useEffect(() => {
    if (!open) return;
    const handler = (e) => {
      if (rowRef.current && !rowRef.current.contains(e.target)) {
        setOpen(false);
        setOffset(0);
      }
    };
    document.addEventListener("touchstart", handler, true);
    return () => document.removeEventListener("touchstart", handler, true);
  }, [open]);

  const onTouchStart = (e) => {
    startX.current = e.touches[0].clientX;
    startY.current = e.touches[0].clientY;
    setSwiping(false);
  };
  const onTouchMove = (e) => {
    if (startX.current === null) return;
    const dx = e.touches[0].clientX - startX.current;
    const dy = Math.abs(e.touches[0].clientY - startY.current);
    if (!swiping && dy > Math.abs(dx)) { startX.current = null; return; }
    if (dx < 0 || open) {
      setSwiping(true);
      e.preventDefault();
      const base = open ? -snapWidth : 0;
      setOffset(Math.min(0, Math.max(-snapWidth - 20, base + dx)));
    }
  };
  const onTouchEnd = () => {
    setSwiping(false);
    startX.current = null;
    if (open) {
      if (offset > -snapWidth / 2) { setOpen(false); setOffset(0); }
      else { setOffset(-snapWidth); }
    } else {
      if (offset < -threshold) { setOpen(true); setOffset(-snapWidth); }
      else { setOffset(0); }
    }
  };

  const handleDeleteTap = (e) => {
    e.stopPropagation();
    setConfirmOpen(true);
  };

  const handleConfirmDelete = (e) => {
    e.stopPropagation();
    setConfirmOpen(false);
    setOpen(false);
    setOffset(0);
    onDelete();
  };

  const handleCancelDelete = (e) => {
    e.stopPropagation();
    setConfirmOpen(false);
    setOpen(false);
    setOffset(0);
  };

  return (
    <div ref={rowRef} style={{position:"relative",overflow:"hidden",borderRadius:14,marginBottom:8}}>
      {confirmOpen && (
        <div style={{position:"fixed",inset:0,zIndex:800,display:"flex",alignItems:"center",justifyContent:"center",background:"rgba(0,0,0,0.6)"}} onClick={handleCancelDelete}>
          <div onClick={e=>e.stopPropagation()} style={{background:"#ffffff",border:"1px solid rgba(255,68,68,0.3)",borderRadius:18,padding:"28px 24px",maxWidth:300,width:"90%",textAlign:"center",boxShadow:"0 20px 60px rgba(0,0,0,0.08)"}}>
            <div style={{fontSize:32,marginBottom:12}}>🗑</div>
            <div style={{fontSize:16,fontWeight:900,color:"var(--text)",marginBottom:8}}>Delete Project?</div>
            <div style={{fontSize:13,color:"var(--muted)",marginBottom:24,lineHeight:1.5}}>This will permanently delete the project and all its data. This cannot be undone.</div>
            <div style={{display:"flex",gap:10}}>
              <button onClick={handleCancelDelete} style={{flex:1,background:"rgba(0,0,0,0.05)",border:"1px solid var(--border)",borderRadius:12,padding:"12px",color:"var(--text)",fontSize:14,fontWeight:700,cursor:"pointer",fontFamily:"var(--font)"}}>Cancel</button>
              <button onClick={handleConfirmDelete} style={{flex:1,background:"#cc1111",border:"1px solid rgba(255,68,68,0.5)",borderRadius:12,padding:"12px",color:"#fff",fontSize:14,fontWeight:800,cursor:"pointer",fontFamily:"var(--font)"}}>Delete</button>
            </div>
          </div>
        </div>
      )}
      {/* Red delete button revealed on swipe */}
      <div
        style={{position:"absolute",top:0,right:0,bottom:0,width:snapWidth,background:"#cc1111",display:"flex",flexDirection:"column",alignItems:"center",justifyContent:"center",gap:2,borderRadius:"0 14px 14px 0",cursor:"pointer",userSelect:"none"}}
        onTouchEnd={handleDeleteTap}
        onClick={handleDeleteTap}
      >
        <span style={{fontSize:16}}>🗑</span>
        <span style={{color:"#fff",fontSize:11,fontWeight:800,letterSpacing:0.5}}>DELETE</span>
      </div>
      <div
        onTouchStart={onTouchStart}
        onTouchMove={onTouchMove}
        onTouchEnd={onTouchEnd}
        style={{transform:`translateX(${offset}px)`,transition:swiping?"none":"transform 0.3s ease",position:"relative",zIndex:1,...sx}}
      >
        {children}
      </div>
    </div>
  );
}


// ═══ POPUP MENU ═══
function PopupMenu({title, options, onSelect, onClose, showManual, manualLabel, manualValue, onManualChange, onManualConfirm}) {
  return (
    <div style={{position:"fixed",inset:0,zIndex:600,display:"flex",alignItems:"flex-end",background:"rgba(0,0,0,0.5)"}} onClick={onClose}>
      <div onClick={e=>e.stopPropagation()} style={{width:"100%",maxWidth:460,margin:"0 auto",background:"rgba(245,246,248,0.99)",backdropFilter:"blur(20px)",borderRadius:"20px 20px 0 0",border:"1px solid var(--border)",padding:"20px 16px",paddingBottom:"calc(20px + env(safe-area-inset-bottom,0))"}}>
        <div style={{width:36,height:4,background:"var(--border)",borderRadius:2,margin:"0 auto 12px"}} />
        {title&&<div style={{fontSize:11,color:"var(--muted)",fontWeight:700,textTransform:"uppercase",letterSpacing:"0.1em",textAlign:"center",marginBottom:14}}>{title}</div>}
        <div style={{display:"flex",flexWrap:"wrap",gap:8,justifyContent:"center",marginBottom:showManual?12:0}}>
          {options.map(o=>(
            <button key={o} onClick={()=>onSelect(o)} style={{padding:"10px 18px",borderRadius:10,border:"1px solid var(--border)",background:"rgba(0,0,0,0.05)",color:"var(--text)",fontSize:14,fontWeight:700,cursor:"pointer",fontFamily:"var(--font)"}}>
              {o}
            </button>
          ))}
        </div>
        {showManual&&<div style={{marginTop:8}}>
          <div style={{fontSize:11,color:"var(--muted)",marginBottom:6,fontWeight:700,textTransform:"uppercase"}}>{manualLabel||"Manual Entry"}</div>
          <div style={{display:"flex",gap:8}}>
            <input value={manualValue||""} onChange={e=>onManualChange(e.target.value)} placeholder="Enter value..." style={{...S.inp,flex:1}} />
            <button onClick={onManualConfirm} style={{...S.bp,width:"auto",padding:"10px 18px",fontSize:14}}>OK</button>
          </div>
        </div>}
      </div>
    </div>
  );
}

