/* ===== Reports: manager view + board panel + submit modal ===== */
const { useState: useStateR, useMemo: useMemoR, useEffect: useEffectR } = React;

function dueRuleText(s) {
  const h = `${String(s.dueHour).padStart(2,"0")}:00`;
  if (s.cadence === "daily")  return `ทุกวัน ${h} น.`;
  if (s.cadence === "weekly") return `ทุกวัน${DOW_TH[s.dueDow]} ${h} น.`;
  return `ทุกวันที่ ${s.dueDom} ของเดือน ${h} น.`;
}

function scheduleStats(s, submissions) {
  const periods = periodsFor(s).map(p => {
    const sub = submissions[subKey(s.id, p.key)];
    return { ...p, sub, status: reportStatus(p, sub) };
  });
  const due = periods.filter(p => p.status !== "pending");
  const ontime = due.filter(p => p.status === "ontime").length;
  const late   = due.filter(p => p.status === "late").length;
  const missed = due.filter(p => p.status === "missed").length;
  const pct = due.length ? Math.round((ontime / due.length) * 100) : 0;
  let streak = 0;
  for (let i = periods.length - 1; i >= 0; i--) {
    if (periods[i].status === "pending") continue;
    if (periods[i].status === "ontime") streak++; else break;
  }
  return { periods, dueCount: due.length, ontime, late, missed, pct, streak };
}

/* ---- dot strip (contribution-style) ---- */
function DotStrip({ periods, onPick }) {
  return (
    <div style={{ display: "flex", gap: 5, flexWrap: "wrap" }}>
      {periods.map(p => {
        const st = REPORT_STATUS[p.status];
        const isPending = p.status === "pending";
        const tip = `${p.label} · ${st.label}` + (p.sub ? ` (${new Date(p.sub.at).toLocaleString("th-TH",{day:"numeric",month:"short",hour:"2-digit",minute:"2-digit"})})` : "");
        return (
          <button key={p.key} title={tip} onClick={onPick ? () => onPick(p) : undefined}
            style={{
              width: 17, height: 17, borderRadius: 5, flex: "none", padding: 0,
              border: isPending ? "1.5px dashed var(--todo)" : "0",
              background: isPending ? "transparent" : st.color,
              cursor: onPick ? "pointer" : "default", transition: ".12s",
            }} />
        );
      })}
    </div>
  );
}

function MiniCount({ n, color, label }) {
  return (
    <div style={{ display: "flex", alignItems: "center", gap: 6 }}>
      <span className="dot" style={{ background: color, width: 8, height: 8 }}></span>
      <span style={{ fontFamily: "var(--font-num)", fontWeight: 700, fontSize: 14, color: "var(--ink)" }}>{n}</span>
      <span style={{ fontSize: 12, color: "var(--ink-3)" }}>{label}</span>
    </div>
  );
}

