// ======== app.jsx ========
function IPSProjectWrapper() {
  const [stage, setStage] = React.useState("init"); // init | name | pin | section | blocked | app
  const [currentUser, setCurrentUser] = React.useState(null);
  const [tabPermissions, setTabPermissions] = React.useState({});
  const [showCrew, setShowCrew] = React.useState(false);
  const [lockedProjectId, setLockedProjectId] = React.useState(null);
  const [lockedSection, setLockedSection] = React.useState(null); // null = no section (1-section project or manager)
  const [pendingProject, setPendingProject] = React.useState(null); // project awaiting section selection
  const [blockedProjectName, setBlockedProjectName] = React.useState("");

  React.useEffect(() => {
    const setup = async () => {
      initFirebase();
      await new Promise(r => setTimeout(r, 300));
      const localUser = getLocalUser();
      if (localUser?.name && localUser?.deviceId) {
        setCurrentUser({...localUser, role: null});
        setStage("pin");
      } else {
        setStage("name");
      }
    };
    setup();
  }, []);

  const handleName = (name) => {
    const deviceId = getDeviceId();
    const u = { name, deviceId };
    setLocalUser(u);
    setCurrentUser(u);
    setStage("pin");
  };

  const normalizePN = (s) => String(s||"").trim().toUpperCase().replace(/\s+/g,"");

  const handlePin = async (enteredPin) => {
    const deviceId = getDeviceId();
    const name = currentUser?.name || "Unknown";

    // 1. Check manager PIN
    const pins = await Storage.getPins();
    const { managerPin } = pins;
    if (managerPin && enteredPin === managerPin) {
      await Storage.registerUser(deviceId, name);
      const fullUser = { name, deviceId, role: "manager" };
      setLocalUser(fullUser);
      setCurrentUser(fullUser);
      setTabPermissions({});
      setLockedProjectId(null);
      setStage("app");
      return true;
    }

    // 2. Check project number PIN
    const projects = await Storage.loadProjects();
    const normalized = normalizePN(enteredPin);
    const matched = projects.find(p => normalizePN(p.projectNumber) === normalized);

    if (matched) {
      if (matched.closed) {
        setBlockedProjectName(`${matched.projectNumber}${matched.client ? " — " + matched.client : ""}`);
        setStage("blocked");
        return true;
      }
      await Storage.registerUser(deviceId, name);
      const perms = await Storage.getUserPermissions(deviceId);
      const fullUser = { name, deviceId, role: "crew" };
      setLocalUser(fullUser);
      setCurrentUser(fullUser);
      setTabPermissions(perms);

      // Multi-section: show section picker before entering app
      const numSections = matched.numSections || 1;
      if (numSections > 1) {
        setLockedProjectId(matched.id);
        setPendingProject(matched);
        setStage("section");
        return true;
      }

      setLockedProjectId(matched.id);
      setLockedSection(null);
      setStage("app");
      return true;
    }

    return false; // wrong PIN
  };

  const handleCrewPageRequest = () => setShowCrew(true);

  const handleSectionSelect = async (sectionNum) => {
    if (!pendingProject) return;

    // Section 1 uses the parent project directly (no change for single-section or first section)
    if (sectionNum === 1) {
      setLockedSection(sectionNum);
      setPendingProject(null);
      setStage("app");
      return;
    }

    // For sections 2+, find or create a child project doc
    // Child docs are named "<parentProjectNumber>-S<n>" internally
    const allProjects = await Storage.loadProjects();
    const sectionPN = `${pendingProject.projectNumber}-S${sectionNum}`;
    let sectionDoc = allProjects.find(p => p.projectNumber === sectionPN && p._parentId === pendingProject.id);

    if (!sectionDoc) {
      // Create a new section project doc that inherits parent settings
      const newId = String(Date.now());
      sectionDoc = {
        id: newId,
        projectNumber: sectionPN,
        _parentId: pendingProject.id,
        _sectionNum: sectionNum,
        jobNumber: pendingProject.jobNumber,
        client: pendingProject.client,
        location: pendingProject.location,
        productType: pendingProject.productType,
        diameter: pendingProject.diameter,
        actualID: pendingProject.actualID,
        length: pendingProject.length,
        defaultTank: pendingProject.defaultTank,
        startDate: pendingProject.startDate,
        endDate: pendingProject.endDate,
        email: pendingProject.email,
        emails: pendingProject.emails || [],
        reviewEmails: pendingProject.reviewEmails || [],
        numSections: pendingProject.numSections,
        closed: false,
        runs: [],
        dailyNotes: [],
        coatingDays: [],
        jsas: [],
        deliveries: [],
        compData: null,
        inspections: [],
        checklist: [],
      };
      await Storage.saveProject(sectionDoc);
    }

    setLockedProjectId(sectionDoc.id);
    setLockedSection(sectionNum);
    setPendingProject(null);
    setStage("app");
  };

  const refreshPerms = async () => {
    if (!currentUser?.deviceId || currentUser.role === "manager") return;
    const perms = await Storage.getUserPermissions(currentUser.deviceId);
    setTabPermissions(perms);
    setShowCrew(false);
  };

  if (stage === "init") return (
    <div style={{minHeight:"100vh",background:"#f5f6f8",display:"flex",alignItems:"center",justifyContent:"center"}}>
      <style>{CSS}</style>
      <div style={{color:"var(--accent)",fontSize:14,fontFamily:"'Outfit',sans-serif",fontWeight:700}}>Loading…</div>
    </div>
  );

  if (stage === "name") return <NameEntry onDone={handleName} />;

  if (stage === "pin") return (
    <PinEntry
      prompt="Enter PIN to continue"
      subtitle={currentUser?.name ? `Welcome, ${currentUser.name}` : ""}
      pinSource={() => "__PASSTHROUGH__"}
      onSuccess={handlePin}
    />
  );

  if (stage === "blocked") return (
    <div style={{minHeight:"100vh",background:"#f5f6f8",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&display=swap" rel="stylesheet" />
      <div style={{fontSize:22,fontWeight:900,fontFamily:"'Outfit',sans-serif",marginBottom:8,color:"var(--text)"}}>IPS-PROJECT</div>
      <div style={{fontSize:40,marginBottom:16}}>🔒</div>
      <div style={{fontSize:16,fontWeight:800,color:"#cc1111",marginBottom:8}}>Project Closed</div>
      <div style={{fontSize:13,color:"var(--muted)",marginBottom:32,textAlign:"center",maxWidth:280}}>
        <span style={{color:"var(--text)",fontWeight:700}}>{blockedProjectName}</span> has been closed and is no longer accepting entries.
      </div>
      <button onClick={()=>setStage("pin")} style={{background:"rgba(0,0,0,0.06)",border:"1px solid rgba(0,0,0,0.15)",borderRadius:12,padding:"12px 28px",color:"var(--text)",fontSize:13,fontWeight:700,cursor:"pointer",fontFamily:"'Outfit',sans-serif"}}>
        ← Try Another PIN
      </button>
    </div>
  );

  if (stage === "section") return (
    <SectionSelectPage
      project={pendingProject}
      onSelectSection={handleSectionSelect}
      onBack={() => setStage("pin")}
    />
  );

  if (showCrew) return (
    <CrewManagementPage
      onBack={() => { setShowCrew(false); refreshPerms(); }}
    />
  );

  return (
    <IPSProjectApp
      currentUser={currentUser}
      tabPermissions={tabPermissions}
      lockedProjectId={lockedProjectId}
      lockedSection={lockedSection}
      onCrewPage={handleCrewPageRequest}
    />
  );
}

function IPSProjectApp({currentUser, tabPermissions, lockedProjectId, lockedSection, onCrewPage}) {
  const deviceId = currentUser?.deviceId;
  const isPrimary = currentUser?.role === "manager";
  const isCrew = currentUser?.role === "crew";

  const [page, setPage] = React.useState(lockedProjectId ? "runs" : "projects");
  const [projects, setProjects] = React.useState([]);
  const [apId, setApId] = React.useState(null);
  const [runs, setRuns] = React.useState([]);
  // activeRun is DERIVED below via useMemo — not state
  const [editingRun, setER] = React.useState(null);   // a past run being edited (no timer)
  const [paused, setPaused] = React.useState(false);
  const [elapsed, setElapsed] = React.useState(0);
  const [pausedTotal, setPT] = React.useState(0);
  const pauseRef = React.useRef(null);
  const [dailyNotes, setDN] = React.useState([]);
  const [coatingDays, setCoatingDays] = React.useState([]);
  const [jsas, setJSAs] = React.useState([]);
  const [deliveries, setDeliveries] = React.useState([]);
  const [compData, setCompData] = React.useState(null);
  const [inspections, setInspections] = React.useState([]);
  const [checklist, setChecklist] = React.useState(DEFAULT_CHECKLIST);
  const [photos, setPhotos] = React.useState([]);
  const [showPrompt, setSP] = React.useState(true);
  const [showMenu, setShowMenu] = React.useState(false);
  const [loading, setLoading] = React.useState(true);
  const tRef = React.useRef(null);
  const saveTimer = React.useRef(null); // kept for legacy reference
  const proj = projects.find(p => p.id === apId) || {};

  // ── SINGLE SOURCE OF TRUTH ──────────────────────────────────────────────────
  // `runs` is the only truth. `activeRun` is DERIVED: the last run with no
  // receiveTime and no shuttleComplete. Every device computes it the same way
  // from the same Firestore data, so all devices stay in sync automatically.
  // ────────────────────────────────────────────────────────────────────────────

  const apIdRef = React.useRef(apId);
  React.useEffect(() => { apIdRef.current = apId; }, [apId]);

  // Block Firestore-triggered saves (incoming updates must not echo back)
  const incomingUpdateRef = React.useRef(false);

  // ── LAZY LOADING ─────────────────────────────────────────────────────────────
  // 1. Project LIST listener: loads only lightweight summary fields for all
  //    projects. Heavy sub-data (runs, coatingDays, jsas, photos, etc.) is NOT
  //    included — keeping this snapshot fast even with 100+ projects.
  // 2. Active project listener: a separate single-doc onSnapshot fires only on
  //    the selected project, pulling full data into component state.
  //    It is torn down and replaced whenever apId changes.
  // No Firestore schema changes — existing data is untouched and unaffected.
  // ────────────────────────────────────────────────────────────────────────────

  // Load projects + set up lightweight project-list listener
  React.useEffect(() => {
    if (!getDb()) return;
    setLoading(true);

    const legacy = Storage.loadLegacy();
    if (legacy?.projects?.length > 0) {
      (async () => {
        for (const p of legacy.projects) await Storage.saveProject(p);
        Storage.clearLegacy();
      })();
    }

    // Lightweight collection listener — only summary metadata, no heavy arrays.
    // We use fieldMask via .select() when the SDK supports it; falling back to
    // the full doc if .select is unavailable (compat SDK exposes it via get()
    // but not onSnapshot, so we load full docs but strip heavy fields client-side
    // to avoid re-renders triggering the active-project effect unnecessarily).
    const unsub = getDb()
      .collection("companies").doc(COMPANY)
      .collection("projects")
      .onSnapshot(snap => {
        const summaries = snap.docs.map(d => {
          const data = d.data();
          // Strip heavy array fields from the project list snapshot so React
          // doesn't re-render with stale sub-data from a different project load.
          const { runs, dailyNotes, coatingDays, jsas, deliveries, compData,
                  inspections, checklist, photos, ...summary } = data;
          return { ...summary, id: d.id };
        });
        setProjects(summaries);
        setLoading(false);
      }, err => { console.error("Snapshot error:", err); setLoading(false); });

    if (lockedProjectId) {
      setApId(lockedProjectId);
      const lastTab = localStorage.getItem(`pipelog_lasttab_${lockedProjectId}`);
      if (lastTab) setPage(lastTab);
    } else {
      const savedId = Storage.getActiveProjectId();
      if (savedId) { setApId(savedId); setPage("runs"); }
    }

    return () => unsub();
  }, []);

  // Active-project listener: single-doc real-time subscription on the selected
  // project. Fires immediately with full data when apId changes (project open),
  // and stays live so all devices see run/coating/jsa updates in real time.
  // Tears down automatically when the user switches projects or leaves.
  const activeProjectUnsubRef = React.useRef(null);

  React.useEffect(() => {
    // Tear down any previous single-doc listener
    if (activeProjectUnsubRef.current) {
      activeProjectUnsubRef.current();
      activeProjectUnsubRef.current = null;
    }
    if (!apId || !getDb()) return;

    Storage.saveActiveProjectId(apId);

    const docRef = getDb()
      .collection("companies").doc(COMPANY)
      .collection("projects").doc(String(apId));

    const unsub = docRef.onSnapshot(snap => {
      if (!snap.exists) return;
      const p = { ...snap.data(), id: snap.id };

      // Merge full data back into the projects summary list so `proj` (derived
      // via projects.find) always has the complete record while active.
      setProjects(prev => {
        const idx = prev.findIndex(x => x.id === p.id);
        if (idx === -1) return [...prev, p];
        const next = [...prev];
        next[idx] = p;
        return next;
      });

      // Sync all sub-data into component state — Firestore is the truth.
      incomingUpdateRef.current = true;
      setRuns(p.runs || []);
      setDN(p.dailyNotes || []);
      setCoatingDays(p.coatingDays || []);
      setJSAs(p.jsas || []);
      setDeliveries(p.deliveries || []);
      setCompData(p.compData || null);
      setInspections(p.inspections || []);
      setChecklist(p.checklist || DEFAULT_CHECKLIST);
      setPhotos(p.photos || []);
      setTimeout(() => { incomingUpdateRef.current = false; }, 50);
    }, err => { console.error("Active project snapshot error:", err); });

    activeProjectUnsubRef.current = unsub;

    return () => {
      if (activeProjectUnsubRef.current) {
        activeProjectUnsubRef.current();
        activeProjectUnsubRef.current = null;
      }
    };
  }, [apId]);

  // Derive activeRun from runs — the last run that hasn't been received yet.
  // This runs on every device every time `runs` changes, so all devices
  // automatically show/hide the active run form in sync.
  const activeRun = React.useMemo(() => {
    return runs.find(r => !r.receiveTime && !r.shuttleComplete && !r._saved) || null;
  }, [runs]);

  // Whenever activeRun appears or its launchTime changes, sync showPrompt
  React.useEffect(() => {
    if (activeRun) setSP(false);
    else setSP(true);
  }, [activeRun?.id]);

  // Field-level saves to Firestore — debounced per field
  const saveTimers = React.useRef({});
  const scheduleFieldSave = React.useCallback((field, value) => {
    if (!apIdRef.current) return;
    if (incomingUpdateRef.current) return;
    clearTimeout(saveTimers.current[field]);
    const delay = field === "runs" ? 300 : 1200;
    saveTimers.current[field] = setTimeout(async () => {
      let saveValue = value;
      if (field === "photos") {
        saveValue = value.map(p => { const { dataUrl, uploadProgress, ...rest } = p; return rest; });
      } else if (field === "jsas") {
        // Strip inline signature dataUrls — only sigUrl (Storage URL) is persisted in Firestore
        saveValue = value.map(jsa => ({
          ...jsa,
          crewSignIn: (jsa.crewSignIn||[]).map(s => { const { sig, ...rest } = s; return rest; }),
          crewSignOut: (jsa.crewSignOut||[]).map(s => { const { sig, ...rest } = s; return rest; }),
        }));
      }
      await Storage.saveFields(apIdRef.current, { [field]: saveValue });
    }, delay);
  }, []);

  React.useEffect(() => { if (!apId) return; scheduleFieldSave("runs", runs); }, [runs]);
  React.useEffect(() => { if (!apId) return; scheduleFieldSave("dailyNotes", dailyNotes); }, [dailyNotes]);
  React.useEffect(() => { if (!apId) return; scheduleFieldSave("coatingDays", coatingDays); }, [coatingDays]);
  React.useEffect(() => { if (!apId) return; scheduleFieldSave("jsas", jsas); }, [jsas]);
  React.useEffect(() => { if (!apId) return; scheduleFieldSave("deliveries", deliveries); }, [deliveries]);
  React.useEffect(() => { if (!apId) return; scheduleFieldSave("compData", compData); }, [compData]);
  React.useEffect(() => { if (!apId) return; scheduleFieldSave("inspections", inspections); }, [inspections]);
  React.useEffect(() => { if (!apId) return; scheduleFieldSave("checklist", checklist); }, [checklist]);
  React.useEffect(() => { if (!apId) return; scheduleFieldSave("photos", photos); }, [photos]);

  // Timer — driven purely off activeRun.launchTime, works on every device
  React.useEffect(() => {
    const launchTime = activeRun?.launchTime;
    const isComplete = activeRun?.receiveTime || activeRun?.shuttleComplete;
    if (launchTime && !isComplete && !paused) {
      setElapsed(Date.now() - launchTime);
      tRef.current = setInterval(() => setElapsed(Date.now() - launchTime), 1000);
    } else {
      clearInterval(tRef.current);
    }
    return () => clearInterval(tRef.current);
  }, [activeRun?.launchTime, activeRun?.receiveTime, activeRun?.shuttleComplete, paused]);

  const createProj = () => {
    const id = Date.now();
    const np = {id: String(id), projectNumber:`P-${String(projects.length+1).padStart(3,"0")}`,jobNumber:"",length:"",diameter:"",actualID:"",client:"",email:"",emails:[],reviewEmails:[],location:"",productType:"",defaultTank:"Tank 1",startDate:"",endDate:"",closed:false,runs:[],dailyNotes:[],coatingDays:[],jsas:[],deliveries:[],compData:null,inspections:[]};
    Storage.saveProject(np);
    setApId(String(id)); setRuns([]); setDN([]); setCoatingDays([]); setJSAs([]); setDeliveries([]); setCompData(null); setInspections([]); setChecklist(DEFAULT_CHECKLIST); setPhotos([]);
    navTo("setup");
  };

  const updProj = (f, v) => {
    const current = projects.find(p => p.id === apId);
    if (!current) return;
    const updated = { ...current, [f]: v };
    Storage.saveProject(updated);
  };

  // Wrap setPage to persist last tab for crew
  const navTo = (tab) => {
    setPage(tab);
    if (isCrew && lockedProjectId) {
      localStorage.setItem(`pipelog_lasttab_${lockedProjectId}`, tab);
    }
  };

  const selProj = id => { setApId(id); navTo("runs"); setSP(true); };

  const delProj = id => {
    Storage.deleteProject(id);
    if (apId === id) { setApId(null); navTo("projects"); }
  };

  const closeProj = () => {
    const current = projects.find(p => p.id === apId);
    if (!current) return;
    const updated = { ...current, closed: true, endDate: current.endDate || new Date().toLocaleDateString("en-US") };
    Storage.saveProject(updated);
  };

  const blankRun = () => ({id:Date.now(),runNumber:runs.length+1,date:Date.now(),direction:DIRECTION_OPTIONS[0],frontPig:"CCFS",rearPig:"None",thirdPig:"None",chemType:"H2O",chemPercent:"100%",chemVolume:1000,chemManualType:"",launchTime:null,receiveTime:null,pausedDuration:0,estVolumeOut:1000,tank:proj.defaultTank||"Tank 1",totalSolids:"NA",solidColor:"NA",layeredTop:"0",layeredMid:"0",layeredBot:"0",percentAcid:"NA",notes:"",showThirdPig:false,layeredEnabled:false,shuttleMode:false,shuttlePasses:[],shuttleComplete:false});
  const copyLast = () => { const l=runs[runs.length-1]; const r={...blankRun(),frontPig:l.frontPig,rearPig:l.rearPig,thirdPig:l.thirdPig,showThirdPig:l.showThirdPig,chemType:l.chemType,chemPercent:l.chemPercent,chemVolume:l.chemVolume,chemManualType:l.chemManualType,tank:l.tank,estVolumeOut:l.chemVolume,direction:l.direction}; if(r.direction==="Receive \u2192 Launch")r.tank="Shuttle"; return r; };

  // Add a new in-progress run to Firestore — all devices see it immediately
  const startNew = copy => {
    const r = copy && runs.length > 0 ? copyLast() : blankRun();
    r.estVolumeOut = r.chemVolume;
    setRuns(prev => [...prev, r]);
    setER(null); setPaused(false); setElapsed(0); setPT(0); pauseRef.current = null;
  };

  // Update a field on the active run directly in runs (→ Firestore)
  const updateActiveRun = (fields) => {
    if (!activeRun) return;
    const id = activeRun.id;
    setRuns(prev => prev.map(r => r.id === id ? { ...r, ...fields } : r));
  };

  // Mark the active run complete (save button)
  const saveRun = () => {
    if (!activeRun) return;
    const r = { ...activeRun };
    if (r.launchTime && r.receiveTime && !r.shuttleMode)
      r.duration = r.receiveTime - r.launchTime - (r.pausedDuration || 0);
    // Mark as saved so it's no longer "active" — we use a _saved flag
    // Actually: giving it a receiveTime is enough. If it has no receiveTime yet
    // (user saves without receiving), we force it complete with a flag.
    if (!r.receiveTime && !r.shuttleComplete) r._saved = true;
    setRuns(prev => prev.map(run => run.id === r.id ? r : run));
    setPaused(false);
  };

  // Cancel / discard unsaved run — remove it from Firestore too
  const clearRun = () => {
    if (activeRun && !activeRun.launchTime) {
      setRuns(prev => prev.filter(r => r.id !== activeRun.id));
    }
    setPaused(false);
  };

  // Save an edit to a past run
  const savePastRun = () => {
    if (!editingRun) return;
    const r = { ...editingRun };
    if (r.launchTime && r.receiveTime && !r.shuttleMode)
      r.duration = r.receiveTime - r.launchTime - (r.pausedDuration || 0);
    // Update local state
    const updatedRuns = runs.map(x => x.id === r.id ? r : x);
    setRuns(updatedRuns);
    // Write directly to Firestore — bypasses incomingUpdateRef guard so the
    // corrected duration actually lands in the database and isn't overwritten.
    if (apIdRef.current) Storage.saveFields(apIdRef.current, { runs: updatedRuns });
    setER(null);
  };

  const duplicateRun = (idx) => {
    const src = runs[idx];
    const duped = {...src, id:Date.now(), runNumber:runs.length+1, launchTime:null, receiveTime:null, pausedDuration:0, duration:undefined, shuttlePasses:[], shuttleComplete:false, _saved:false};
    setRuns(prev => [...prev, duped]);
  };

  const deleteRun = (idx) => { setRuns(prev => prev.filter((_,i) => i !== idx).map((r,i) => ({...r, runNumber: i+1}))); };

  const todayStr = new Date().toLocaleDateString("en-US");
  const todayNote = dailyNotes.find(n => n.date === todayStr);
  const setTodayNote = text => setDN(prev => { const i=prev.findIndex(n=>n.date===todayStr); if(i>=0){const c=[...prev];c[i]={...c[i],text};return c} return [...prev,{date:todayStr,text}]; });
  const editRun = idx => { setER({...runs[idx]}); navTo("runs"); };
  const clearEditingRun = () => { setER(null); };

  const NavBar = () => (
    <div style={{position:"fixed",bottom:0,left:0,right:0,background:"rgba(245,246,248,0.97)",backdropFilter:"blur(10px)",borderTop:"1px solid var(--border)",zIndex:200,paddingBottom:"env(safe-area-inset-bottom,0)"}}>
      {lockedSection && (
        <div style={{background:"rgba(255,165,0,0.1)",borderBottom:"1px solid rgba(255,165,0,0.2)",padding:"3px 0",textAlign:"center"}}>
          <span style={{fontSize:10,fontWeight:900,color:"var(--accent)",textTransform:"uppercase",letterSpacing:"0.14em",fontFamily:"var(--font)"}}>📍 Section {lockedSection}</span>
        </div>
      )}
      <button onClick={() => setShowMenu(true)} style={{width:"100%",background:"none",border:"none",padding:"14px 0 12px",cursor:"pointer",display:"flex",flexDirection:"column",alignItems:"center",gap:3,color:"var(--accent)",fontFamily:"var(--font)"}}>
        <span style={{fontSize:20}}>☰</span>
        <span style={{fontSize:9,fontWeight:800,textTransform:"uppercase",letterSpacing:"0.12em"}}>Menu</span>
      </button>
    </div>
  );

  if (loading) return (
    <div style={{minHeight:"100vh",background:"#f5f6f8",display:"flex",alignItems:"center",justifyContent:"center",flexDirection:"column",gap:12}}>
      <style>{CSS}</style>
      <div style={{color:"var(--accent)",fontSize:16,fontFamily:"'Outfit',sans-serif",fontWeight:900}}>IPS-PROJECT</div>
      <div style={{color:"var(--muted)",fontSize:13,fontFamily:"'Outfit',sans-serif"}}>Syncing…</div>
    </div>
  );

  return (
    <div>
      <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" />

      {showMenu && <MenuOverlay page={page} setPage={navTo} onClose={()=>setShowMenu(false)} clearRun={clearRun} isPrimary={isPrimary} tabPermissions={tabPermissions} onCrewPage={()=>{setShowMenu(false);onCrewPage();}} />}

      {!isCrew && page==="projects" && <ProjectsPage projects={projects} onSelect={selProj} onCreate={createProj} onDelete={delProj} />}
      {page==="setup" && !isCrew && <SetupPage proj={proj} onUpdate={updProj} onBack={()=>navTo("projects")} onContinue={()=>{navTo("runs");setSP(true)}} onClose={closeProj} NavBar={NavBar} />}
      {page==="runs" && <RunsPage proj={proj} runs={runs} activeRun={activeRun} updateActiveRun={updateActiveRun} editingRun={editingRun} setER={setER} showPrompt={showPrompt} paused={paused} setPaused={setPaused} elapsed={elapsed} setElapsed={setElapsed} pausedTotal={pausedTotal} setPT={setPT} pauseRef={pauseRef} onSaveRun={saveRun} onSavePastRun={savePastRun} onStartNew={startNew} onDeleteRun={deleteRun} onDuplicateRun={duplicateRun} onClearEditingRun={clearEditingRun} onClearRun={clearRun} setRuns={setRuns} NavBar={NavBar} />}
      {page==="runsheet" && <RunSheetPage runs={runs} proj={proj} coatingDays={coatingDays} onEditRun={editRun} NavBar={NavBar} />}
      {page==="results" && <ResultsPage runs={runs} proj={proj} NavBar={NavBar} />}
      {page==="notes" && <NotesPage dailyNotes={dailyNotes} todayStr={todayStr} todayNote={todayNote} setTodayNote={setTodayNote} NavBar={NavBar} />}
      {page==="report" && <DailyReportPage proj={proj} runs={runs} dailyNotes={dailyNotes} coatingDays={coatingDays} jsas={jsas} inspections={inspections} photos={photos} NavBar={NavBar} />}
      {page==="final" && <FinalReportPage proj={proj} runs={runs} dailyNotes={dailyNotes} coatingDays={coatingDays} inspections={inspections} photos={photos} NavBar={NavBar} />}
      {page==="archive" && !isCrew && <ArchivePage proj={proj} runs={runs} dailyNotes={dailyNotes} coatingDays={coatingDays} jsas={jsas} deliveries={deliveries} compData={compData} inspections={inspections} checklist={checklist} photos={photos} NavBar={NavBar} />}
      {page==="coating" && <CoatingPage proj={proj} coatingDays={coatingDays} setCoatingDays={setCoatingDays} NavBar={NavBar} />}
      {page==="jsa" && <JSAPage jsas={jsas} setJSAs={setJSAs} proj={proj} NavBar={NavBar} />}
      {page==="deliveries" && <DeliveriesPage deliveries={deliveries} setDeliveries={setDeliveries} NavBar={NavBar} />}
      {page==="comps" && <CompsPage compData={compData} setCompData={setCompData} NavBar={NavBar} />}
      {page==="inspect" && <FinalInspectionPage inspections={inspections} setInspections={setInspections} NavBar={NavBar} />}
      {page==="checklist" && <ChecklistPage checklist={checklist} setChecklist={setChecklist} NavBar={NavBar} />}
      {page==="photos" && <PhotosPage photos={photos} setPhotos={setPhotos} proj={proj} NavBar={NavBar} />}
      {page==="manhours" && <ManHoursPage jsas={jsas} setJSAs={setJSAs} NavBar={NavBar} />}
      {page !== "projects" && <NavBar />}
    </div>
  );
}

const root=ReactDOM.createRoot(document.getElementById('root'));
root.render(<IPSProjectWrapper />);
