// Hawthorne NPD Workflow — React app
// Compiled at runtime by Babel standalone. No build step required.

const { useState, useEffect, useCallback } = React;

// ── Brand palette (per Hawthorne Brand Guide §4) ────────────────────────────
const C = {
  black:"#000000", inkSoft:"#1C1A17",
  ivory:"#F8F2E9", ivoryD:"#ECE3D2", ivoryDD:"#DDD0BA",
  brick:"#803A2B", brickL:"#9A4D3C", brickD:"#5E2A1E",
  moss:"#757C4C", herb:"#666B36", sand:"#CDC4AB", mist:"#A89F6D",
  rust:"#A35C2F", copper:"#90482D",
  white:"#FFFFFF", muted:"#8A8275", mutedL:"#B8AE9C",
};

// ── Official Hawthorne brand mark (icon) — from supplied SVG ────────────────
const BRAND_MARK_PATH = "M454.43,572.38h-92.33l-36.23-185.3c-3.93-20.13-21.53-34.65-41.99-34.65H68.46l-4.88,33.94,59.34,29.53-30.59,156.48H0l33.59-171.78c12.26-62.7,13.83-127.04,4.66-190.26L7.76,0h91.55l32.61,224.83c3.05,21.09,21.09,36.74,42.35,36.74h145.99c42.65,0,79.33,30.27,87.53,72.24l46.65,238.57ZM548.6,265.89c-9.17-63.23-7.59-127.56,4.67-190.27L568.05,0h-92.34l-13.53,69.24,61.4,26.59-5.29,29.77h-215.32c-20.45,0-38.05-16.33-41.99-36.46L243.55,0h-92.33l27.85,142.41c8.2,41.97,44.88,72.24,87.53,72.24h145.99c21.25,0,39.28,15.64,42.34,36.73l48.79,320.99h91.55l-46.68-306.49Z";

// ── Official Hawthorne master logo (wordmark) — from supplied SVG ───────────
const WORDMARK_PATH = "M83.7,142.6h15.6V21.7h-15.6v52.2H15.5V21.7H0v120.9h15.5v-42.4l-12.2-7.1v-4.4h80.3v53.9h0ZM182.8,99.1c0,9.9-2.6,17.7-7.7,23.5-5.1,5.8-11.8,8.6-20.1,8.6s-15.7-2.9-20.9-8.6-7.8-13.6-7.8-23.5,2.6-17.9,7.8-23.6c5.2-5.7,12.1-8.6,20.9-8.6s15,2.9,20.1,8.6,7.7,13.6,7.7,23.5M183.5,142.6h13.7V55.5h-13.7v14.5h-.9c-3-4.9-7.3-8.9-12.8-11.8-5.5-2.9-11.5-4.4-18-4.4s-14.5,1.9-20.6,5.7c-6.2,3.8-11,9.1-14.6,16s-5.4,14.7-5.4,23.6,1.8,16.7,5.4,23.6c3.6,6.9,8.4,12.2,14.6,16,6.2,3.8,13,5.7,20.6,5.7s12.4-1.5,18-4.4c5.5-2.9,9.8-6.9,12.8-11.8h.9v14.5h0ZM317.9,142.6l21.4-87.2h-14.3l-17.1,77.1h-4l-14.8-77.1h-29.8l-14.9,77.1h-4.1l-17.1-77.1h-14.8l21.6,87.2h27.1l16.6-86h.3l16.6,86h27.3ZM377.1,142.6h31.2v-13.1h-28.3v-60.8h23v-13.1h-34.2v-4.4l11.2-6.5v-23h-14.3v33.9h-15.3v13.1h15.3v62.5c0,6.3,5.1,11.5,11.5,11.5M484.2,142.6h14.3v-52c0-11.7-3-20.8-8.9-27.2-5.9-6.4-14.1-9.6-24.6-9.6s-12.6,1.4-17.7,4.2c-5.1,2.8-9,6.5-11.7,11h-.9V21.7h-14.3v120.9h14.3v-47.7c0-8.3,2.5-15,7.6-20.2,5.1-5.2,11.5-7.8,19.3-7.8s13,2.3,16.8,6.8c3.8,4.6,5.7,11,5.7,19.3v49.6ZM584.5,99.1c0,9.7-2.7,17.5-8,23.3-5.4,5.9-12.5,8.8-21.5,8.8s-16-2.9-21.3-8.8c-5.4-5.9-8-13.7-8-23.3s2.7-17.5,8-23.3c5.4-5.9,12.5-8.8,21.3-8.8s16.2,2.9,21.5,8.8,8,13.6,8,23.3M593.7,122.4c3.8-6.9,5.7-14.7,5.7-23.3s-1.9-16.4-5.7-23.3c-3.8-6.9-9.1-12.3-15.8-16.2-6.7-3.9-14.4-5.8-22.9-5.8s-16,2-22.7,5.9c-6.7,3.9-12,9.3-15.9,16.2-3.9,6.9-5.8,14.6-5.8,23.2s1.9,16.4,5.8,23.2c3.9,6.9,9.2,12.2,15.9,16.2,6.7,3.9,14.3,5.9,22.7,5.9s16.2-1.9,22.9-5.8c6.7-3.9,12-9.2,15.8-16.2M651.5,68.3h12.1v-12.8h-23.3l-11.1,17h-3.5v-17h-14.3v87.1h14.3v-46.8c0-8.2,2.4-14.8,7.1-19.9s10.9-7.6,18.7-7.6M735.1,142.6h14.4v-48.8c0-22-17.9-40-40-40s-40,17.9-40,40v48.8h14.4v-48.8c0-14.1,11.5-25.6,25.6-25.6s25.6,11.5,25.6,25.6v48.8h0ZM835.4,91.6h-58.1c1.4-7.5,4.7-13.5,9.9-18,5.2-4.5,11.7-6.7,19.3-6.7s14,2.3,19.1,6.9c5.1,4.6,8.4,10.5,9.8,17.8M850.4,103.6v-3.5c0-9-1.9-17-5.8-24s-9.1-12.5-15.8-16.4c-6.7-3.9-14.1-5.9-22.3-5.9s-15.9,2-22.7,6c-6.9,4-12.3,9.4-16.2,16.3-4,6.9-6,14.6-6,23s2,16.1,6,23c4,6.9,9.4,12.4,16.2,16.3s14.4,6,22.7,6,19.5-2.9,26.9-8.6c7.3-5.8,12.3-12.8,14.9-21.1h-15c-2.1,5-5.4,9-9.9,12-4.5,3-10.2,4.6-16.8,4.6s-14.8-2.5-20.2-7.6c-5.4-5.1-8.6-11.7-9.5-20h73.6Z";

