// Guess the most likely website domain for a company from its display name.
// Heuristic: lowercase, strip non-alphanumeric, append .com if no dot present.
// E.g. "monday.com" → "monday.com", "Rapyd" → "rapyd.com", "eon.io" → "eon.io".
function guessCompanyDomain(name) {
  if (!name) return null;
  const trimmed = String(name).trim().toLowerCase();
  if (!trimmed) return null;
  if (trimmed.includes(".")) return trimmed.replace(/[^a-z0-9.\-]/g, "");
  const slug = trimmed.replace(/[^a-z0-9]/g, "");
  if (!slug) return null;
  return slug + ".com";
}

// Self-managed brand logo image — tries Clearbit, falls back to Google favicon,
// finally renders the provided fallback child (an abstract glyph) if both fail.
function BrandLogoImg({ domain, size, fallbackChild }) {
  const [stage, setStage] = React.useState(0); // 0=clearbit, 1=favicon, 2=give up
  React.useEffect(() => { setStage(0); }, [domain]);
  if (!domain || stage >= 2) return fallbackChild;
  const src = stage === 0
    ? `https://logo.clearbit.com/${domain}`
    : `https://www.google.com/s2/favicons?domain=${domain}&sz=128`;
  return (
    <img
      src={src}
      alt=""
      style={{
        width: size, height: size, objectFit: "contain",
        borderRadius: Math.round(size * 0.18),
        background: "transparent",
      }}
      onError={() => setStage(s => s + 1)}
    />
  );
}