/* ===== Manager reports tab ===== */
function ReportsView({ schedules, submissions, members, onGotoBoard, onSubmitReport, onAddSchedule, onEditSchedule }) {
  const memberList = members || MEMBERS;
  const [filter, setFilter] = useStateR("all"); // member id or "all"
  const [activeSub, setActiveSub] = useStateR(null); // { schedule, period, existing }
  const rows = useMemoR(() => {
    return schedules
      .map(s => ({ s, m: MEMBER_MAP[s.owner], stats: scheduleStats(s, submissions) }))
      .filter(r => r.m) // skip schedules whose owner was deleted
      .filter(r => filter === "all" || r.s.owner === filter)
      .sort((a, b) => {
        const ai = memberList.findIndex(x => x.id === a.s.owner);
        const bi = memberList.findIndex(x => x.id === b.s.owner);
        if (ai !== bi) return ai - bi;
        return a.s.name.localeCompare(b.s.name, "th");
      });
  }, [schedules, submissions, filter, memberList]);
  const agg = useMemoR(() => {
    let ontime = 0, late = 0, missed = 0;
    rows.forEach(r => { ontime += r.stats.ontime; late += r.stats.late; missed += r.stats.missed; });
    const total = ontime + late + missed;
    return { ontime, late, missed, total, pct: total ? Math.round((ontime / total) * 100) : 0 };
  }, [rows]);

  const summary = [
    { label: "อัตราส่งตรงเวลา", value: agg.pct + "%", color: "var(--primary)", big: true },
    { label: "ส่งตรงเวลา", value: agg.ontime, color: "var(--done)" },
    { label: "ส่งช้า", value: agg.late, color: "var(--review)" },
    { label: "ขาดส่ง", value: agg.missed, color: "var(--high)" },
  ];

  return (
    <div className="animate-pop">
      <div style={rvStyles.head}>
        <div>
          <div style={rvStyles.kicker}>รายงานประจำ · Recurring reports</div>
          <h1 style={rvStyles.h1}>การส่งรายงานของทีม</h1>
          <div style={rvStyles.sub}>ติดตามว่าใครส่งตรงเวลา ส่งช้า หรือขาดส่ง — แต่ละคนตั้งความถี่ได้เอง</div>
        </div>
        <Legend />
      </div>

      <div style={rvStyles.summaryGrid} className="rv-summary">
        {summary.map(c => (
          <div key={c.label} className="card" style={rvStyles.statCard}>
            <div style={{ fontSize: 13.5, fontWeight: 600, color: "var(--ink-2)" }}>{c.label}</div>
            <div style={{ fontFamily: "var(--font-num)", fontSize: c.big ? 40 : 34, fontWeight: 700, lineHeight: 1, color: c.color, marginTop: 10 }}>{c.value}</div>
          </div>
        ))}
      </div>

      <div style={rvStyles.filterBar} className="scroll">
        <button onClick={() => setFilter("all")} style={rvStyles.chip(filter === "all")}>
          <UsersIcon /> ทั้งหมด <span style={rvStyles.chipCount(filter === "all")}>{schedules.length}</span>
        </button>
        {memberList.map(m => {
          const count = schedules.filter(s => s.owner === m.id).length;
          if (count === 0) return null;
          const on = filter === m.id;
          return (
            <button key={m.id} onClick={() => setFilter(m.id)} style={rvStyles.chip(on)}>
              <Avatar member={m} size={20} />
              <span>{m.nick}</span>
              <span style={rvStyles.chipCount(on)}>{count}</span>
            </button>
          );
        })}
      </div>

      <div className="card" style={{ padding: 0, overflow: "hidden" }}>
        <div style={rvStyles.panelHead}>
          <div style={{ display: "flex", flexDirection: "column", gap: 2 }}>
            <span style={{ fontWeight: 700, fontSize: 15.5 }}>รายงานรายคน · By person</span>
            <span style={{ fontSize: 12.5, color: "var(--ink-3)" }}>ชี้ที่จุดเพื่อดูวันที่ · คลิกชื่อเพื่อเปิดบอร์ด</span>
          </div>
          {onAddSchedule && (
            <button className="btn btn-primary" style={{ padding: "9px 14px", fontSize: 13, display: "flex", alignItems: "center", gap: 6 }} onClick={() => onAddSchedule()}>
              <PlusIcon /> เพิ่มรายงาน
            </button>
          )}
        </div>
        {rows.length === 0 && (
          <div style={{ padding: "36px 20px", textAlign: "center", color: "var(--ink-3)", fontSize: 13.5 }}>
            {filter === "all" ? "ยังไม่มีรายงานในระบบ" : "คนนี้ยังไม่มีรายงานประจำ"}
          </div>
        )}
        {rows.map(({ s, m, stats }) => (
          <div key={s.id} style={rvStyles.row} className="rv-row">
            <button className="hov-row" style={rvStyles.who} onClick={() => onGotoBoard(s.owner)}>
              <Avatar member={m} size={40} />
              <div style={{ textAlign: "left", minWidth: 0 }}>
                <div style={{ fontWeight: 600, fontSize: 14.5 }}>{m.nick} <span style={{ color: "var(--ink-3)", fontWeight: 500 }}>· {s.name}</span></div>
                <div style={{ fontSize: 12, color: "var(--ink-3)" }}>
                  <span style={rvStyles.cadenceTag}>{CADENCES[s.cadence].label}</span> {dueRuleText(s)}
                </div>
              </div>
            </button>

            <div style={rvStyles.mid}>
              <DotStrip periods={stats.periods}
                onPick={onSubmitReport ? (p) => setActiveSub({ schedule: s, period: p, existing: p.sub }) : undefined} />
              <div style={{ display: "flex", gap: 16, marginTop: 10 }}>
                <MiniCount n={stats.ontime} color="var(--done)" label="ตรงเวลา" />
                <MiniCount n={stats.late} color="var(--review)" label="ช้า" />
                <MiniCount n={stats.missed} color="var(--high)" label="ขาด" />
              </div>
            </div>

            <div style={rvStyles.right}>
              <div style={{ fontFamily: "var(--font-num)", fontSize: 26, fontWeight: 700, color: stats.pct >= 80 ? "var(--done)" : stats.pct >= 50 ? "var(--review)" : "var(--high)" }}>
                {stats.pct}<span style={{ fontSize: 14, color: "var(--ink-3)" }}>%</span>
              </div>
              {stats.streak > 0 && <div style={rvStyles.streak}>🔥 ตรงเวลา {stats.streak} รอบ</div>}
              {onEditSchedule && (
                <button className="btn btn-ghost" style={rvStyles.editBtn} title="แก้ไขรายงาน" onClick={() => onEditSchedule(s)}>
                  <PencilIcon /> แก้ไข
                </button>
              )}
            </div>
          </div>
        ))}
      </div>

      {activeSub && (
        <ReportSubmitModal {...activeSub}
          onClose={() => setActiveSub(null)}
          onSubmit={(remark, atMs) => { onSubmitReport(activeSub.schedule.id, activeSub.period.key, remark, atMs); setActiveSub(null); }} />
      )}
    </div>
  );
}