function BrandMark({ size = 32, color }) {
  const c = color || C.brick;
  const h = size * (572.38 / 595.28);
  return (
    <svg viewBox="0 0 595.28 572.38" width={size} height={h} xmlns="http://www.w3.org/2000/svg" style={{display:"block"}}>
      <path d={BRAND_MARK_PATH} fill={c}/>
    </svg>
  );
}

function Wordmark({ height = 28, color }) {
  const c = color || C.brick;
  const w = height * (850.4 / 166);
  return (
    <svg viewBox="0 0 850.4 166" width={w} height={height} xmlns="http://www.w3.org/2000/svg" style={{display:"block"}}>
      <path d={WORDMARK_PATH} fill={c}/>
    </svg>
  );
}

// ── Stages (the NPD process) ────────────────────────────────────────────────
const STAGES = [
  { id:"1", label:"Demand & Viability", short:"Viability", owner:"Supply Chain",
    gate:"Viability approved — proceed to Stage 2",
    items:["Demand source documented (range review / customer request / trend / supplier)","Pricing estimate obtained from supplier","Landed cost and margin assessed against Hawthorne pricing structure","Product added to WIP sheet (All New Product with Pricing spreadsheet)","Viability approved — team notified to proceed"] },
  { id:"2", label:"Supplier Engagement & Cin7 Setup", short:"Cin7 Setup", owner:"Supply Chain",
    gate:"Sample ordered + Cin7 code created",
    items:["Sample(s) ordered from supplier","Fabric samples ordered (upholstery only — mark N/A if not applicable)","Sample expected arrival date recorded on WIP sheet","New product code(s) created in Cin7","Cin7 fields complete: name, materials, dimensions, weight, RRP, cost, supplier, country of origin","Compliance field confirmed: product meets applicable NZ/AU safety standards","Product copy drafted in Cin7 ready for final review on arrival"] },
  { id:"3A", label:"Sample Review & Sign-off", short:"Sample", owner:"Supply Chain + Marketing",
    gate:"Sample signed off by Supply Chain AND Marketing Manager",
    items:["Product quality & finish reviewed — PASS","Dimensions match specification — PASS","Colour match to approved swatch — PASS","Structural integrity confirmed — PASS","Upholstery / fabric quality reviewed (or marked N/A)","Preliminary packaging quality noted","Sample sign-off recorded: approved by Supply Chain Specialist","Sample sign-off recorded: approved by Marketing Manager"] },
  { id:"3B", label:"Branding & Packaging Sign-off", short:"Branding", owner:"Marketing Manager", new:true,
    gate:"All branding items confirmed + PDF proof approved in writing",
    items:["Packaging brief created by Marketing Manager (referencing Brand Guide)","Packaging brief sent to supplier — receipt acknowledged by Supply Chain","Hawthorne brand mark: correct version (master logo / icon), minimum sizes respected","Logo placement: per Brand Guide §2 — clear space respected","Colour palette: CMYK values match core palette (Black, Ivory, Brick) per Brand Guide §4","Typography: Bw Gradual or Neue Haas Grotesk — no substitutions on packaging","Barcode / SKU label: correct Cin7 SKU, scan-tested","Care / material label: correct fibre content, country of origin (Designed in NZ), care symbols","Packaging copy: product name, dimensions, weight match Cin7 listing","Packaging finish confirmed (matte / gloss as specified in brief)","Fabric swatch attached to packaging / swing tag (upholstery only — or N/A)","Pre-production PDF proof reviewed and approved IN WRITING by Marketing Manager","Physical production packaging sample approved (new formats only — or N/A)"] },
  { id:"4", label:"Pre-Launch Setup", short:"Pre-Launch", owner:"Supply Chain + Designer",
    gate:"Photography brief live in Airtable",
    items:["Product added to Photography tab in Airtable (code, name, PO, arrival date)","Product added to Marketing Plan tab in Airtable (PO ref, description, EDM slot, social slot)","Factory clear-cut product images received prior to dispatch","Studio photography brief completed (light plain background, per Brand Guide §5)","Photography brief approved by Marketing Manager","Shipment timing monitored — Airtable updated as required"] },
  { id:"5", label:"Arrival, QC & Go-Live", short:"Go-Live", owner:"Supply Chain + Designer",
    gate:"Branding QC passed + product live in Magento",
    items:["Products delivered to showroom for photography and QC","Physical QC completed against Stage 3A sample sign-off","BRANDING QC — Hawthorne brand mark present and correct","BRANDING QC — Logo placement and clear space respected","BRANDING QC — Colours match approved swatch (Brick / Ivory / Black)","BRANDING QC — Typography correct (Bw Gradual / Neue Haas Grotesk)","BRANDING QC — Barcode / SKU scans correctly in Cin7","BRANDING QC — Care / material label correct","BRANDING QC — Packaging copy matches Cin7 listing","BRANDING QC — Packaging finish as specified","Photography complete and uploaded to Cin7 and Magento","Product made visible in Magento — added to New In / appropriate categories","EDM scheduled","Social activity scheduled"] },
];

const ROLES = ["Supply Chain Specialist","Marketing Manager","Graphic Designer / Photographer","Warehouse","Director","Other"];

// ── Local + remote state ───────────────────────────────────────────────────
const USER_KEY = "hawthorne-npd-user";
const API_URL = "/api/state";

const fmtDate = (iso) => { if (!iso) return ""; const d = new Date(iso); return d.toLocaleDateString("en-NZ",{day:"numeric",month:"short",year:"2-digit",hour:"2-digit",minute:"2-digit"}); };