// Custom monogram glyphs — original marks (NOT recreations of brand logos)
// `override` may carry { _logoMode:"letter"|"glyph"|"url", _logoLetter, _logoBg, _logoDomain }
//
// Default behaviour (no override.mode set): auto-fetch the brand logo from the company
// name (Clearbit → favicon → abstract glyph fallback). Set _logoMode explicitly via the
// Edit drawer to override.
function CompanyGlyph({ name, size = 22, override }){
  const ov = override || (window.Store && window.Store.getCompanyOverride ? null : null);
  const logo = randLogo(name);
  const s = size;
  const stroke = "rgba(255,255,255,0.96)";
  const fill = "rgba(255,255,255,0.96)";

  const mode = override?._logoMode;

  // Build the abstract-glyph fallback once so we can hand it to BrandLogoImg.
  const renderAbstractGlyph = () => {
    const G = ABSTRACT_GLYPHS(s, stroke, fill);
    return G[logo.glyph] || G.dot;
  };

  // Letter monogram (explicit)
  if(mode === "letter"){
    const letter = (override._logoLetter || name[0] || "·").toUpperCase().slice(0,2);
    return (
      <span style={{
        fontFamily:"'Fraunces',serif",
        fontWeight:500,
        fontSize: Math.round(s * 0.66),
        color: fill,
        letterSpacing:"-.03em",
        lineHeight:1,
      }}>{letter}</span>
    );
  }

  // Abstract glyph (explicit override — keep the prototype look)
  if(mode === "glyph"){
    return renderAbstractGlyph();
  }

  // Brand logo from URL — explicit (custom domain) OR default (guess from name).
  const explicitDomain = mode === "url" ? (override._logoDomain || "") : "";
  const cleanedExplicit = explicitDomain.replace(/^https?:\/\//, "").replace(/\/.*$/, "").trim();
  const domain = cleanedExplicit || guessCompanyDomain(name);
  return <BrandLogoImg domain={domain} size={s} fallbackChild={renderAbstractGlyph()}/>;
}

// Abstract glyph dictionary, factored out so CompanyGlyph can call it as a fallback
// when the brand-logo fetch fails.
function ABSTRACT_GLYPHS(s, stroke, fill) {
  return {
    "three-bars": (
      <svg width={s} height={s} viewBox="0 0 24 24" fill="none">
        <rect x="4" y="6" width="3" height="12" rx="1.2" fill={fill}/>
        <rect x="10.5" y="9" width="3" height="9" rx="1.2" fill={fill} opacity=".85"/>
        <rect x="17" y="11" width="3" height="7" rx="1.2" fill={fill} opacity=".7"/>
      </svg>
    ),
    "orbit": (
      <svg width={s} height={s} viewBox="0 0 24 24" fill="none">
        <ellipse cx="12" cy="12" rx="9" ry="4" stroke={stroke} strokeWidth="1.6"/>
        <circle cx="12" cy="12" r="3" fill={fill}/>
      </svg>
    ),
    "chevron-stack": (
      <svg width={s} height={s} viewBox="0 0 24 24" fill="none">
        <path d="M5 9l7-4 7 4" stroke={stroke} strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"/>
        <path d="M5 14l7-4 7 4" stroke={stroke} strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round" opacity=".75"/>
        <path d="M5 19l7-4 7 4" stroke={stroke} strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round" opacity=".5"/>
      </svg>
    ),
    "diamond": (
      <svg width={s} height={s} viewBox="0 0 24 24" fill="none">
        <path d="M12 3l8 9-8 9-8-9z" stroke={stroke} strokeWidth="1.6" strokeLinejoin="round"/>
        <path d="M12 3l3 9-3 9-3-9z" fill={fill} opacity=".9"/>
      </svg>
    ),
    "heart-pulse": (
      <svg width={s} height={s} viewBox="0 0 24 24" fill="none">
        <path d="M12 20s-7-4.5-7-10a4 4 0 0 1 7-2.6A4 4 0 0 1 19 10c0 5.5-7 10-7 10z" stroke={stroke} strokeWidth="1.6" strokeLinejoin="round"/>
        <path d="M5 13h3l1.5-3 2 5 1.5-2h6" stroke={stroke} strokeWidth="1.4" strokeLinecap="round" strokeLinejoin="round" opacity=".95"/>
      </svg>
    ),
    "leaf": (
      <svg width={s} height={s} viewBox="0 0 24 24" fill="none">
        <path d="M5 19c0-8 6-14 14-14 0 8-6 14-14 14z" fill={fill}/>
        <path d="M5 19c4-4 8-8 14-14" stroke="rgba(0,0,0,.18)" strokeWidth="1.2" strokeLinecap="round"/>
      </svg>
    ),
    "infinity": (
      <svg width={s} height={s} viewBox="0 0 24 24" fill="none">
        <path d="M7.5 9c-2.5 0-4 1.4-4 3s1.5 3 4 3c4 0 5-6 9-6 2.5 0 4 1.4 4 3s-1.5 3-4 3c-4 0-5-6-9-6z" stroke={stroke} strokeWidth="1.7" strokeLinejoin="round"/>
      </svg>
    ),
    "play-burst": (
      <svg width={s} height={s} viewBox="0 0 24 24" fill="none">
        <circle cx="12" cy="12" r="9" stroke={stroke} strokeWidth="1.4" opacity=".55"/>
        <path d="M10 8.5v7l6-3.5z" fill={fill}/>
      </svg>
    ),
    "prism": (
      <svg width={s} height={s} viewBox="0 0 24 24" fill="none">
        <path d="M12 4l8 14H4z" stroke={stroke} strokeWidth="1.6" strokeLinejoin="round"/>
        <path d="M12 4v14M4 18l16 0" stroke={stroke} strokeWidth="1.2" opacity=".6"/>
      </svg>
    ),
    "dot": <svg width={s} height={s} viewBox="0 0 24 24"><circle cx="12" cy="12" r="6" fill={fill}/></svg>,
  };
}

// Shared icon components + small UI pieces
const Icon = {
  Bell: (p) => (<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round" {...p}><path d="M6 8a6 6 0 0 1 12 0c0 7 3 9 3 9H3s3-2 3-9"/><path d="M10.3 21a1.94 1.94 0 0 0 3.4 0"/></svg>),
  Search: (p) => (<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round" {...p}><circle cx="11" cy="11" r="8"/><path d="m21 21-4.3-4.3"/></svg>),
  Plus: (p) => (<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round" {...p}><path d="M12 5v14M5 12h14"/></svg>),
  ArrowRight: (p) => (<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round" {...p}><path d="M5 12h14M13 5l7 7-7 7"/></svg>),
  Close: (p) => (<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round" {...p}><path d="M18 6 6 18M6 6l12 12"/></svg>),
  Trash: (p) => (<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round" {...p}><polyline points="3 6 5 6 21 6"/><path d="M19 6l-1 14a2 2 0 0 1-2 2H8a2 2 0 0 1-2-2L5 6"/><path d="M10 11v6M14 11v6"/><path d="M9 6V4a2 2 0 0 1 2-2h2a2 2 0 0 1 2 2v2"/></svg>),
  Check: (p) => (<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="3" strokeLinecap="round" strokeLinejoin="round" {...p}><polyline points="20 6 9 17 4 12"/></svg>),
  Phone: (p) => (<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round" {...p}><path d="M22 16.92v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07 19.5 19.5 0 0 1-6-6 19.79 19.79 0 0 1-3.07-8.67A2 2 0 0 1 4.11 2h3a2 2 0 0 1 2 1.72 12.84 12.84 0 0 0 .7 2.81 2 2 0 0 1-.45 2.11L8.09 9.91a16 16 0 0 0 6 6l1.27-1.27a2 2 0 0 1 2.11-.45 12.84 12.84 0 0 0 2.81.7A2 2 0 0 1 22 16.92z"/></svg>),
  Mail: (p) => (<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round" {...p}><rect x="2" y="4" width="20" height="16" rx="2"/><path d="m22 7-10 5L2 7"/></svg>),
  Calendar: (p) => (<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round" {...p}><rect x="3" y="4" width="18" height="18" rx="2"/><path d="M16 2v4M8 2v4M3 10h18"/></svg>),
  Users: (p) => (<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round" {...p}><path d="M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2"/><circle cx="9" cy="7" r="4"/><path d="M22 21v-2a4 4 0 0 0-3-3.87M16 3.13a4 4 0 0 1 0 7.75"/></svg>),
  Pin: (p) => (<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round" {...p}><path d="M12 17v5M9 10.76a2 2 0 0 1-1.11 1.79l-1.78.9A2 2 0 0 0 5 15.24V16a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-.76a2 2 0 0 0-1.11-1.79l-1.78-.9A2 2 0 0 1 15 10.76V7a1 1 0 0 1 1-1 2 2 0 0 0 0-4H8a2 2 0 0 0 0 4 1 1 0 0 1 1 1z"/></svg>),
  Money: (p) => (<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round" {...p}><line x1="12" y1="1" x2="12" y2="23"/><path d="M17 5H9.5a3.5 3.5 0 0 0 0 7h5a3.5 3.5 0 0 1 0 7H6"/></svg>),
  Menu: (p) => (<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round" {...p}><line x1="3" y1="6" x2="21" y2="6"/><line x1="3" y1="12" x2="21" y2="12"/><line x1="3" y1="18" x2="21" y2="18"/></svg>),
  Sparkle: (p) => (<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round" {...p}><path d="M12 3v4M12 17v4M3 12h4M17 12h4M5.6 5.6l2.8 2.8M15.6 15.6l2.8 2.8M5.6 18.4l2.8-2.8M15.6 8.4l2.8-2.8"/></svg>),
  ChevL: (p) => (<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" {...p}><polyline points="15 18 9 12 15 6"/></svg>),
  ChevR: (p) => (<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" {...p}><polyline points="9 18 15 12 9 6"/></svg>),
  Pencil: (p) => (<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round" {...p}><path d="M12 20h9"/><path d="M16.5 3.5a2.121 2.121 0 0 1 3 3L7 19l-4 1 1-4 12.5-12.5z"/></svg>),
};

// Editorial header (clock + date)
function EditorialHeader(){
  const [now, setNow] = React.useState(new Date());
  React.useEffect(()=>{
    const t = setInterval(()=>setNow(new Date()), 1000);
    return ()=>clearInterval(t);
  }, []);
  const hh = String(now.getHours()).padStart(2,"0");
  const mm = String(now.getMinutes()).padStart(2,"0");
  const dateStr = now.toLocaleDateString("en-US", { weekday:"long", month:"long", day:"numeric", year:"numeric" });

  return (
    <div className="editorial-head">
      <div className="eh-greet">
        <span className="eyebrow">Medical by Moveo · Control Center</span>
        <h1>At a <em className="em">glance</em>.</h1>
        <p className="sub">Every client, every thread — live.</p>
      </div>
      <div className="eh-clock">
        <div className="time">{hh}<span className="sep">:</span>{mm}</div>
        <div className="date">{dateStr}</div>
      </div>
    </div>
  );
}

// Top bar
function TopBar({ onOpenTweaks, onOpenMenu }){
  return (
    <div className="topbar">
      <button
        className="tb-menu-btn"
        type="button"
        aria-label="Open menu"
        onClick={onOpenMenu}
      >
        <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><line x1="3" y1="6" x2="21" y2="6"/><line x1="3" y1="12" x2="21" y2="12"/><line x1="3" y1="18" x2="21" y2="18"/></svg>
      </button>
      <div className="tb-brand">
        <img src="assets/medical-logo.png" alt="Medical by Moveo"/>
        <div className="tb-name">
          <b>Medical by Moveo</b>
          <span className="sub">Control Center</span>
        </div>
      </div>
      <div className="tb-right">
        <span className="tb-pill"><span className="dot"/>All systems <b>green</b></span>
        <button className="tb-icon-btn" title="Search"><Icon.Search/></button>
        <button className="tb-icon-btn" title="Notifications">
          <Icon.Bell/>
          <span className="badge-dot"/>
        </button>
        <div className="tb-user" title="Shared team view">
          <div className="av" style={{ background:"linear-gradient(135deg,#2A1D1A,#6B5C54)" }}>
            <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" style={{color:"#fff"}}><path d="M17 21v-2a4 4 0 0 0-3-3.87M16 3.13a4 4 0 0 1 0 7.75M3 21v-2a4 4 0 0 1 4-4h3a4 4 0 0 1 4 4v2"/><circle cx="8.5" cy="7" r="4"/></svg>
          </div>
          <div className="nm">
            <b>Team view</b>
            <span>All employees · shared</span>
          </div>
        </div>
      </div>
    </div>
  );
}

function KPIStrip(){
  const live = window.useLiveData ? window.useLiveData() : null;
  const fmt  = window.fmtMoney  || (n => "₪" + n);
  const fmtS = window.fmtSigned || (n => (n>=0?"+":"") + "₪" + n);

  // Live tiles. Until the JSON loads, fall back to the mock array so the layout doesn't pop.
  const tiles = live ? [
    {
      lbl: "FY26 Booked",
      val: fmt(live.fy.booked),
      trend: live.fy.onTrack ? "On track" : "Behind plan",
      trendType: live.fy.onTrack ? "pos" : "neg",
      sub: `of ${fmt(live.fy.plan)} plan · ${live.fy.daysLeft} days left`,
    },
    {
      lbl: `YTD vs Plan · ${live.monthsClosedLabels[0] || "Jan"}–${live.monthsClosedLabels[live.monthsClosedLabels.length-1] || ""}`,
      val: fmtS(live.ytd.variance),
      trend: live.ytd.variance >= 0 ? "Ahead" : "Behind",
      trendType: live.ytd.variance >= 0 ? "pos" : "neg",
      sub: `${fmt(live.ytd.booked)} booked · plan ${fmt(live.ytd.plan)}`,
    },
    {
      lbl: "Awaiting Invoice",
      val: fmt(live.status["Awaiting Invoice"] || 0),
      trend: "to bill",
      trendType: "flat",
      sub: "across 2026 bookings",
    },
    {
      lbl: "Late!",
      val: fmt(live.status["Late!"] || 0),
      trend: live.status["Late!"] > 0 ? "overdue" : "clean",
      trendType: live.status["Late!"] > 0 ? "neg" : "pos",
      sub: "collection at risk",
    },
  ] : KPIs;

  return (
    <div className="kpi-strip">
      {tiles.map((k, i)=>(
        <div key={i} className="kpi">
          <div className="lbl">{k.lbl}</div>
          <div className="val">{k.val}<span className="unit">{k.unit||""}</span></div>
          <div className="trend">
            <span className={"chip " + (k.trendType==="pos"?"":(k.trendType==="neg"?"neg":"flat"))}>
              {k.trendType==="pos" && "↑"}{k.trendType==="neg" && "↓"} {k.trend}
            </span>
            <span>{k.sub}</span>
          </div>
        </div>
      ))}
    </div>
  );
}

function AgendaPanel(){
  return (
    <div className="panel">
      <div className="panel-head">
        <h3>Today across the <em>company</em></h3>
        <span className="more">View calendar →</span>
      </div>
      <div className="agenda">
        <div className="ag-day">
          <div className="ag-day-label"><span className="dot"/>Today · {AGENDA_TODAY.length} items</div>
          {AGENDA_TODAY.map((a, i)=>(
            <div key={i} className="ag-item">
              <span className="tm">{a.time}</span>
              <div className="ti">
                <b>{a.title}</b>
                <span className="meta">{a.meta}</span>
              </div>
              <span className={"tag " + a.tag}>{a.tagLabel}</span>
            </div>
          ))}
        </div>
        <div className="ag-day tomorrow">
          <div className="ag-day-label"><span className="dot"/>Tomorrow</div>
          {AGENDA_TOMORROW.map((a, i)=>(
            <div key={i} className="ag-item">
              <span className="tm">{a.time}</span>
              <div className="ti">
                <b>{a.title}</b>
                <span className="meta">{a.meta}</span>
              </div>
              <span className={"tag " + a.tag}>{a.tagLabel}</span>
            </div>
          ))}
        </div>
        <div className="ag-day week">
          <div className="ag-day-label"><span className="dot"/>Rest of the week</div>
          {AGENDA_WEEK.map((a, i)=>(
            <div key={i} className="ag-item">
              <span className="tm">{a.time}</span>
              <div className="ti">
                <b>{a.title}</b>
                <span className="meta">{a.meta}</span>
              </div>
              <span className={"tag " + a.tag}>{a.tagLabel}</span>
            </div>
          ))}
        </div>
      </div>
    </div>
  );
}

function AlertsPanel({ onOpen }){
  // Subscribe to tasks and added companies so the panel updates as the Store changes.
  const tasksByClient = window.useStore(s => s.tasksByClient) || {};
  window.useStore(s => s.addedCompanies);

  const tweaks = window.__TWEAKS__ || {};
  const added = (window.Store && window.Store.getAddedCompanies) ? {
    md:   window.Store.getAddedCompanies("md"),
    mgmt: window.Store.getAddedCompanies("mgmt"),
  } : { md:[], mgmt:[] };

  // Full picker list — built from tweaks defaults plus persisted-added companies.
  const allClients = [
    ...((tweaks.mdCompanies   || []).map(n => ({ name: n, segment: "md"   }))),
    ...(added.md   || []).map(c => ({ name: c.name, segment: "md"   })),
    ...((tweaks.mgmtCompanies || []).map(n => ({ name: n, segment: "mgmt" }))),
    ...(added.mgmt || []).map(c => ({ name: c.name, segment: "mgmt" })),
  ].filter((v,i,a) => a.findIndex(x => x.name === v.name && x.segment === v.segment) === i);

  // Reference time at local midnight
  const today = new Date(); today.setHours(0,0,0,0);
  const weekEnd = new Date(today); weekEnd.setDate(today.getDate() + 7);

  // Flatten { "Name:seg": [tasks] } into a list of attention items, filtered to
  // not-done tasks that are overdue OR due within the next 7 days.
  const flat = [];
  for (const [key, list] of Object.entries(tasksByClient)) {
    if (!Array.isArray(list) || !list.length) continue;
    const colonIdx = key.lastIndexOf(":");
    const clientName = key.slice(0, colonIdx);
    const segment    = key.slice(colonIdx + 1) || "md";
    for (let i = 0; i < list.length; i++) {
      const t = list[i];
      if (!t || t.done) continue;
      if (!t.dueIso) continue;
      const due = new Date(t.dueIso + "T00:00");
      if (isNaN(due.getTime())) continue;
      const overdue = due < today;
      const thisWeek = !overdue && due <= weekEnd;
      if (!overdue && !thisWeek) continue;
      flat.push({ ...t, clientName, segment, _due: due, _kind: overdue ? "overdue" : "thisweek" });
    }
  }
  flat.sort((a, b) => (a._kind === b._kind) ? (a._due - b._due) : (a._kind === "overdue" ? -1 : 1));

  const overdueCount = flat.filter(t => t._kind === "overdue").length;
  const weekCount    = flat.length - overdueCount;

  const openTaskClient = (t) => {
    if (!onOpen) return;
    const src = t.segment === "mgmt" ? MGMT_DATA : MD_DATA;
    const data = src[t.clientName];
    if (data) onOpen(
      { name: t.clientName, segment: t.segment, ...data },
      { initialTab: "tasks", highlightTaskAt: t.addedAt }
    );
  };
  const deleteTask = (t, evt) => {
    if (evt && evt.stopPropagation) evt.stopPropagation();
    if (!window.Store) return;
    if (!confirm(`Delete task "${t.title}"?`)) return;
    const cur = window.Store.getTasks(t.clientName, t.segment) || [];
    window.Store.setTasks(t.clientName, t.segment, cur.filter(x => x.addedAt !== t.addedAt));
  };

  // === Quick-add form (inline) ===
  const [adding, setAdding] = React.useState(false);
  const [nTitle, setNTitle] = React.useState("");
  const [nClient, setNClient] = React.useState(""); // value = "Name:segment"
  const [nDate, setNDate] = React.useState("");
  const [nLink, setNLink] = React.useState("");

  const dueLabelFor = (iso) => {
    if (!iso) return "No date";
    const due = new Date(iso + "T00:00");
    const diff = Math.round((due - today) / 86400000);
    if (diff === 0) return "Today";
    if (diff === 1) return "Tomorrow";
    if (diff === -1) return "Yesterday";
    if (diff > 0 && diff < 7) return due.toLocaleDateString(undefined, { weekday: "long" });
    return due.toLocaleDateString(undefined, { month: "short", day: "numeric" });
  };
  const submitNew = () => {
    if (!nTitle.trim() || !nClient || !window.Store) return;
    const colonIdx = nClient.lastIndexOf(":");
    const clientName = nClient.slice(0, colonIdx);
    const segment    = nClient.slice(colonIdx + 1);
    const dueIso = nDate || null;
    let status = "";
    if (dueIso) {
      const due = new Date(dueIso + "T00:00");
      const diff = Math.round((due - today) / 86400000);
      if (diff < 0) status = "overdue";
      else if (diff <= 3) status = "soon";
    }
    const cur = window.Store.getTasks(clientName, segment) || [];
    window.Store.setTasks(clientName, segment, [...cur, {
      title: nTitle.trim(), due: dueLabelFor(dueIso), status,
      done: false, addedAt: Date.now(),
      dueIso, dueTime: null,
      link: nLink.trim() || null,
    }]);
    setNTitle(""); setNClient(""); setNDate(""); setNLink(""); setAdding(false);
  };

  return (
    <div className="panel">
      <div className="panel-head">
        <h3>What needs <em>attention</em></h3>
        <span className="count">
          {overdueCount > 0 && (<><span style={{color:"var(--red)", fontWeight:600}}>{overdueCount} overdue</span> · </>)}
          {weekCount} this week
        </span>
        <button onClick={() => setAdding(v => !v)}
                style={{
                  marginLeft:"auto", padding:"4px 12px", borderRadius:999,
                  border:"1px solid var(--line)", background:"var(--bg-card)",
                  color:"var(--ink)", fontSize:12, cursor:"pointer",
                }}>
          {adding ? "Cancel" : "+ Task"}
        </button>
      </div>

      {adding && (
        <div style={{padding:"10px 14px", display:"flex", flexDirection:"column", gap:8, borderBottom:"1px solid var(--line-soft)"}}>
          <input value={nTitle} onChange={e=>setNTitle(e.target.value)}
                 placeholder="What needs doing?"
                 onKeyDown={e=>{ if(e.key==="Enter") submitNew(); if(e.key==="Escape") setAdding(false); }}
                 style={{padding:"8px 10px", borderRadius:8, border:"1px solid var(--line)", background:"var(--bg-card)"}}/>
          <div style={{display:"flex", gap:8, flexWrap:"wrap", minWidth:0}}>
            <select value={nClient} onChange={e=>setNClient(e.target.value)}
                    style={{flex:"1 1 160px", minWidth:0, padding:"8px 10px", borderRadius:8, border:"1px solid var(--line)", background:"var(--bg-card)"}}>
              <option value="">— Pick client —</option>
              {allClients.map(c => (
                <option key={c.name + ":" + c.segment} value={c.name + ":" + c.segment}>
                  {c.name} · {c.segment === "md" ? "MD" : "Mgmt"}
                </option>
              ))}
            </select>
            <input type="date" value={nDate} onChange={e=>setNDate(e.target.value)}
                   style={{flex:"1 1 120px", minWidth:0, padding:"8px 10px", borderRadius:8, border:"1px solid var(--line)", background:"var(--bg-card)"}}/>
            <button onClick={submitNew}
                    disabled={!nTitle.trim() || !nClient}
                    style={{
                      padding:"8px 14px", borderRadius:8,
                      background: !nTitle.trim() || !nClient ? "var(--line)" : "var(--ink)",
                      color:"#fff", border:"none", cursor:"pointer", fontSize:13,
                      opacity: !nTitle.trim() || !nClient ? .5 : 1,
                    }}>
              Add
            </button>
          </div>
          <input type="url" value={nLink} onChange={e=>setNLink(e.target.value)}
                 placeholder="🔗 Link (optional)"
                 style={{width:"100%", minWidth:0, boxSizing:"border-box", padding:"8px 10px", borderRadius:8, border:"1px solid var(--line)", background:"var(--bg-card)"}}/>
        </div>
      )}

      <div className="alerts">
        {flat.length === 0 ? (
          <div style={{padding:"18px 14px", color:"var(--ink-muted)", fontSize:13}}>
            Nothing overdue and nothing due this week. Add a task above ↑
          </div>
        ) : (
          flat.map((t, i) => (
            <div key={i}
                 className={"alert " + (t._kind === "overdue" ? "red" : "amber") + " clickable"}
                 onClick={() => openTaskClient(t)}>
              <div className="ic">{t._kind === "overdue" ? "⚠" : "◐"}</div>
              <div className="body">
                <b>{t.title}</b>
                <div className="meta">
                  {t.clientName} · {t.segment === "md" ? "MD" : "Management"} · {t.due}
                  {t._kind === "overdue" && " · overdue"}
                </div>
                {t.link && (
                  <a href={t.link} target="_blank" rel="noreferrer"
                     onClick={e=>e.stopPropagation()}
                     style={{
                       display:"inline-flex", alignItems:"center", gap:4,
                       marginTop:4, padding:"2px 8px", borderRadius:999,
                       background:"color-mix(in oklab, var(--accent-soft) 25%, transparent)",
                       border:"1px solid var(--accent-soft)",
                       fontSize:10, fontFamily:"'JetBrains Mono',monospace",
                       color:"var(--ink)", textDecoration:"none",
                       width:"fit-content", maxWidth:"100%",
                       overflow:"hidden", textOverflow:"ellipsis", whiteSpace:"nowrap",
                     }}>
                    🔗 {(() => { try { return new URL(t.link).hostname.replace(/^www\./,""); } catch { return "link"; } })()}
                  </a>
                )}
              </div>
              <button onClick={(e) => deleteTask(t, e)}
                      title="Delete task"
                      style={{
                        background:"transparent", border:"none",
                        color:"var(--ink-muted)", fontSize:18,
                        padding:"0 8px", cursor:"pointer",
                        lineHeight:1,
                      }}>×</button>
              <div className="arr"><Icon.ArrowRight/></div>
            </div>
          ))
        )}
      </div>
    </div>
  );
}

function CompanyTile({ name, data, onOpen, segmentTag }){
  const logo = randLogo(name);
  return (
    <div className="tile" onClick={onOpen}>
      <div className="tile-head">
        <div className="tile-logo" style={{ background: logo.bg }}><CompanyGlyph name={name} size={22}/></div>
        <div className="tile-title">
          <b>{name}</b>
          <span className="role">{data.poc?.name} · {data.poc?.role}</span>
        </div>
        <div className={"health-dot " + (data.health || "")}/>
      </div>

      <div className="tile-row">
        <span className="k">Last touchpoint</span>
        <span className="v"><span className="dim">{data.lastTouch.type} · {data.lastTouch.when} ·</span> {data.lastTouch.note}</span>
      </div>

      <div className="tile-row">
        <span className="k">Current project</span>
        <span className="v">{data.currentProject}</span>
      </div>

      <div className="tile-foot">
        <span className="chip">{data.mrr}</span>
        <span className={"chip " + (data.renewalDays < 15 ? "urgent" : data.renewalDays < 60 ? "warn" : "")}>
          Renews in {data.renewalDays}d
        </span>
        <span className="arr"><Icon.ArrowRight/></span>
      </div>
    </div>
  );
}

function AddTile({ onClick, label, sub }){
  return (
    <div className="tile add" onClick={onClick}>
      <div className="plus"><Icon.Plus/></div>
      <b>{label}</b>
      <span>{sub}</span>
    </div>
  );
}

Object.assign(window, {
  Icon, EditorialHeader, TopBar, KPIStrip, AgendaPanel, AlertsPanel,
  CompanyTile, AddTile, CompanyGlyph,
});

// ============================================================
// Mobile bits — useMediaQuery hook + MobileNav drawer + BottomTabBar
// ============================================================

function useMediaQuery(query){
  const [matches, setMatches] = React.useState(() => {
    if (typeof window === "undefined" || !window.matchMedia) return false;
    return window.matchMedia(query).matches;
  });
  React.useEffect(() => {
    if (!window.matchMedia) return;
    const mql = window.matchMedia(query);
    const onChange = () => setMatches(mql.matches);
    if (mql.addEventListener) mql.addEventListener("change", onChange);
    else mql.addListener(onChange); // older Safari
    return () => {
      if (mql.removeEventListener) mql.removeEventListener("change", onChange);
      else mql.removeListener(onChange);
    };
  }, [query]);
  return matches;
}

// Sections rendered as nav items. `id` matches the section's HTML id attribute.
const NAV_SECTIONS = [
  { id: "kpis",         label: "KPIs",       icon: "📊" },
  { id: "finance",      label: "Finance",    icon: "₪"  },
  { id: "attention",    label: "Attention",  icon: "!"  },
  { id: "gantt",        label: "Roadmap",    icon: "▦"  },
  { id: "md-services",  label: "MD",         icon: "♥"  },
  { id: "management",   label: "Mgmt",       icon: "★"  },
  { id: "new-business", label: "Pipeline",   icon: "→"  },
  { id: "internal",     label: "Team",       icon: "◉"  },
];

function scrollToSection(id){
  const el = document.getElementById(id);
  if (!el) return;
  el.scrollIntoView({ behavior: "smooth", block: "start" });
}

function MobileNav({ open, onClose }){
  // Body scroll-lock + Escape close
  React.useEffect(() => {
    if (!open) return;
    const prev = document.body.style.overflow;
    document.body.style.overflow = "hidden";
    const onKey = e => { if (e.key === "Escape") onClose(); };
    window.addEventListener("keydown", onKey);
    return () => { document.body.style.overflow = prev; window.removeEventListener("keydown", onKey); };
  }, [open, onClose]);

  return (
    <React.Fragment>
      <div className={"mobile-nav-scrim " + (open ? "on" : "")} onClick={onClose}/>
      <aside className={"mobile-nav " + (open ? "on" : "")}>
        <div className="mobile-nav-head">
          <img src="assets/favicon.svg" alt="" width="36" height="36"/>
          <div>
            <div className="mono" style={{color:"var(--ink-muted)", fontSize:9, letterSpacing:".14em"}}>MEDICAL BY MOVEO</div>
            <div style={{fontFamily:"'Fraunces','Noto Sans Hebrew',serif", fontSize:18, fontWeight:500}}>Control Center</div>
          </div>
          <button className="mobile-nav-close" onClick={onClose} aria-label="Close nav">
            <Icon.Close/>
          </button>
        </div>
        <nav className="mobile-nav-list">
          {NAV_SECTIONS.map(s => (
            <button key={s.id}
                    className="mobile-nav-link"
                    onClick={() => { scrollToSection(s.id); onClose(); }}>
              <span className="mobile-nav-icon" aria-hidden="true">{s.icon}</span>
              <span>{s.label}</span>
            </button>
          ))}
        </nav>
      </aside>
    </React.Fragment>
  );
}

// Compact bottom-tab nav for thumb-reach. Shows the 5 most-used sections.
function BottomTabBar({ onOpenMenu }){
  const tabs = [
    { id: "finance",      label: "Finance",  icon: "₪" },
    { id: "attention",    label: "Today",    icon: "!" },
    { id: "gantt",        label: "Roadmap",  icon: "▦" },
    { id: "md-services",  label: "Clients",  icon: "♥" },
    { id: "_menu",        label: "More",     icon: "≡" },
  ];
  return (
    <nav className="mobile-tabbar">
      {tabs.map(t => (
        <button key={t.id}
                onClick={() => t.id === "_menu" ? onOpenMenu() : scrollToSection(t.id)}>
          <span className="tab-icon" aria-hidden="true">{t.icon}</span>
          <span className="tab-label">{t.label}</span>
        </button>
      ))}
    </nav>
  );
}

Object.assign(window, { useMediaQuery, MobileNav, BottomTabBar });