function Legend() {
  const items = [["ontime","ส่งตรงเวลา"],["late","ส่งช้า"],["missed","ขาดส่ง"],["pending","รอส่ง"]];
  return (
    <div style={{ display: "flex", gap: 14, flexWrap: "wrap", alignItems: "center" }}>
      {items.map(([k, label]) => {
        const st = REPORT_STATUS[k];
        const pending = k === "pending";
        return (
          <div key={k} style={{ display: "flex", alignItems: "center", gap: 6 }}>
            <span style={{ width: 13, height: 13, borderRadius: 4, background: pending ? "transparent" : st.color, border: pending ? "1.5px dashed var(--todo)" : "0" }}></span>
            <span style={{ fontSize: 12.5, color: "var(--ink-2)", fontWeight: 500 }}>{label}</span>
          </div>
        );
      })}
    </div>
  );
}

/* ===== Board panel: my reports to submit ===== */
function ReportPanel({ currentUser, schedules, submissions, onSubmit, onAddSchedule, onEditSchedule }) {
  const mine = schedules.filter(s => s.owner === currentUser);
  const [active, setActive] = useStateR(null); // {schedule, period}
  const showAdd = !!onAddSchedule;
  if (!mine.length && !showAdd) return null;

  return (
    <>
      <div className="card" style={rpStyles.wrap}>
        <div style={rpStyles.head}>
          <div style={{ display: "flex", flexDirection: "column", gap: 2, minWidth: 0 }}>
            <span style={{ fontWeight: 700, fontSize: 15, whiteSpace: "nowrap" }}>📋 รายงานที่ต้องส่ง</span>
            <span style={{ fontSize: 12.5, color: "var(--ink-3)" }}>กดส่งเพื่อบันทึกเวลา · ตั้งรอบส่งได้เอง</span>
          </div>
          {showAdd && (
            <button className="btn btn-primary" style={{ padding: "8px 13px", fontSize: 13, display: "flex", alignItems: "center", gap: 6 }} onClick={() => onAddSchedule(currentUser)}>
              <PlusIcon /> เพิ่มรายงาน
            </button>
          )}
        </div>
        <div style={rpStyles.list}>
          {mine.length === 0 && (
            <div style={rpStyles.emptyState}>
              <div style={{ fontSize: 14, color: "var(--ink-2)", fontWeight: 600 }}>ยังไม่มีรายงานประจำ</div>
              <div style={{ fontSize: 12.5, color: "var(--ink-3)", marginTop: 4 }}>กด “เพิ่มรายงาน” เพื่อตั้งความถี่และเวลาส่ง</div>
            </div>
          )}
          {mine.map(s => {
            const stats = scheduleStats(s, submissions);
            const cur = stats.periods[stats.periods.length - 1];
            const st = REPORT_STATUS[cur.status];
            const done = cur.status === "ontime" || cur.status === "late";
            return (
              <div key={s.id} style={rpStyles.item}>
                <div style={{ minWidth: 0, flex: 1 }}>
                  <div style={{ fontWeight: 600, fontSize: 14 }}>{s.name}</div>
                  <div style={{ fontSize: 12, color: "var(--ink-3)", marginTop: 2 }}>
                    <span style={rvStyles.cadenceTag}>{CADENCES[s.cadence].label}</span> รอบ {cur.label} · กำหนด {String(s.dueHour).padStart(2,"0")}:00 น.
                  </div>
                  <div style={{ marginTop: 9 }}>
                    <DotStrip periods={stats.periods.slice(-14)} onPick={(p) => setActive({ schedule: s, period: p, existing: p.sub })} />
                  </div>
                  <div style={{ fontSize: 11, color: "var(--ink-3)", marginTop: 5 }}>
                    คลิกจุดเพื่อแก้ไขรอบเก่า
                  </div>
                </div>
                <div style={{ display: "flex", flexDirection: "column", alignItems: "flex-end", gap: 8 }}>
                  <span className="badge" style={{ background: st.soft, color: st.color }}>
                    <span className="dot" style={{ background: st.color }}></span>{st.label}
                  </span>
                  <div style={{ display: "flex", gap: 6 }}>
                    {onEditSchedule && (
                      <button className="btn btn-ghost" style={{ padding: "8px 10px", fontSize: 12.5, display: "inline-flex", alignItems: "center", gap: 5 }} title="แก้ไขรายงาน" onClick={() => onEditSchedule(s)}>
                        <PencilIcon />
                      </button>
                    )}
                    <button className={done ? "btn btn-ghost" : "btn btn-primary"} style={{ padding: "8px 14px", fontSize: 13 }}
                      onClick={() => setActive({ schedule: s, period: cur, existing: cur.sub })}>
                      {done ? "แก้ไข / ดูโน้ต" : "ส่งรายงาน"}
                    </button>
                  </div>
                </div>
              </div>
            );
          })}
        </div>
      </div>

      {active && (
        <ReportSubmitModal {...active}
          onClose={() => setActive(null)}
          onSubmit={(remark, atMs) => { onSubmit(active.schedule.id, active.period.key, remark, atMs); setActive(null); }} />
      )}
    </>
  );
}