const initProduct = (name, sku, supplier, createdBy) => ({
  id: Date.now().toString() + "-" + Math.random().toString(36).slice(2,7),
  name, sku, supplier,
  createdAt: new Date().toISOString(), createdBy, currentStage:"1",
  stages: Object.fromEntries(STAGES.map(s => [s.id, { items: s.items.map((text,i) => ({ id:`${s.id}-${i}`, text, checked:false, checkedBy:null, checkedAt:null, note:"" })) }]))
});

const stageProgress = (product, stageId) => {
  const items = product.stages[stageId]?.items || [];
  const done = items.filter(i => i.checked).length;
  return { done, total:items.length, pct: items.length ? Math.round(done/items.length*100) : 0 };
};
const stageComplete = (product, stageId) => { const {done,total} = stageProgress(product, stageId); return total>0 && done===total; };
const overallProgress = (product) => {
  let done = 0, total = 0;
  STAGES.forEach(s => { const items = product.stages[s.id]?.items || []; done += items.filter(i=>i.checked).length; total += items.length; });
  return total ? Math.round(done/total*100) : 0;
};
const deriveCurrentStage = (product) => {
  for (const s of STAGES) { if (!stageComplete(product, s.id)) return s.id; }
  return STAGES[STAGES.length-1].id;
};

// ── Remote storage (Cloudflare KV via Pages Functions) ──────────────────────
async function loadState() {
  try {
    const r = await fetch(API_URL, { cache: "no-store" });
    if (!r.ok) return { products: [] };
    return await r.json();
  } catch { return { products: [] }; }
}
async function saveState(state) {
  try {
    await fetch(API_URL, { method:"POST", headers:{"Content-Type":"application/json"}, body: JSON.stringify(state) });
  } catch (e) { console.error("Save failed:", e); }
}

// ─── Login ──────────────────────────────────────────────────────────────────
function LoginScreen({ onLogin }) {
  const [name, setName] = useState("");
  const [role, setRole] = useState(ROLES[0]);

  return (
    <div style={{minHeight:"100vh",background:C.ivory,display:"flex",alignItems:"center",justifyContent:"center",padding:"24px",position:"relative",overflow:"hidden"}}>
      <div style={{position:"absolute",top:"-60px",right:"-80px",opacity:0.05,transform:"rotate(15deg)"}}><BrandMark size={420}/></div>
      <div style={{position:"absolute",bottom:"-100px",left:"-60px",opacity:0.04,transform:"rotate(-20deg)"}}><BrandMark size={320}/></div>

      <div className="fade-up" style={{width:"100%",maxWidth:"460px",position:"relative",zIndex:1}}>
        <div style={{textAlign:"center",marginBottom:"40px"}}>
          <div style={{display:"flex",justifyContent:"center",marginBottom:"20px"}}><BrandMark size={56}/></div>
          <div style={{display:"flex",justifyContent:"center",marginBottom:"10px"}}><Wordmark height={32}/></div>
          <div style={{fontSize:"10px",color:C.brick,letterSpacing:"0.28em",fontWeight:600,marginTop:"8px"}}>NEW PRODUCT DEVELOPMENT</div>
        </div>

        <div style={{background:C.white,borderRadius:"4px",padding:"40px",border:`1px solid ${C.ivoryD}`,position:"relative"}}>
          <div style={{position:"absolute",top:0,left:0,right:0,height:"4px",background:C.brick,borderRadius:"4px 4px 0 0"}}/>
          <div style={{fontSize:"11px",color:C.brick,letterSpacing:"0.2em",fontWeight:600,marginBottom:"8px"}}>SIGN IN</div>
          <h2 style={{fontSize:"24px",color:C.black,marginBottom:"6px",fontWeight:400,letterSpacing:"-0.01em"}}>Welcome back</h2>
          <p style={{fontSize:"14px",color:C.muted,marginBottom:"32px",lineHeight:1.5}}>Enter your name to track new product development.</p>

          <div style={{marginBottom:"20px"}}>
            <label style={{display:"block",fontSize:"10px",color:C.black,letterSpacing:"0.18em",fontWeight:700,marginBottom:"8px"}}>YOUR NAME</label>
            <input value={name} onChange={e=>setName(e.target.value)} onKeyDown={e=>e.key==="Enter"&&name.trim()&&onLogin(name.trim(),role)} placeholder="e.g. Louisa"
              style={{width:"100%",padding:"13px 16px",background:C.ivory,border:`1px solid ${C.ivoryD}`,borderRadius:"3px",color:C.black,fontSize:"15px",outline:"none",transition:"border-color .2s"}}
              onFocus={e=>e.target.style.borderColor=C.brick} onBlur={e=>e.target.style.borderColor=C.ivoryD}/>
          </div>

          <div style={{marginBottom:"32px"}}>
            <label style={{display:"block",fontSize:"10px",color:C.black,letterSpacing:"0.18em",fontWeight:700,marginBottom:"8px"}}>YOUR ROLE</label>
            <select value={role} onChange={e=>setRole(e.target.value)}
              style={{width:"100%",padding:"13px 16px",background:C.ivory,border:`1px solid ${C.ivoryD}`,borderRadius:"3px",color:C.black,fontSize:"15px",outline:"none",cursor:"pointer"}}>
              {ROLES.map(r=><option key={r} value={r}>{r}</option>)}
            </select>
          </div>

          <button onClick={()=>name.trim()&&onLogin(name.trim(),role)} disabled={!name.trim()}
            style={{width:"100%",padding:"14px",background:name.trim()?C.brick:C.ivoryD,color:name.trim()?C.ivory:C.muted,border:"none",borderRadius:"3px",fontSize:"12px",fontWeight:700,letterSpacing:"0.18em",cursor:name.trim()?"pointer":"not-allowed",transition:"all .2s"}}
            onMouseEnter={e=>{if(name.trim())e.target.style.background=C.brickD}}
            onMouseLeave={e=>{if(name.trim())e.target.style.background=C.brick}}>
            ENTER WORKSPACE
          </button>
        </div>
        <p style={{textAlign:"center",fontSize:"12px",color:C.muted,marginTop:"20px",fontStyle:"italic"}}>Your individuality is our inspiration.</p>
      </div>
    </div>
  );
}

function StagePill({ stage, active, done, locked }) {
  const bg = done?C.moss:active?C.brick:locked?"transparent":C.ivoryD;
  const border = done?C.moss:active?C.brick:C.ivoryDD;
  const color = done?C.ivory:active?C.ivory:locked?C.mutedL:C.muted;
  return (
    <div style={{display:"flex",flexDirection:"column",alignItems:"center",gap:"5px",flex:1,minWidth:0}}>
      <div style={{width:"30px",height:"30px",borderRadius:"50%",background:bg,border:`1.5px solid ${border}`,display:"flex",alignItems:"center",justifyContent:"center",fontSize:"11px",fontWeight:700,color,transition:"all .3s"}}>
        {done?"✓":stage.id}
      </div>
      <span style={{fontSize:"9px",color:active?C.brick:done?C.moss:C.muted,fontWeight:active||done?700:500,textAlign:"center",lineHeight:1.3,overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap",maxWidth:"68px",letterSpacing:"0.05em"}}>{stage.short}</span>
    </div>
  );
}

function ProductCard({ product, onClick }) {
  const pct = overallProgress(product);
  const stageIdx = STAGES.findIndex(s=>s.id===product.currentStage);
  const currentStage = STAGES[stageIdx];
  const isComplete = stageIdx===STAGES.length-1 && stageComplete(product, product.currentStage);
  return (
    <div onClick={onClick} className="fade-up"
      style={{background:C.white,borderRadius:"4px",padding:"24px",cursor:"pointer",border:`1px solid ${C.ivoryD}`,transition:"all .25s",position:"relative",overflow:"hidden"}}
      onMouseEnter={e=>{e.currentTarget.style.transform="translateY(-2px)";e.currentTarget.style.boxShadow="0 10px 30px rgba(128,58,43,0.08)";e.currentTarget.style.borderColor=C.brick}}
      onMouseLeave={e=>{e.currentTarget.style.transform="";e.currentTarget.style.boxShadow="";e.currentTarget.style.borderColor=C.ivoryD}}>
      <div style={{position:"absolute",left:0,top:0,bottom:0,width:"3px",background:isComplete?C.moss:C.brick}}/>
      <div style={{display:"flex",justifyContent:"space-between",alignItems:"flex-start",marginBottom:"16px",paddingLeft:"6px"}}>
        <div>
          <div style={{fontSize:"20px",fontWeight:300,color:C.black,marginBottom:"4px",letterSpacing:"-0.01em"}}>{product.name}</div>
          <div style={{display:"flex",gap:"10px",fontSize:"11px",color:C.muted,letterSpacing:"0.06em"}}>
            {product.sku && <span>SKU · {product.sku}</span>}
            {product.supplier && <span>· {product.supplier}</span>}
          </div>
        </div>
        <div style={{textAlign:"right"}}>
          <div style={{fontSize:"24px",fontWeight:300,color:isComplete?C.moss:C.brick,letterSpacing:"-0.02em"}}>{pct}<span style={{fontSize:"14px",color:C.muted}}>%</span></div>
        </div>
      </div>
      <div style={{height:"2px",background:C.ivoryD,marginBottom:"18px",overflow:"hidden",marginLeft:"6px"}}>
        <div style={{height:"100%",width:`${pct}%`,background:isComplete?C.moss:C.brick,transition:"width .5s ease"}}/>
      </div>
      <div style={{display:"flex",alignItems:"flex-start",gap:"0",marginBottom:"16px",marginLeft:"6px"}}>
        {STAGES.map((s,i)=>{
          const done = i<stageIdx || (i===stageIdx && stageComplete(product, s.id));
          const active = i===stageIdx && !done;
          const locked = i>stageIdx;
          return (
            <div key={s.id} style={{display:"flex",flex:1,alignItems:"center"}}>
              <StagePill stage={s} active={active} done={done} locked={locked}/>
              {i<STAGES.length-1 && <div style={{flex:1,height:"1px",background:done?C.moss:C.ivoryD,minWidth:"4px",marginTop:"-18px"}}/>}
            </div>
          );
        })}
      </div>
      <div style={{display:"flex",justifyContent:"space-between",alignItems:"center",marginLeft:"6px"}}>
        <div style={{display:"flex",alignItems:"center",gap:"8px"}}>
          <div style={{width:"6px",height:"6px",borderRadius:"50%",background:isComplete?C.moss:C.brick}} className={isComplete?"":"pulse"}/>
          <span style={{fontSize:"13px",color:C.black,fontWeight:500}}>{isComplete?"Complete":`Stage ${currentStage?.id} · ${currentStage?.label}`}</span>
          {currentStage?.new && <span style={{fontSize:"9px",background:C.brick,color:C.ivory,padding:"3px 7px",borderRadius:"2px",fontWeight:700,letterSpacing:"0.1em"}}>NEW</span>}
        </div>
        <span style={{fontSize:"11px",color:C.muted,letterSpacing:"0.04em"}}>{product.createdBy}</span>
      </div>
    </div>
  );
}

function AddProductModal({ user, onAdd, onClose }) {
  const [name, setName] = useState(""); const [sku, setSku] = useState(""); const [supplier, setSupplier] = useState("");
  const inp = {width:"100%",padding:"12px 14px",background:C.ivory,border:`1px solid ${C.ivoryD}`,borderRadius:"3px",fontSize:"14px",color:C.black,outline:"none",transition:"border-color .2s"};
  return (
    <div style={{position:"fixed",inset:0,background:"rgba(28,26,23,0.55)",display:"flex",alignItems:"center",justifyContent:"center",zIndex:100,padding:"24px",backdropFilter:"blur(4px)"}}>
      <div className="fade-up" style={{background:C.white,borderRadius:"4px",padding:"40px",width:"100%",maxWidth:"460px",boxShadow:"0 20px 60px rgba(28,26,23,0.25)",position:"relative"}}>
        <div style={{position:"absolute",top:0,left:0,right:0,height:"4px",background:C.brick,borderRadius:"4px 4px 0 0"}}/>
        <div style={{fontSize:"11px",color:C.brick,letterSpacing:"0.2em",fontWeight:700,marginBottom:"8px"}}>NEW PRODUCT</div>
        <h2 style={{fontSize:"26px",color:C.black,marginBottom:"8px",fontWeight:300,letterSpacing:"-0.01em"}}>Start a workflow</h2>
        <p style={{fontSize:"13px",color:C.muted,marginBottom:"28px",lineHeight:1.5}}>Initiate a new product through the Hawthorne NPD process.</p>
        {[["PRODUCT NAME *",name,setName,"e.g. Alva 3-Seat Sofa"],["CIN7 SKU",sku,setSku,"e.g. SOF-ALV-3S"],["SUPPLIER",supplier,setSupplier,"e.g. Guangzhou Furniture Co."]].map(([label,val,setVal,ph])=>(
          <div key={label} style={{marginBottom:"18px"}}>
            <label style={{display:"block",fontSize:"10px",color:C.black,letterSpacing:"0.18em",fontWeight:700,marginBottom:"8px"}}>{label}</label>
            <input value={val} onChange={e=>setVal(e.target.value)} placeholder={ph} style={inp} onFocus={e=>e.target.style.borderColor=C.brick} onBlur={e=>e.target.style.borderColor=C.ivoryD}/>
          </div>
        ))}
        <div style={{display:"flex",gap:"10px",marginTop:"28px"}}>
          <button onClick={onClose} style={{flex:1,padding:"13px",background:"transparent",border:`1px solid ${C.ivoryD}`,borderRadius:"3px",fontSize:"12px",color:C.muted,cursor:"pointer",letterSpacing:"0.15em",fontWeight:600}}>CANCEL</button>
          <button onClick={()=>name.trim()&&onAdd(initProduct(name.trim(),sku.trim(),supplier.trim(),user.name))} disabled={!name.trim()}
            style={{flex:2,padding:"13px",background:name.trim()?C.brick:C.ivoryD,color:name.trim()?C.ivory:C.muted,border:"none",borderRadius:"3px",fontSize:"12px",fontWeight:700,cursor:name.trim()?"pointer":"not-allowed",letterSpacing:"0.18em",transition:"background .2s"}}
            onMouseEnter={e=>{if(name.trim())e.target.style.background=C.brickD}}
            onMouseLeave={e=>{if(name.trim())e.target.style.background=C.brick}}>
            CREATE WORKFLOW
          </button>
        </div>
      </div>
    </div>
  );
}

function CheckItem({ item, onToggle, onNote, canCheck }) {
  const [expanded, setExpanded] = useState(false);
  const isBrandingQC = item.text.startsWith("BRANDING QC");
  const displayText = item.text.replace("BRANDING QC — ", "");
  return (
    <div style={{borderRadius:"3px",border:`1px solid ${item.checked?(isBrandingQC?C.moss+"40":C.ivoryD):C.ivoryD}`,background:item.checked?(isBrandingQC?C.moss+"0d":C.ivory):C.white,transition:"all .2s",overflow:"hidden"}}>
      <div style={{display:"flex",alignItems:"flex-start",gap:"12px",padding:"13px 16px"}}>
        <button onClick={()=>canCheck&&onToggle(item.id)}
          style={{width:"20px",height:"20px",minWidth:"20px",borderRadius:"3px",border:`1.5px solid ${item.checked?(isBrandingQC?C.moss:C.brick):C.ivoryDD}`,background:item.checked?(isBrandingQC?C.moss:C.brick):C.white,display:"flex",alignItems:"center",justifyContent:"center",cursor:canCheck?"pointer":"default",transition:"all .2s",marginTop:"1px",padding:0}}>
          {item.checked && <span style={{color:C.ivory,fontSize:"11px",fontWeight:700,lineHeight:1}}>✓</span>}
        </button>
        <div style={{flex:1,minWidth:0}}>
          <div style={{display:"flex",alignItems:"flex-start",justifyContent:"space-between",gap:"8px"}}>
            <div style={{flex:1}}>
              {isBrandingQC && <span style={{fontSize:"9px",background:item.checked?C.moss:C.brick,color:C.ivory,padding:"2px 6px",borderRadius:"2px",fontWeight:700,marginRight:"8px",letterSpacing:"0.1em"}}>BRANDING QC</span>}
              <span style={{fontSize:"13px",color:item.checked?C.muted:C.black,textDecoration:item.checked?"line-through":"none",lineHeight:1.55}}>{displayText}</span>
            </div>
            <button onClick={()=>setExpanded(!expanded)} style={{background:"none",border:"none",cursor:"pointer",color:C.muted,fontSize:"16px",lineHeight:1,padding:"0 3px",flexShrink:0,fontWeight:300}}>{expanded?"−":"+"}</button>
          </div>
          {item.checked && item.checkedBy && <div style={{marginTop:"6px",fontSize:"11px",color:C.muted,letterSpacing:"0.04em"}}>✓ {item.checkedBy} · {fmtDate(item.checkedAt)}</div>}
        </div>
      </div>
      {expanded && (
        <div style={{padding:"0 16px 13px 48px"}}>
          <textarea value={item.note} onChange={e=>onNote(item.id,e.target.value)} placeholder="Add a note or N/A reason…" rows={2}
            style={{width:"100%",padding:"9px 12px",background:C.ivory,border:`1px solid ${C.ivoryD}`,borderRadius:"3px",fontSize:"13px",color:C.black,resize:"vertical",outline:"none"}}/>
        </div>
      )}
    </div>
  );
}

function StagePanel({ stage, stageData, user, onToggle, onNote, isActive, isDone, isLocked }) {
  const { done, total, pct } = stageData
    ? { done: stageData.items.filter(i=>i.checked).length, total: stageData.items.length, pct: stageData.items.length ? Math.round(stageData.items.filter(i=>i.checked).length/stageData.items.length*100) : 0 }
    : { done:0, total:0, pct:0 };
  const allDone = done === total && total > 0;
  const [open, setOpen] = useState(true);
  useEffect(()=>{ if (isActive) setOpen(true); }, [isActive]);
  const headerBg = isDone?C.moss:isActive?C.brick:isLocked?C.ivory:C.inkSoft;
  const headerColor = isDone||isActive?C.ivory:isLocked?C.muted:C.ivory;
  return (
    <div style={{borderRadius:"4px",overflow:"hidden",border:`1px solid ${isActive?C.brick:isDone?C.moss+"40":C.ivoryD}`,boxShadow:isActive?`0 0 0 1px ${C.brick}`:"none",transition:"all .3s"}}>
      <button onClick={()=>!isLocked&&setOpen(!open)}
        style={{width:"100%",background:headerBg,padding:"17px 22px",display:"flex",alignItems:"center",justifyContent:"space-between",border:"none",cursor:isLocked?"default":"pointer",transition:"background .3s"}}>
        <div style={{display:"flex",alignItems:"center",gap:"14px"}}>
          <div style={{width:"34px",height:"34px",borderRadius:"50%",background:isDone?"rgba(248,242,233,0.2)":isActive?"rgba(248,242,233,0.18)":"rgba(248,242,233,0.06)",display:"flex",alignItems:"center",justifyContent:"center",fontSize:"13px",fontWeight:700,color:isDone||isActive?C.ivory:C.muted,flexShrink:0,border:isLocked?`1px solid ${C.ivoryD}`:"none"}}>
            {isDone?"✓":stage.id}
          </div>
          <div style={{textAlign:"left"}}>
            <div style={{display:"flex",alignItems:"center",gap:"10px"}}>
              <span style={{fontSize:"17px",fontWeight:400,color:headerColor,letterSpacing:"-0.005em"}}>{stage.label}</span>
              {stage.new && <span style={{fontSize:"9px",background:isActive||isDone?"rgba(248,242,233,0.25)":C.brick,color:C.ivory,padding:"2px 7px",borderRadius:"2px",fontWeight:700,letterSpacing:"0.1em"}}>NEW</span>}
            </div>
            <div style={{fontSize:"11px",color:isDone||isActive?"rgba(248,242,233,0.7)":C.muted,marginTop:"3px",letterSpacing:"0.06em"}}>OWNER · {stage.owner.toUpperCase()}</div>
          </div>
        </div>
        <div style={{display:"flex",alignItems:"center",gap:"12px"}}>
          {!isLocked && <span style={{fontSize:"13px",color:isDone?"rgba(248,242,233,0.85)":isActive?C.ivory:C.muted,fontWeight:600,letterSpacing:"0.05em"}}>{done} / {total}</span>}
          {isLocked && <span style={{fontSize:"11px",color:C.muted,letterSpacing:"0.08em"}}>LOCKED</span>}
          {!isLocked && <span style={{fontSize:"14px",color:isDone||isActive?"rgba(248,242,233,0.7)":C.muted}}>{open?"▲":"▼"}</span>}
        </div>
      </button>
      {!isLocked && <div style={{height:"2px",background:"rgba(0,0,0,0.05)"}}><div style={{height:"100%",width:`${pct}%`,background:isDone?C.moss:C.brick,transition:"width .5s ease"}}/></div>}
      {open && !isLocked && (
        <div style={{padding:"22px",background:C.white}}>
          <div style={{background:C.ivory,borderRadius:"3px",padding:"12px 16px",marginBottom:"18px",borderLeft:`3px solid ${C.brick}`,fontSize:"13px",color:C.black,lineHeight:1.5}}>
            <span style={{fontWeight:700,letterSpacing:"0.1em",fontSize:"10px",color:C.brick}}>GATE</span>
            <span style={{display:"block",marginTop:"2px"}}>{stage.gate}</span>
          </div>
          <div style={{display:"flex",flexDirection:"column",gap:"7px",marginBottom:"18px"}}>
            {stageData?.items.map(item => (
              <CheckItem key={item.id} item={item} onToggle={onToggle} onNote={onNote} canCheck={true}/>
            ))}
          </div>
          {stage.id === STAGES[STAGES.length-1].id && allDone && (
            <div style={{padding:"24px",background:C.moss+"0d",borderRadius:"3px",border:`1px solid ${C.moss}40`,textAlign:"center"}}>
              <div style={{fontSize:"11px",color:C.moss,letterSpacing:"0.2em",fontWeight:700,marginBottom:"6px"}}>LAUNCHED</div>
              <div style={{fontSize:"20px",color:C.black,fontWeight:300,letterSpacing:"-0.01em"}}>Product is live</div>
              <div style={{fontSize:"13px",color:C.muted,marginTop:"6px",fontStyle:"italic"}}>All stages complete · brand integrity preserved</div>
            </div>
          )}
        </div>
      )}
    </div>
  );
}

function ProductDetail({ product, user, onUpdate, onBack }) {
  const stageIdx = STAGES.findIndex(s=>s.id===product.currentStage);
  const handleToggle = useCallback((stageId,itemId)=>{
    const updated = JSON.parse(JSON.stringify(product));
    const item = updated.stages[stageId].items.find(i=>i.id===itemId);
    if (item) { item.checked = !item.checked; item.checkedBy = item.checked?user.name:null; item.checkedAt = item.checked?new Date().toISOString():null; }
    updated.currentStage = deriveCurrentStage(updated);
    onUpdate(updated);
  },[product,user,onUpdate]);
  const handleNote = useCallback((stageId,itemId,note)=>{
    const updated = JSON.parse(JSON.stringify(product));
    const item = updated.stages[stageId].items.find(i=>i.id===itemId);
    if (item) item.note = note;
    onUpdate(updated);
  },[product,onUpdate]);
  const pct = overallProgress(product);
  const isComplete = stageIdx===STAGES.length-1 && stageComplete(product, product.currentStage);
  return (
    <div style={{minHeight:"100vh",background:C.ivory}}>
      <div style={{background:C.black,padding:"15px 22px",display:"flex",alignItems:"center",gap:"16px",position:"sticky",top:0,zIndex:50,borderBottom:`3px solid ${C.brick}`}}>
        <button onClick={onBack} style={{background:"rgba(248,242,233,0.1)",border:"none",color:C.ivory,padding:"8px 14px",borderRadius:"3px",cursor:"pointer",fontSize:"12px",letterSpacing:"0.1em",fontWeight:600}}>← BACK</button>
        <div style={{flex:1}}>
          <div style={{fontSize:"18px",color:C.ivory,fontWeight:400,letterSpacing:"-0.005em"}}>{product.name}</div>
          <div style={{fontSize:"11px",color:C.mutedL,marginTop:"2px",letterSpacing:"0.05em"}}>
            {product.sku && `SKU · ${product.sku}  `}
            {product.supplier && `·  ${product.supplier}  `}
            <span style={{color:C.ivoryDD}}>·  </span>
            <span style={{color:C.brickL,fontWeight:600}}>{user.name}</span>
          </div>
        </div>
        <div style={{textAlign:"right"}}>
          <div style={{fontSize:"22px",fontWeight:300,color:isComplete?C.moss:C.brickL,letterSpacing:"-0.02em"}}>{pct}<span style={{fontSize:"12px",color:C.mutedL}}>%</span></div>
        </div>
      </div>
      <div style={{height:"3px",background:"rgba(255,255,255,0.05)"}}><div style={{height:"100%",width:`${pct}%`,background:isComplete?C.moss:C.brick,transition:"width .5s"}}/></div>
      <div style={{maxWidth:"800px",margin:"0 auto",padding:"32px 22px"}}>
        <div style={{display:"flex",flexDirection:"column",gap:"10px"}}>
          {STAGES.map((stage,i)=>{
            const done = stageComplete(product, stage.id);
            const active = i===stageIdx && !done;
            return (
              <StagePanel key={stage.id} stage={stage} stageData={product.stages[stage.id]} user={user}
                onToggle={(itemId)=>handleToggle(stage.id,itemId)} onNote={(itemId,note)=>handleNote(stage.id,itemId,note)}
                isActive={active} isDone={done} isLocked={false}/>
            );
          })}
        </div>
      </div>
    </div>
  );
}

function Dashboard({ user, products, onSelect, onAdd, onSignOut }) {
  const [showAdd, setShowAdd] = useState(false);
  const [filter, setFilter] = useState("all");
  const filtered = products.filter(p=>{
    if (filter==="all") return true;
    const idx = STAGES.findIndex(s=>s.id===p.currentStage);
    const complete = idx===STAGES.length-1 && stageComplete(p, p.currentStage);
    if (filter==="active") return !complete;
    if (filter==="complete") return complete;
    if (filter==="branding") return p.currentStage==="3B";
    return true;
  });
  const stats = {
    total: products.length,
    active: products.filter(p=>{const idx=STAGES.findIndex(s=>s.id===p.currentStage);return !(idx===STAGES.length-1 && stageComplete(p, p.currentStage));}).length,
    branding: products.filter(p=>p.currentStage==="3B").length,
    complete: products.filter(p=>{const idx=STAGES.findIndex(s=>s.id===p.currentStage);return idx===STAGES.length-1 && stageComplete(p, p.currentStage);}).length,
  };
  return (
    <div style={{minHeight:"100vh",background:C.ivory}}>
      <div style={{background:C.black,borderBottom:`3px solid ${C.brick}`}}>
        <div style={{maxWidth:"1100px",margin:"0 auto",padding:"18px 22px",display:"flex",alignItems:"center",justifyContent:"space-between"}}>
          <div style={{display:"flex",alignItems:"center",gap:"14px"}}>
            <BrandMark size={32} color={C.ivory}/>
            <div style={{height:"28px",width:"1px",background:"rgba(248,242,233,0.2)"}}/>
            <Wordmark height={22} color={C.ivory}/>
            <div style={{fontSize:"9px",color:C.brickL,letterSpacing:"0.25em",fontWeight:700,marginLeft:"8px"}}>NPD WORKFLOW</div>
          </div>
          <div style={{display:"flex",alignItems:"center",gap:"16px"}}>
            <div style={{fontSize:"12px",color:C.mutedL,letterSpacing:"0.03em"}}>
              <span style={{color:C.brickL,fontWeight:700}}>{user.name}</span>
              <span style={{color:"rgba(248,242,233,0.3)",margin:"0 8px"}}>·</span>
              <span>{user.role}</span>
            </div>
            <button onClick={onSignOut} style={{background:"rgba(248,242,233,0.08)",border:"none",color:C.mutedL,padding:"7px 12px",borderRadius:"3px",cursor:"pointer",fontSize:"11px",letterSpacing:"0.12em",fontWeight:600}}>SIGN OUT</button>
          </div>
        </div>
      </div>

      <div style={{maxWidth:"1100px",margin:"0 auto",padding:"32px 22px"}}>
        <div style={{marginBottom:"28px"}}>
          <div style={{fontSize:"10px",color:C.brick,letterSpacing:"0.25em",fontWeight:700,marginBottom:"6px"}}>NEW PRODUCT DEVELOPMENT</div>
          <div style={{fontSize:"32px",fontWeight:300,color:C.black,letterSpacing:"-0.02em",lineHeight:1.1}}>Your individuality<br/><span style={{color:C.brick,fontStyle:"italic"}}>is our inspiration</span></div>
        </div>

        <div className="stats-grid" style={{display:"grid",gridTemplateColumns:"repeat(4,1fr)",gap:"14px",marginBottom:"28px"}}>
          {[["Total",stats.total,C.black],["In Progress",stats.active,C.brick],["Branding Review",stats.branding,C.rust],["Complete",stats.complete,C.moss]].map(([label,val,color])=>(
            <div key={label} className="fade-up" style={{background:C.white,borderRadius:"4px",padding:"18px 20px",border:`1px solid ${C.ivoryD}`,position:"relative",overflow:"hidden"}}>
              <div style={{position:"absolute",left:0,top:0,bottom:0,width:"2px",background:color}}/>
              <div style={{fontSize:"30px",fontWeight:300,color,letterSpacing:"-0.02em",lineHeight:1}}>{val}</div>
              <div style={{fontSize:"10px",color:C.muted,marginTop:"6px",letterSpacing:"0.15em",fontWeight:700}}>{label.toUpperCase()}</div>
            </div>
          ))}
        </div>

        <div className="toolbar" style={{display:"flex",justifyContent:"space-between",alignItems:"center",marginBottom:"18px",flexWrap:"wrap",gap:"12px"}}>
          <div style={{display:"flex",gap:"4px",flexWrap:"wrap"}}>
            {[["all","All"],["active","Active"],["branding","Branding"],["complete","Complete"]].map(([val,label])=>(
              <button key={val} onClick={()=>setFilter(val)}
                style={{padding:"8px 16px",borderRadius:"3px",border:`1px solid ${filter===val?C.brick:C.ivoryD}`,background:filter===val?C.brick:C.white,color:filter===val?C.ivory:C.muted,fontSize:"12px",fontWeight:filter===val?700:500,cursor:"pointer",letterSpacing:"0.08em",transition:"all .2s"}}>
                {label.toUpperCase()}
              </button>
            ))}
          </div>
          <button onClick={()=>setShowAdd(true)}
            style={{padding:"10px 20px",background:C.black,color:C.ivory,border:"none",borderRadius:"3px",fontSize:"12px",fontWeight:700,cursor:"pointer",letterSpacing:"0.18em",transition:"background .2s"}}
            onMouseEnter={e=>e.target.style.background=C.inkSoft}
            onMouseLeave={e=>e.target.style.background=C.black}>
            + NEW PRODUCT
          </button>
        </div>

        {stats.branding>0 && (
          <div className="fade-up" style={{background:C.rust+"14",border:`1px solid ${C.rust}40`,borderRadius:"3px",padding:"14px 18px",marginBottom:"18px",borderLeft:`3px solid ${C.rust}`}}>
            <span style={{fontSize:"10px",letterSpacing:"0.18em",fontWeight:700,color:C.rust}}>BRANDING REVIEW REQUIRED · </span>
            <span style={{fontSize:"13px",color:C.black,fontWeight:600}}>{stats.branding} product{stats.branding!==1?"s":""} awaiting Stage 3B sign-off</span>
            <span style={{color:C.muted,fontSize:"13px"}}> — Marketing Manager action required</span>
          </div>
        )}

        {filtered.length===0 ? (
          <div style={{textAlign:"center",padding:"64px 24px",color:C.muted,background:C.white,borderRadius:"4px",border:`1px solid ${C.ivoryD}`}}>
            <div style={{display:"flex",justifyContent:"center",opacity:0.4}}><BrandMark size={56}/></div>
            <div style={{fontSize:"24px",marginTop:"16px",marginBottom:"6px",color:C.black,fontWeight:300,letterSpacing:"-0.01em"}}>No products here</div>
            <div style={{fontSize:"13px",fontStyle:"italic"}}>Add your first product to start a workflow</div>
          </div>
        ) : (
          <div className="product-grid" style={{display:"grid",gridTemplateColumns:"repeat(auto-fill,minmax(460px,1fr))",gap:"14px"}}>
            {filtered.map(p=><ProductCard key={p.id} product={p} onClick={()=>onSelect(p.id)}/>)}
          </div>
        )}
      </div>

      <div style={{maxWidth:"1100px",margin:"40px auto 0",padding:"24px 22px",borderTop:`1px solid ${C.ivoryD}`,display:"flex",justifyContent:"space-between",alignItems:"center"}}>
        <div style={{display:"flex",alignItems:"center",gap:"10px"}}>
          <BrandMark size={20} color={C.muted}/>
          <div style={{fontSize:"11px",color:C.muted,letterSpacing:"0.05em"}}>Hawthorne Group · hawthornegroup.co.nz</div>
        </div>
        <div style={{fontSize:"10px",color:C.muted,letterSpacing:"0.18em",fontWeight:700}}>NPD WORKFLOW v2.0</div>
      </div>

      {showAdd && <AddProductModal user={user} onAdd={(p)=>{onAdd(p);setShowAdd(false);}} onClose={()=>setShowAdd(false)}/>}
    </div>
  );
}

function App() {
  const [user, setUser] = useState(null);
  const [products, setProducts] = useState([]);
  const [selectedId, setSelectedId] = useState(null);
  const [loading, setLoading] = useState(true);

  // Restore user from localStorage (so they don't sign in every visit)
  useEffect(()=>{
    try { const saved = localStorage.getItem(USER_KEY); if (saved) setUser(JSON.parse(saved)); } catch {}
  },[]);

  // Load shared state from Cloudflare KV, poll for updates
  useEffect(()=>{
    let cancelled = false;
    const load = async () => {
      const state = await loadState();
      if (!cancelled) { setProducts(state.products || []); setLoading(false); }
    };
    load();
    const interval = setInterval(load, 8000);
    return () => { cancelled = true; clearInterval(interval); };
  },[]);

  const persist = async (newProducts) => {
    setProducts(newProducts);
    await saveState({ products: newProducts });
  };

  const handleLogin = (name, role) => {
    const u = { name, role };
    setUser(u);
    try { localStorage.setItem(USER_KEY, JSON.stringify(u)); } catch {}
  };
  const handleSignOut = () => { setUser(null); try { localStorage.removeItem(USER_KEY); } catch {} };
  const handleUpdate = (updated) => persist(products.map(p=>p.id===updated.id?updated:p));
  const handleAdd = (product) => persist([...products, product]);

  if (loading) {
    return (
      <div style={{minHeight:"100vh",background:C.ivory,display:"flex",alignItems:"center",justifyContent:"center",flexDirection:"column",gap:"20px"}}>
        <div className="pulse"><BrandMark size={64}/></div>
        <Wordmark height={20} color={C.muted}/>
      </div>
    );
  }
  if (!user) return <LoginScreen onLogin={handleLogin}/>;
  const selected = selectedId ? products.find(p=>p.id===selectedId) : null;
  if (selected) return <ProductDetail product={selected} user={user} onUpdate={handleUpdate} onBack={()=>setSelectedId(null)}/>;
  return <Dashboard user={user} products={products} onSelect={setSelectedId} onAdd={handleAdd} onSignOut={handleSignOut}/>;
}

ReactDOM.createRoot(document.getElementById("root")).render(<App/>);