// แปลง ms -> "YYYY-MM-DDTHH:mm" สำหรับ datetime-local input (ใช้ local time)
function msToInputLocal(ms) {
  const d = new Date(ms);
  const pad = (n) => String(n).padStart(2, "0");
  return `${d.getFullYear()}-${pad(d.getMonth()+1)}-${pad(d.getDate())}T${pad(d.getHours())}:${pad(d.getMinutes())}`;
}
function inputLocalToMs(str) {
  return new Date(str).getTime();
}

function ReportSubmitModal({ schedule, period, existing, onClose, onSubmit }) {
  const [remark, setRemark] = useStateR(existing?.remark || "");
  // default เวลาที่ส่ง: ถ้าแก้รายการเดิม = ค่าเดิม, ถ้าใหม่ = ตอนนี้
  const [atMs, setAtMs] = useStateR(existing?.at ?? Date.now());

  useEffectR(() => {
    const onKey = (e) => { if (e.key === "Escape") onClose(); };
    window.addEventListener("keydown", onKey);
    return () => window.removeEventListener("keydown", onKey);
  }, []);

  // คำนวณสถานะ live ตาม atMs ปัจจุบัน
  const ontime = atMs <= period.dueMs;
  const willBe = ontime ? "ส่งตรงเวลา" : "ส่งช้า";
  const willColor = ontime ? "var(--done)" : "var(--review)";
  const willBg = ontime ? "var(--done-soft)" : "var(--review-soft)";

  // ขอบเขต: ไม่ก่อนรอบเริ่ม, ไม่หลังตอนนี้
  const minMs = period.date.getTime();           // วันเริ่มรอบ 00:00
  const maxMs = Date.now();                       // ไม่ใส่อนาคต
  const minStr = msToInputLocal(minMs);
  const maxStr = msToInputLocal(maxMs);

  const setPreset = (kind) => {
    if (kind === "now") setAtMs(Date.now());
    else if (kind === "due") setAtMs(period.dueMs - 30 * 60 * 1000); // 30 นาทีก่อนกำหนด
    else if (kind === "early") setAtMs(period.dueMs - 4 * 60 * 60 * 1000); // 4 ชม. ก่อนกำหนด
  };

  const handleSubmit = () => {
    let safeMs = atMs;
    if (safeMs > maxMs) safeMs = maxMs;
    if (safeMs < minMs) safeMs = minMs;
    onSubmit(remark, safeMs);
  };

  return (
    <div style={rpStyles.overlay} onMouseDown={onClose}>
      <div style={rpStyles.sheet} className="modal-sheet" onMouseDown={(e) => e.stopPropagation()}>
        <div style={{ display: "flex", justifyContent: "space-between", alignItems: "flex-start" }}>
          <div>
            <div style={rvStyles.kicker}>ส่งรายงาน · {CADENCES[schedule.cadence].label}</div>
            <div style={{ fontSize: 20, fontWeight: 700, marginTop: 4 }}>{schedule.name}</div>
            <div style={{ fontSize: 13.5, color: "var(--ink-3)", marginTop: 3 }}>รอบ {period.label} · กำหนด {dueRuleText(schedule)}</div>
          </div>
          <button style={rpStyles.x} className="tm-x" onClick={onClose}><CloseIcon /></button>
        </div>

        {/* สถานะที่จะถูกบันทึก */}
        <div style={{ ...rpStyles.note, background: willBg, color: willColor }}>
          จะบันทึกเป็น <b>"{willBe}"</b> · เวลาที่ส่ง {new Date(atMs).toLocaleString("th-TH",{day:"numeric",month:"short",hour:"2-digit",minute:"2-digit"})} น.
        </div>

        {/* เวลาที่ส่ง — ปรับย้อนหลังได้ */}
        <label style={{ display: "flex", flexDirection: "column", gap: 7, marginTop: 16 }}>
          <span style={{ fontSize: 13, fontWeight: 600, color: "var(--ink-2)" }}>
            เวลาที่ส่ง · Submitted at
            {!existing && Date.now() > period.dueMs && (
              <span style={{ marginLeft: 8, fontSize: 11.5, fontWeight: 500, color: "var(--ink-3)" }}>
                (ลืมกดส่ง? ปรับเวลาย้อนหลังได้)
              </span>
            )}
          </span>
          <input type="datetime-local"
            value={msToInputLocal(atMs)}
            min={minStr} max={maxStr}
            onChange={(e) => setAtMs(inputLocalToMs(e.target.value))}
            style={rpStyles.textarea} />
          <div style={{ display: "flex", gap: 6, flexWrap: "wrap", marginTop: 2 }}>
            <button onClick={() => setPreset("now")} style={rpPresetStyle}>ตอนนี้</button>
            <button onClick={() => setPreset("due")} style={rpPresetStyle}>ก่อนกำหนด 30 นาที</button>
            <button onClick={() => setPreset("early")} style={rpPresetStyle}>ก่อนกำหนด 4 ชม.</button>
          </div>
        </label>

        <label style={{ display: "flex", flexDirection: "column", gap: 7, marginTop: 16 }}>
          <span style={{ fontSize: 13, fontWeight: 600, color: "var(--ink-2)" }}>Remark · โน้ต (ถ้ามี)</span>
          <textarea value={remark} onChange={(e) => setRemark(e.target.value)} rows={3}
            placeholder="เช่น สรุปสั้นๆ ว่าทำอะไรไปบ้าง หรือเหตุผลที่ส่งช้า"
            style={rpStyles.textarea} />
        </label>

        <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center", gap: 10, marginTop: 18, flexWrap: "wrap" }}>
          {existing
            ? <button className="btn" style={{ background: "var(--high-soft)", color: "var(--high)", padding: "9px 13px", fontSize: 13 }}
                onClick={() => { if (confirm("ยกเลิกการส่งรายงานรอบนี้?")) onSubmit(null, null); }}>
                ยกเลิกการส่ง
              </button>
            : <span />
          }
          <div style={{ display: "flex", gap: 10, marginLeft: "auto" }}>
            <button className="btn btn-ghost" onClick={onClose}>ยกเลิก</button>
            <button className="btn btn-primary" onClick={handleSubmit}>{existing ? "บันทึก" : "ยืนยันส่งรายงาน"}</button>
          </div>
        </div>
      </div>
    </div>
  );
}

const rpPresetStyle = {
  border: "1px solid var(--line)", background: "var(--surface)",
  color: "var(--ink-2)", padding: "5px 10px", borderRadius: 8,
  fontSize: 12, fontWeight: 600, cursor: "pointer",
};

const rvStyles = {
  head: { display: "flex", alignItems: "flex-start", justifyContent: "space-between", gap: 16, flexWrap: "wrap", margin: "28px 0 22px" },
  kicker: { fontSize: 12.5, fontWeight: 700, color: "var(--primary)", letterSpacing: ".4px", textTransform: "uppercase" },
  h1: { fontSize: 26, fontWeight: 700, margin: "8px 0 8px", letterSpacing: "-.4px" },
  sub: { fontSize: 14, color: "var(--ink-3)", maxWidth: 560 },
  summaryGrid: { display: "grid", gridTemplateColumns: "repeat(4, 1fr)", gap: 16, marginBottom: 18 },
  statCard: { padding: "18px 20px" },
  panelHead: { display: "flex", alignItems: "center", justifyContent: "space-between", padding: "16px 20px", borderBottom: "1px solid var(--line-soft)" },
  row: { display: "grid", gridTemplateColumns: "minmax(200px, 1fr) minmax(220px, 1.3fr) 150px", gap: 18, alignItems: "center", padding: "16px 20px", borderBottom: "1px solid var(--line-soft)" },
  who: { display: "flex", alignItems: "center", gap: 12, border: 0, background: "transparent", padding: "6px 8px", borderRadius: 11, cursor: "pointer", textAlign: "left" },
  cadenceTag: { display: "inline-block", background: "var(--primary-soft)", color: "var(--primary)", fontWeight: 700, fontSize: 11, padding: "1px 7px", borderRadius: 6, marginRight: 5, whiteSpace: "nowrap" },
  mid: {},
  right: { display: "flex", flexDirection: "column", alignItems: "flex-end", gap: 5 },
  streak: { fontSize: 11.5, fontWeight: 600, color: "var(--ink-2)", background: "var(--review-soft)", padding: "2px 9px", borderRadius: 20, whiteSpace: "nowrap" },
  editBtn: { padding: "5px 10px", fontSize: 12, display: "inline-flex", alignItems: "center", gap: 5, color: "var(--ink-2)" },
  filterBar: {
    display: "flex", gap: 8, overflowX: "auto", padding: "2px 2px 14px",
    marginBottom: 4, scrollbarWidth: "thin",
  },
  chip: (on) => ({
    display: "inline-flex", alignItems: "center", gap: 7, whiteSpace: "nowrap",
    padding: "7px 12px", borderRadius: 22, fontSize: 13, fontWeight: 600,
    border: "1.5px solid " + (on ? "var(--primary)" : "var(--line)"),
    background: on ? "var(--primary)" : "var(--surface)",
    color: on ? "#fff" : "var(--ink-2)",
    cursor: "pointer", transition: ".12s", boxShadow: on ? "0 4px 12px rgba(47,107,255,.28)" : "var(--shadow-sm)",
    flex: "none",
  }),
  chipCount: (on) => ({
    fontFamily: "var(--font-num)", fontSize: 11.5, fontWeight: 700,
    background: on ? "rgba(255,255,255,.25)" : "var(--surface-soft)",
    color: on ? "#fff" : "var(--ink-2)",
    padding: "1px 7px", borderRadius: 20,
  }),
};

const rpStyles = {
  wrap: { padding: 0, overflow: "hidden", marginBottom: 18 },
  head: { display: "flex", alignItems: "center", justifyContent: "space-between", padding: "14px 18px", borderBottom: "1px solid var(--line-soft)", background: "var(--surface-soft)" },
  list: { display: "grid", gridTemplateColumns: "repeat(auto-fit, minmax(340px, 1fr))", gap: 0 },
  item: { display: "flex", gap: 14, padding: "15px 18px", borderTop: "1px solid var(--line-soft)" },
  emptyState: { padding: "22px 18px", textAlign: "center", borderTop: "1px solid var(--line-soft)" },
  overlay: { position: "fixed", inset: 0, zIndex: 100, background: "rgba(20,30,55,.42)", backdropFilter: "blur(4px)", display: "grid", placeItems: "center", padding: 20, animation: "overlayIn .2s ease both" },
  sheet: { width: "min(500px, 100%)", background: "var(--surface)", borderRadius: 22, boxShadow: "var(--shadow-pop)", padding: "24px 26px 26px", animation: "sheetIn .3s cubic-bezier(.2,.7,.3,1) both" },
  x: { width: 36, height: 36, borderRadius: 10, border: "1px solid var(--line)", background: "var(--surface)", color: "var(--ink-2)", display: "grid", placeItems: "center" },
  note: { marginTop: 16, padding: "11px 14px", borderRadius: 12, fontSize: 13.5, fontWeight: 500, lineHeight: 1.5 },
  textarea: { border: "1.5px solid var(--line)", borderRadius: 11, padding: "11px 13px", fontSize: 14.5, color: "var(--ink)", outline: "none", resize: "vertical", lineHeight: 1.5 },
};

Object.assign(window, { ReportsView, ReportPanel });
