// screen-home.jsx — Unified home (list + goals modes).
// • Top: settings gear + small lock indicator
// • Then: horizontal swipeable segment bar (pull-down replaced)
// • Body: task list with type-aware rows
// • Bottom: List ⇄ Goals toggle, floating + add button

const { useState: useStateH, useEffect: useEffectH } = React;

function ScreenHome({ state, onCheck, onStartTask, onOpenSettings }) {
  const {
    tasks,
    categories,
    mode,
    setMode,
    listCat,
    setListCat,
    goalAxis,
    setGoalAxis,
    goalSubCats = {},
    setGoalSubCats,
    addTask,
  } = state;

  const isList = mode === "list";
  const lang = (typeof window !== "undefined" && window.__witnessLang) || "en";

  // ───────── Add task sheet ─────────
  const [addOpen, setAddOpen] = useStateH(false);

  // ───────── Task detail sheet ─────────
  const [detailTask, setDetailTask] = useStateH(null);

  // ───────── Drawer state ─────────
  const [sheetOpen, setSheetOpen] = useStateH(false);
  const [extraCats, setExtraCats] = useStateH([]);

  // ───────── Goal sub-tabs ─────────
  // "__unsorted__" is a virtual sub-tab always pinned last; matches tasks with no subCategory
  const UNSORTED_SUB = { id: "__unsorted__", label: { en: "Unsorted", zh: "未分類" } };
  const currentAxisSubs = [...(goalSubCats[goalAxis] || []), UNSORTED_SUB];
  const [goalSub, setGoalSub] = useStateH(currentAxisSubs[0].id);
  useEffectH(() => {
    const subs = [...(goalSubCats[goalAxis] || []), UNSORTED_SUB];
    setGoalSub(subs[0].id);
  }, [goalAxis]);
  const allCategories = [...categories, ...extraCats];

  // ───────── Top-level list views (drawer) ─────────
  // listCat switches between these top-level views
  const listViews = [
    { id: "today", label: t("cat_today"), icon: "today" },
    { id: "inbox", label: t("cat_inbox"), icon: "inbox" },
    { id: "abandoned", label: t("cat_abandoned"), icon: "abandoned" },
  ];

  // ───────── Sub-tabs — only inside 'today' view ─────────
  const [listSub, setListSub] = useStateH("today");
  const todaySubTabs = [
    { id: "overdue", label: t("cat_overdue") },
    { id: "today", label: t("cat_today") },
  ];

  // ───────── Visible tasks ─────────
  let visibleTasks;
  if (!isList) {
    const catTasks = tasks.filter((x) => x.category === goalAxis);
    visibleTasks = goalSub === "__unsorted__"
      ? catTasks.filter((x) => !x.subCategory)
      : goalSub
        ? catTasks.filter((x) => x.subCategory === goalSub)
        : catTasks;
  } else if (listCat === "today") {
    visibleTasks =
      listSub === "overdue"
        ? tasks.filter((x) => x.day === "overdue")
        : tasks.filter((x) => x.day === "today");
  } else if (listCat === "inbox") {
    visibleTasks = tasks.filter((x) => !x.abandoned);
  } else if (listCat === "abandoned") {
    visibleTasks = tasks.filter((x) => x.abandoned === true);
  } else {
    visibleTasks = [];
  }

  // ───────── Drawer items with counts ─────────
  const listDrawerItems = listViews.map((v) => ({
    ...v,
    count:
      v.id === "today"
        ? tasks.filter((x) => x.day === "today" || x.day === "overdue").length
        : v.id === "inbox"
          ? tasks.filter((x) => !x.abandoned).length
          : tasks.filter((x) => x.abandoned).length,
  }));
  const goalDrawerItems = [
    ...allCategories.filter((cat) => cat.id !== "unsorted"),
    ...allCategories.filter((cat) => cat.id === "unsorted"),
  ].map((cat) => ({
    id: cat.id,
    label:
      typeof cat.label === "object"
        ? cat.label[lang] || cat.label.en
        : cat.label,
    icon: "axis",
    count: tasks.filter((x) => x.category === cat.id).length,
  }));

  const handleAddGoalSub = () => {
    const name = window.prompt(lang === "zh" ? "新增分類名稱：" : "New filter name:");
    if (name && name.trim() && setGoalSubCats) {
      const newSub = { id: `sub-${Date.now()}`, label: { en: name.trim(), zh: name.trim() } };
      setGoalSubCats((prev) => ({
        ...prev,
        [goalAxis]: [...(prev[goalAxis] || []), newSub],
      }));
      setGoalSub(newSub.id);
    }
  };

  const handleAddCategory = () => {
    const name = window.prompt(
      lang === "zh" ? "新增主題名稱：" : "New axis name:",
    );
    if (name && name.trim()) {
      setExtraCats((prev) => [
        ...prev,
        {
          id: `cat-${Date.now()}`,
          label: { en: name.trim(), zh: name.trim() },
        },
      ]);
    }
  };

  // ───────── Lock indicator ─────────
  const total = visibleTasks.length;
  const completed = visibleTasks.filter(
    (x) => x.done || isAllSubDone(x),
  ).length;
  const lockReleased = total > 0 && completed === total;

  // current view label for header
  const currentGoalCat = allCategories.find((c) => c.id === goalAxis) || allCategories[0];
  const currentViewLabel = isList
    ? (listViews.find((v) => v.id === listCat) || listViews[0]).label
    : currentGoalCat
      ? (typeof currentGoalCat.label === "object"
          ? currentGoalCat.label[lang] || currentGoalCat.label.en
          : currentGoalCat.label)
      : t("mode_goals");

  return (
    <div
      style={{
        width: "100%",
        height: "100%",
        background: `radial-gradient(140% 80% at 50% -10%, #16171a 0%, ${W.ink} 55%, ${W.void} 100%)`,
        color: W.textHi,
        display: "flex",
        flexDirection: "column",
        fontFamily: W.mono,
        position: "relative",
        overflow: "hidden",
      }}
    >
      <WStatusBar time="04:41" />

      {/* Top header — hamburger | title | lock */}
      <div
        style={{
          padding: "4px 18px 10px",
          display: "flex",
          alignItems: "center",
          justifyContent: "space-between",
        }}
      >
        <button
          onClick={() => setSheetOpen(true)}
          style={{
            width: 36, height: 36,
            border: "0.5px solid rgba(255,255,255,0.12)",
            borderRadius: 9999, background: "rgba(255,255,255,0.04)",
            cursor: "pointer", display: "flex", alignItems: "center",
            justifyContent: "center", color: W.text, flexShrink: 0,
          }}
        >
          <svg width="16" height="12" viewBox="0 0 16 12" fill="none">
            <line x1="0" y1="1" x2="16" y2="1" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round"/>
            <line x1="0" y1="6" x2="16" y2="6" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round"/>
            <line x1="0" y1="11" x2="16" y2="11" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round"/>
          </svg>
        </button>
        <span style={{ fontFamily: W.display, fontSize: 17, fontWeight: 600, color: W.textHi, letterSpacing: "-0.005em" }}>
          {currentViewLabel}
        </span>
        <button
          onClick={onOpenSettings}
          style={{
            width: 36, height: 36,
            border: "0.5px solid rgba(255,255,255,0.12)",
            borderRadius: 9999, background: "rgba(255,255,255,0.04)",
            cursor: "pointer", display: "flex", alignItems: "center",
            justifyContent: "center", color: "rgba(232,230,224,0.5)",
            flexShrink: 0, transition: "color .2s",
          }}
          onMouseEnter={(e) => (e.currentTarget.style.color = W.textHi)}
          onMouseLeave={(e) => (e.currentTarget.style.color = "rgba(232,230,224,0.5)")}
        >
          <svg width="14" height="16" viewBox="0 0 14 16" fill="none">
            <rect x="1" y="7" width="12" height="8.5" rx="2" stroke="currentColor" strokeWidth="1.3" fill="none"/>
            <path d="M3.5 7V4.5A3.5 3.5 0 0110.5 4.5V7" stroke="currentColor" strokeWidth="1.3" fill="none" strokeLinecap="round"/>
          </svg>
        </button>
      </div>

      {/* Goal sub-tabs — visible in goal mode */}
      {!isList && (
        <div
          style={{
            display: "flex",
            alignItems: "center",
            gap: 22,
            padding: "10px 22px 2px",
            overflowX: "auto",
            WebkitOverflowScrolling: "touch",
          }}
        >
          {currentAxisSubs.map((sub) => {
            const on = goalSub === sub.id;
            const label =
              typeof sub.label === "object"
                ? sub.label[lang] || sub.label.en
                : sub.label;
            return (
              <button
                key={sub.id}
                onClick={() => setGoalSub(sub.id)}
                style={{
                  padding: "4px 0 8px",
                  border: 0,
                  cursor: "pointer",
                  background: "transparent",
                  fontFamily: W.display,
                  fontSize: 14,
                  fontWeight: on ? 600 : 400,
                  color: on ? W.textHi : "rgba(232,230,224,0.38)",
                  transition: "color .2s",
                  display: "inline-flex",
                  flexDirection: "column",
                  alignItems: "center",
                  gap: 4,
                  flexShrink: 0,
                }}
              >
                <span>{label}</span>
                <div
                  style={{
                    width: 4,
                    height: 4,
                    borderRadius: 9999,
                    background: on ? W.accentHi : "transparent",
                    transition: "background .2s",
                  }}
                />
              </button>
            );
          })}
          {/* Add sub-category button */}
          <button
            onClick={handleAddGoalSub}
            style={{
              padding: "4px 0 8px",
              border: 0,
              cursor: "pointer",
              background: "transparent",
              color: "rgba(232,230,224,0.22)",
              display: "inline-flex",
              flexDirection: "column",
              alignItems: "center",
              gap: 4,
              flexShrink: 0,
              transition: "color .2s",
            }}
            onMouseEnter={(e) => (e.currentTarget.style.color = "rgba(232,230,224,0.55)")}
            onMouseLeave={(e) => (e.currentTarget.style.color = "rgba(232,230,224,0.22)")}
          >
            <svg width="14" height="14" viewBox="0 0 14 14" fill="none">
              <line x1="7" y1="2" x2="7" y2="12" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round"/>
              <line x1="2" y1="7" x2="12" y2="7" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round"/>
            </svg>
            <div style={{ width: 4, height: 4 }} />
          </button>
        </div>
      )}

      {/* Sub-tabs — 已過期 / 今天, only visible inside 'today' top-level view */}
      {isList && listCat === "today" && (
        <div
          style={{
            display: "flex",
            alignItems: "center",
            gap: 22,
            padding: "10px 22px 2px",
          }}
        >
          {todaySubTabs.map((s) => {
            const on = listSub === s.id;
            return (
              <button
                key={s.id}
                onClick={() => setListSub(s.id)}
                style={{
                  padding: "4px 0 8px",
                  border: 0,
                  cursor: "pointer",
                  background: "transparent",
                  fontFamily: W.display,
                  fontSize: 14,
                  fontWeight: on ? 600 : 400,
                  color: on ? W.textHi : "rgba(232,230,224,0.38)",
                  transition: "color .2s",
                  display: "inline-flex",
                  flexDirection: "column",
                  alignItems: "center",
                  gap: 4,
                }}
              >
                <span>{s.label}</span>
                <div
                  style={{
                    width: 4,
                    height: 4,
                    borderRadius: 9999,
                    background: on ? W.accentHi : "transparent",
                    transition: "background .2s",
                  }}
                />
              </button>
            );
          })}
        </div>
      )}

      {/* Task list */}
      <TaskListBody
        visibleTasks={visibleTasks}
        onCheck={onCheck}
        onStartTask={(id) => setDetailTask(tasks.find(t => t.id === id) || null)}
        groupByTime={!isList || listCat === "inbox"}
        inboxMode={isList && listCat === "inbox"}
      />

      {/* Floating add button — filled accent */}
      <button
        style={{
          position: "absolute",
          right: 22,
          bottom: 102,
          zIndex: 4,
          width: 48,
          height: 48,
          borderRadius: 9999,
          cursor: "pointer",
          background: W.accentHi,
          border: "none",
          boxShadow: `0 8px 24px rgba(0,0,0,0.5)`,
          color: W.onAccent,
          display: "flex",
          alignItems: "center",
          justifyContent: "center",
          transition: "filter .25s",
        }}
        onClick={() => setAddOpen(true)}
        onMouseEnter={(e) =>
          (e.currentTarget.style.filter = "brightness(1.15)")
        }
        onMouseLeave={(e) => (e.currentTarget.style.filter = "none")}
      >
        <svg width="16" height="16" viewBox="0 0 20 20" fill="none">
          <line
            x1="10"
            y1="4"
            x2="10"
            y2="16"
            stroke="currentColor"
            strokeWidth="2"
            strokeLinecap="round"
          />
          <line
            x1="4"
            y1="10"
            x2="16"
            y2="10"
            stroke="currentColor"
            strokeWidth="2"
            strokeLinecap="round"
          />
        </svg>
      </button>

      <TaskDetailSheet
        task={detailTask}
        open={!!detailTask}
        onClose={() => setDetailTask(null)}
        onStartTask={(id) => { setDetailTask(null); onStartTask(id); }}
        onCheck={onCheck}
        categories={allCategories}
        lang={lang}
      />

      <AddTaskSheet
        open={addOpen}
        onClose={() => setAddOpen(false)}
        onConfirm={(task) => addTask && addTask(task)}
        categories={allCategories}
        goalSubCats={goalSubCats}
        initialCategory={!isList ? goalAxis : (allCategories.find(c => c.id !== "unsorted") || allCategories[0] || {}).id}
        initialGoalSub={!isList ? goalSub : null}
        tasks={tasks}
      />

      <SideDrawer
        open={sheetOpen}
        onClose={() => setSheetOpen(false)}
        items={isList ? listDrawerItems : goalDrawerItems}
        activeId={isList ? listCat : goalAxis}
        onPick={(id) => {
          isList ? setListCat(id) : setGoalAxis(id);
        }}
        showAdd={!isList}
        onAdd={handleAddCategory}
      />

      <WModeToggle mode={mode} onChange={setMode} onSettings={onOpenSettings} />
    </div>
  );
}

// ─────────────────────────────────────────────────────────────
// ─────────────────────────────────────────────────────────────
// SideDrawer — TickTick-style left drawer.
// Dark warm background, amber icons, count right-aligned, warm highlight on active.
function SideDrawer({
  open,
  onClose,
  items,
  activeId,
  onPick,
  showAdd,
  onAdd,
}) {
  const DRAWER_BG = "#0c0c0e";
  const ACTIVE_ROW = "rgba(255,255,255,0.055)";
  const TEXT_HI = W.textHi;
  const TEXT_LO = "rgba(232,228,218,0.32)";

  return (
    <div
      style={{
        position: "absolute",
        inset: 0,
        zIndex: 30,
        pointerEvents: open ? "auto" : "none",
      }}
    >
      {/* Scrim */}
      <div
        onClick={onClose}
        style={{
          position: "absolute",
          inset: 0,
          background: "rgba(0,0,0,0.6)",
          opacity: open ? 1 : 0,
          transition: "opacity .28s",
        }}
      />

      {/* Drawer panel */}
      <div
        style={{
          position: "absolute",
          top: 0,
          left: 0,
          bottom: 0,
          width: "82%",
          background: DRAWER_BG,
          borderTopRightRadius: 16,
          borderBottomRightRadius: 16,
          boxShadow:
            "1px 0 0 rgba(255,255,255,0.06), 12px 0 40px rgba(0,0,0,0.8)",
          transform: open ? "translateX(0)" : "translateX(-100%)",
          transition: "transform .3s cubic-bezier(.2,.85,.3,1)",
          display: "flex",
          flexDirection: "column",
        }}
      >
        {/* ── Header: real photo avatar + name ── */}
        <div
          style={{
            padding: "54px 20px 18px",
            display: "flex",
            alignItems: "center",
            gap: 14,
            borderBottom: "0.5px solid rgba(255,255,255,0.07)",
          }}
        >
          <div
            style={{
              width: 44,
              height: 44,
              borderRadius: 9999,
              flexShrink: 0,
              overflow: "hidden",
              border: "1.5px solid rgba(255,255,255,0.12)",
              background: "#1a1a1e",
            }}
          >
            <img
              src="https://i.pravatar.cc/44?img=12"
              width="44"
              height="44"
              style={{
                display: "block",
                width: "100%",
                height: "100%",
                objectFit: "cover",
              }}
              onError={(e) => {
                e.target.style.display = "none";
                e.target.parentNode.innerHTML = `<svg width="44" height="44" viewBox="0 0 44 44" fill="none"><circle cx="22" cy="18" r="8" fill="rgba(232,228,218,0.35)"/><ellipse cx="22" cy="36" rx="14" ry="9" fill="rgba(232,228,218,0.25)"/></svg>`;
              }}
            />
          </div>
          <span
            style={{
              fontFamily: W.display,
              fontSize: 17,
              fontWeight: 600,
              color: TEXT_HI,
              flex: 1,
              letterSpacing: "-0.01em",
            }}
          >
            WITNESS
          </span>
        </div>

        {/* ── Item list ── */}
        <div style={{ flex: 1, overflowY: "auto", padding: "8px 0" }}>
          {items.map((item) => {
            const on = activeId === item.id;
            return (
              <button
                key={item.id}
                onClick={() => {
                  onPick && onPick(item.id);
                  onClose();
                }}
                style={{
                  width: "100%",
                  display: "flex",
                  alignItems: "center",
                  gap: 14,
                  padding: "0 12px",
                  height: 52,
                  border: 0,
                  cursor: "pointer",
                  background: on ? ACTIVE_ROW : "transparent",
                  borderRadius: 10,
                  transition: "background .15s",
                  boxSizing: "border-box",
                }}
              >
                {/* Icon — same circle style as footer */}
                <div
                  style={{
                    width: 36,
                    height: 36,
                    flexShrink: 0,
                    borderRadius: 9999,
                    background: on ? "rgba(0,0,0,0.32)" : "transparent",
                    display: "flex",
                    alignItems: "center",
                    justifyContent: "center",
                    color: on ? W.accentHi : "rgba(232,228,218,0.28)",
                    transition: "background .2s, color .2s",
                  }}
                >
                  <DrawerItemIcon type={item.icon} />
                </div>
                {/* Label */}
                <span
                  style={{
                    flex: 1,
                    fontFamily: W.display,
                    fontSize: 15,
                    fontWeight: on ? 600 : 400,
                    color: on ? TEXT_HI : "rgba(232,228,218,0.6)",
                    letterSpacing: "-0.005em",
                    textAlign: "left",
                  }}
                >
                  {item.label}
                </span>
                {/* Count */}
                {item.count > 0 && (
                  <span
                    style={{
                      fontFamily: W.mono,
                      fontSize: 13,
                      color: on ? W.accentHi : TEXT_LO,
                      fontVariantNumeric: "tabular-nums",
                    }}
                  >
                    {item.count}
                  </span>
                )}
              </button>
            );
          })}
        </div>

        {/* ── Footer: 新增主題 (goals mode only) ── */}
        {showAdd && (
          <div
            style={{
              padding: "14px 20px 36px",
              borderTop: "0.5px solid rgba(255,255,255,0.06)",
            }}
          >
            <button
              onClick={onAdd}
              style={{
                display: "flex",
                alignItems: "center",
                gap: 10,
                border: 0,
                background: "transparent",
                cursor: "pointer",
                padding: "8px 0",
              }}
            >
              <svg width="18" height="18" viewBox="0 0 18 18" fill="none" style={{ color: 'rgba(232,228,218,0.45)', flexShrink: 0 }}>
                <rect x="1" y="1" width="16" height="16" rx="4" stroke="currentColor" strokeWidth="1.4"/>
                <line x1="9" y1="5" x2="9" y2="13" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round"/>
                <line x1="5" y1="9" x2="13" y2="9" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round"/>
              </svg>
              <span
                style={{
                  fontFamily: W.display,
                  fontSize: 16,
                  fontWeight: 400,
                  color: "rgba(232,228,218,0.6)",
                }}
              >
                {t("add_category")}
              </span>
            </button>
          </div>
        )}
      </div>
    </div>
  );
}

function DrawerItemIcon({ type }) {
  if (type === "today")
    return (
      <svg width="18" height="18" viewBox="0 0 18 18" fill="none">
        <rect
          x="2"
          y="3"
          width="14"
          height="13"
          rx="2.5"
          stroke="currentColor"
          strokeWidth="1.4"
        />
        <line
          x1="6"
          y1="1.5"
          x2="6"
          y2="5"
          stroke="currentColor"
          strokeWidth="1.4"
          strokeLinecap="round"
        />
        <line
          x1="12"
          y1="1.5"
          x2="12"
          y2="5"
          stroke="currentColor"
          strokeWidth="1.4"
          strokeLinecap="round"
        />
        <line
          x1="2"
          y1="8"
          x2="16"
          y2="8"
          stroke="currentColor"
          strokeWidth="1.1"
          strokeLinecap="round"
        />
      </svg>
    );
  if (type === "inbox")
    return (
      <svg width="18" height="18" viewBox="0 0 18 18" fill="none">
        <rect
          x="2"
          y="8"
          width="14"
          height="8"
          rx="2"
          stroke="currentColor"
          strokeWidth="1.4"
        />
        <path
          d="M2 8l3-5h8l3 5"
          stroke="currentColor"
          strokeWidth="1.4"
          strokeLinecap="round"
          strokeLinejoin="round"
        />
        <line
          x1="6"
          y1="12"
          x2="12"
          y2="12"
          stroke="currentColor"
          strokeWidth="1.2"
          strokeLinecap="round"
        />
      </svg>
    );
  if (type === "abandoned")
    return (
      <svg width="18" height="18" viewBox="0 0 18 18" fill="none">
        <circle cx="9" cy="9" r="7" stroke="currentColor" strokeWidth="1.4" />
        <line
          x1="5.5"
          y1="5.5"
          x2="12.5"
          y2="12.5"
          stroke="currentColor"
          strokeWidth="1.4"
          strokeLinecap="round"
        />
      </svg>
    );
  return (
    <svg width="18" height="18" viewBox="0 0 18 18" fill="none">
      <circle cx="9" cy="9" r="7" stroke="currentColor" strokeWidth="1.4" />
      <circle cx="9" cy="9" r="3" stroke="currentColor" strokeWidth="1.2" />
      <circle cx="9" cy="9" r="1" fill="currentColor" />
    </svg>
  );
}

// ─────────────────────────────────────────────────────────────
// Task list body — splits tasks into Incomplete / Completed sections.
function TaskListBody({ visibleTasks, onCheck, onStartTask, groupByTime = false, inboxMode = false }) {
  const [completedOpen, setCompletedOpen] = useStateH(true);

  const isTaskDone = (task) =>
    task.done ||
    isAllSubDone(task) ||
    (task.type === "C" &&
      task.progress !== undefined &&
      task.progress >= 0.999);

  const incomplete = visibleTasks.filter((t) => !isTaskDone(t));
  const completed = visibleTasks.filter((t) => isTaskDone(t));

  const renderTask = (task, dimCheck = false, defaultOpen = true) => (
    <TaskCard
      key={task.id}
      task={task}
      dimCheck={dimCheck}
      defaultOpen={defaultOpen}
      onCheck={() => onCheck(task.id)}
      onTap={() => onStartTask(task.id)}
      onCheckSub={(sid) => onCheck(`${task.id}/${sid}`)}
    />
  );

  if (groupByTime) {
    return (
      <TaskListBodyGrouped
        visibleTasks={visibleTasks}
        isTaskDone={isTaskDone}
        renderTask={renderTask}
        inboxMode={inboxMode}
      />
    );
  }

  if (visibleTasks.length === 0) {
    return (
      <div
        data-scroll
        style={{
          flex: 1,
          overflowY: "auto",
          WebkitOverflowScrolling: "touch",
          padding: "4px 16px 24px",
        }}
      >
        <div style={{ padding: "32px 18px", textAlign: "center" }}>
          <SerialNum style={{ color: W.textXLo }}>{t("empty_list")}</SerialNum>
        </div>
      </div>
    );
  }

  return (
    <div
      data-scroll
      style={{
        flex: 1,
        overflowY: "auto",
        WebkitOverflowScrolling: "touch",
        padding: "14px 16px 24px",
      }}
    >
      {/* Incomplete section — no header, tasks listed directly */}
      {incomplete.length > 0 && (
        <div style={{ marginBottom: completed.length > 0 ? 20 : 0 }}>
          <div style={{ display: "flex", flexDirection: "column", gap: 10 }}>
            {incomplete.map(renderTask)}
          </div>
        </div>
      )}

      {/* Completed section */}
      {completed.length > 0 && (
        <div>
          <SectionHeader
            label={t("section_complete")}
            count={completed.length}
            open={completedOpen}
            onToggle={() => setCompletedOpen((o) => !o)}
          />
          {completedOpen && (
            <div
              style={{
                display: "flex",
                flexDirection: "column",
                gap: 10,
                marginTop: 8,
              }}
            >
              {completed.map((t) => renderTask(t, true))}
            </div>
          )}
        </div>
      )}
    </div>
  );
}

// ─────────────────────────────────────────────────────────────
// Goal mode — groups tasks by time period: 已過期 / 今天 / 未來 / 已完成
function TaskListBodyGrouped({ visibleTasks, isTaskDone, renderTask, inboxMode = false }) {
  const [overdueOpen, setOverdueOpen] = useStateH(true);
  const [todayOpen, setTodayOpen] = useStateH(true);
  const [futureOpen, setFutureOpen] = useStateH(true);
  const [completedOpen, setCompletedOpen] = useStateH(false);

  const undone = visibleTasks.filter((t) => !isTaskDone(t));
  const overdue = undone.filter((t) => t.day === "overdue");
  const today   = undone.filter((t) => t.day === "today");
  const future  = undone.filter((t) => t.day !== "overdue" && t.day !== "today");
  const completed = visibleTasks.filter((t) => isTaskDone(t));

  const scrollStyle = {
    flex: 1, overflowY: "auto", WebkitOverflowScrolling: "touch",
    padding: "4px 16px 24px",
  };

  if (visibleTasks.length === 0) {
    return (
      <div data-scroll style={scrollStyle}>
        <div style={{ padding: "32px 18px", textAlign: "center" }}>
          <SerialNum style={{ color: W.textXLo }}>{t("empty_list")}</SerialNum>
        </div>
      </div>
    );
  }

  const TimeGroup = ({ label, tasks, open, onToggle, isOverdue, taskDefaultOpen = false }) => {
    if (tasks.length === 0) return null;
    return (
      <div style={{ marginBottom: 6 }}>
        <button
          onClick={onToggle}
          style={{
            display: "flex", alignItems: "center",
            background: "transparent", border: "none", cursor: "pointer",
            padding: "10px 2px 10px", width: "100%", textAlign: "left",
          }}
        >
          <span style={{
            fontFamily: W.display, fontSize: 15, fontWeight: 600,
            color: W.textHi, letterSpacing: "-0.005em", flex: 1,
          }}>{label}</span>
          {isOverdue && (
            <span style={{
              fontFamily: W.mono, fontSize: 11, fontWeight: 500,
              color: W.accentHi, border: `0.5px solid ${W.accentHi}`,
              borderRadius: 4, padding: "1px 5px", marginRight: 8,
              letterSpacing: "0.03em",
            }}>延期</span>
          )}
          <span style={{
            fontFamily: W.mono, fontSize: 13,
            color: "rgba(232,230,224,0.38)", marginRight: 6,
            letterSpacing: "0.04em",
          }}>{tasks.length}</span>
          <svg width="7" height="11" viewBox="0 0 7 11"
            style={{
              color: "rgba(232,230,224,0.3)",
              transform: open ? "rotate(90deg)" : "none",
              transition: "transform .2s", flexShrink: 0,
            }}
          >
            <path d="M1 1L5.5 5.5 1 10" stroke="currentColor" strokeWidth="1.4" fill="none" strokeLinecap="round"/>
          </svg>
        </button>
        {open && (
          <div style={{ display: "flex", flexDirection: "column", gap: 10, paddingBottom: 10 }}>
            {tasks.map((task) => renderTask(task, false, taskDefaultOpen))}
          </div>
        )}
      </div>
    );
  };

  return (
    <div data-scroll style={scrollStyle}>
      {inboxMode ? (
        <>
          <TimeGroup label={t("section_overdue")}  tasks={overdue}   open={overdueOpen}   onToggle={() => setOverdueOpen(o => !o)}   isOverdue taskDefaultOpen={false} />
          <TimeGroup label={t("section_today")}    tasks={today}     open={todayOpen}     onToggle={() => setTodayOpen(o => !o)}    taskDefaultOpen={false} />
          <TimeGroup label={t("section_future")}   tasks={future}    open={futureOpen}    onToggle={() => setFutureOpen(o => !o)}    taskDefaultOpen={false} />
          <TimeGroup label={t("section_complete")} tasks={completed} open={completedOpen} onToggle={() => setCompletedOpen(o => !o)} taskDefaultOpen={false} />
        </>
      ) : (
        <>
          <TimeGroup label={t("section_today")}    tasks={today}     open={todayOpen}     onToggle={() => setTodayOpen(o => !o)}    taskDefaultOpen={true} />
          <TimeGroup label={t("section_overdue")}  tasks={overdue}   open={overdueOpen}   onToggle={() => setOverdueOpen(o => !o)}   isOverdue taskDefaultOpen={false} />
          <TimeGroup label={t("section_future")}   tasks={future}    open={futureOpen}    onToggle={() => setFutureOpen(o => !o)}    taskDefaultOpen={false} />
          <TimeGroup label={t("section_complete")} tasks={completed} open={completedOpen} onToggle={() => setCompletedOpen(o => !o)} taskDefaultOpen={false} />
        </>
      )}
    </div>
  );
}

function SectionHeader({ label, count, open, onToggle }) {
  return (
    <button
      onClick={onToggle}
      style={{
        display: "flex",
        alignItems: "center",
        gap: 8,
        background: "transparent",
        border: "none",
        cursor: onToggle ? "pointer" : "default",
        padding: "2px 4px 6px",
        width: "100%",
        textAlign: "left",
      }}
    >
      <span
        style={{
          fontFamily: W.display,
          fontSize: 13,
          fontWeight: 600,
          color: "rgba(232,230,224,0.65)",
          letterSpacing: "0.01em",
        }}
      >
        {label}
      </span>
      <span
        style={{
          fontFamily: W.mono,
          fontSize: 12,
          color: "rgba(232,230,224,0.35)",
          letterSpacing: "0.04em",
        }}
      >
        {count}
      </span>
      {onToggle && (
        <svg
          width="10"
          height="6"
          viewBox="0 0 10 6"
          style={{
            marginLeft: 2,
            color: "rgba(232,230,224,0.4)",
            transform: open ? "none" : "rotate(-90deg)",
            transition: "transform .2s",
            flexShrink: 0,
          }}
        >
          <path
            d="M1 1L5 5 9 1"
            stroke="currentColor"
            strokeWidth="1.3"
            fill="none"
            strokeLinecap="round"
          />
        </svg>
      )}
    </button>
  );
}

// ─────────────────────────────────────────────────────────────
// Helper: is every subtask of a B/C task done?
function isAllSubDone(task) {
  if (!task.subtasks || task.subtasks.length === 0) return false;
  return task.subtasks.every((s) => s.done || isAllSubDone(s));
}
function subProgress(task) {
  if (!task.subtasks || task.subtasks.length === 0) return task.progress || 0;
  const done = task.subtasks.filter((s) => s.done || isAllSubDone(s)).length;
  return done / task.subtasks.length;
}

// ─────────────────────────────────────────────────────────────
// Task card — dispatches by type.
//   A — simple: flat row, checkbox + title + date
//   B — subtasks container: list-icon + title + chevron, expanded subtasks below
//   C — many-items container: list-icon + title + pie chart (no inline subtasks)
//   D — type B containing C-type subtasks (rendered naturally)
function TaskCard({
  task,
  onCheck,
  onTap,
  onCheckSub,
  dimCheck = false,
  defaultOpen = true,
  depth = 0,
}) {
  const tp = task.type || "A";
  if (tp === "A")
    return (
      <TaskRowA
        task={task}
        onCheck={onCheck}
        onTap={onTap}
        dimCheck={dimCheck}
        depth={depth}
      />
    );
  if (tp === "C") return <TaskRowC task={task} onTap={onTap} onCheckSub={onCheckSub} defaultOpen={defaultOpen} depth={depth} />;
  // B (or anything with subtasks)
  return (
    <TaskRowB
      task={task}
      onCheck={onCheck}
      onCheckSub={onCheckSub}
      onTap={onTap}
      dimCheck={dimCheck}
      defaultOpen={defaultOpen}
      depth={depth}
    />
  );
}

// ─────────────────────────────────────────────────────────────
// Type A — flat single-line task. No container; lives directly in the list.
function TaskRowA({ task, onCheck, onTap, dimCheck = false, depth = 0 }) {
  const checkBg = task.done
    ? dimCheck
      ? "rgba(232,230,224,0.18)"
      : brushedAccent({ intensity: 0.85 })
    : "transparent";
  const checkShadow = task.done
    ? dimCheck
      ? `0 0 0 1px rgba(232,230,224,0.2), inset 0 1px 2px rgba(0,0,0,0.45)`
      : `inset 0 1px 0 rgba(${W.hiRGB},0.4), inset 0 -1px 1px rgba(0,0,0,0.55), 0 0 0 1px rgba(0,0,0,0.6)`
    : `0 0 0 1.5px rgba(232,230,224,0.28), inset 0 1px 2px rgba(0,0,0,0.45)`;
  return (
    <div
      onClick={onTap}
      style={{
        display: "flex",
        alignItems: "center",
        gap: 14,
        padding: "14px 16px",
        background: "rgba(22,24,28,0.55)",
        border: "0.5px solid rgba(255,255,255,0.04)",
        borderRadius: 10,
        opacity: task.done ? 0.5 : 1,
        cursor: "pointer",
        marginLeft: depth * 18,
      }}
    >
      <button
        onClick={(e) => {
          e.stopPropagation();
          onCheck && onCheck();
        }}
        style={{
          width: 20,
          height: 20,
          padding: 0,
          border: 0,
          cursor: "pointer",
          background: checkBg,
          boxShadow: checkShadow,
          borderRadius: 5,
          position: "relative",
          flexShrink: 0,
        }}
      >
        {task.done && (
          <svg
            width="10"
            height="10"
            viewBox="0 0 12 12"
            style={{
              position: "absolute",
              left: "50%",
              top: "50%",
              transform: "translate(-50%,-50%)",
            }}
          >
            <path
              d="M2 6.5L4.8 9.2 10 3.5"
              stroke={dimCheck ? "rgba(232,230,224,0.55)" : W.onAccent}
              strokeWidth="2"
              fill="none"
              strokeLinecap="square"
            />
          </svg>
        )}
      </button>
      <div
        style={{
          flex: 1,
          minWidth: 0,
          fontFamily: W.mono,
          fontSize: 16,
          fontWeight: 500,
          color: task.done ? W.textLo : W.textHi,
          letterSpacing: "0.005em",
          textDecoration: task.done ? "line-through" : "none",
          textOverflow: "ellipsis",
          overflow: "hidden",
          whiteSpace: "nowrap",
        }}
      >
        {task.title}
      </div>
      {task.date && <TaskDate text={task.date} overdue={task.overdue} />}
    </div>
  );
}

// ─────────────────────────────────────────────────────────────
// Type B — container with expandable subtasks. Checkbox on the left;
// user can check the main task directly, or check all subtasks to auto-complete.
function TaskRowB({ task, onCheckSub, onTap, onCheck, dimCheck = false, defaultOpen = true, depth = 0 }) {
  const [open, setOpen] = useStateH(defaultOpen);
  const allDone = isAllSubDone(task);
  const isDone = task.done || allDone;
  // Grey-done style matching A type completed appearance
  const checkBg = isDone ? "rgba(232,230,224,0.32)" : "transparent";
  const checkShadow = isDone
    ? `0 0 0 1px rgba(232,230,224,0.22), inset 0 1px 2px rgba(0,0,0,0.45)`
    : `0 0 0 1.5px rgba(232,230,224,0.28), inset 0 1px 2px rgba(0,0,0,0.45)`;
  return (
    <div
      style={{
        background: "rgba(22,24,28,0.55)",
        border: "0.5px solid rgba(255,255,255,0.04)",
        borderRadius: 10,
        overflow: "hidden",
        opacity: isDone ? 0.55 : 1,
        marginLeft: depth * 18,
      }}
    >
      <div
        onClick={onTap}
        style={{
          display: "flex",
          alignItems: "center",
          gap: 14,
          padding: "14px 16px",
          cursor: "pointer",
        }}
      >
        {/* Checkbox — stops propagation so it doesn't open detail */}
        <button
          onClick={(e) => { e.stopPropagation(); onCheck && onCheck(); }}
          style={{
            width: 20, height: 20, padding: 0, border: 0,
            cursor: "pointer",
            background: checkBg,
            boxShadow: checkShadow,
            borderRadius: 5,
            position: "relative",
            flexShrink: 0,
          }}
        >
          {isDone && (
            <svg width="10" height="10" viewBox="0 0 12 12" style={{
              position: "absolute", left: "50%", top: "50%",
              transform: "translate(-50%,-50%)",
            }}>
              <path d="M2 6.5L4.8 9.2 10 3.5" stroke="rgba(232,230,224,0.55)" strokeWidth="2" fill="none" strokeLinecap="square"/>
            </svg>
          )}
        </button>
        <div
          style={{
            flex: 1, minWidth: 0,
            fontFamily: W.mono, fontSize: 16, fontWeight: 500,
            color: isDone ? W.textLo : W.textHi,
            letterSpacing: "0.005em",
            textOverflow: "ellipsis", overflow: "hidden", whiteSpace: "nowrap",
            textDecoration: isDone ? "line-through" : "none",
          }}
        >
          {task.title}
        </div>
        {/* Date + branch icon — tight together */}
        <div style={{ display: "flex", alignItems: "center", gap: 4, flexShrink: 0 }}>
          {task.date && <TaskDate text={task.date} overdue={task.overdue} />}
          <svg width="13" height="13" viewBox="0 0 13 13" fill="none" style={{ flexShrink: 0, color: W.textXLo }}>
            <line x1="3" y1="2" x2="3" y2="10" stroke="currentColor" strokeWidth="1.2" strokeLinecap="round"/>
            <line x1="3" y1="5" x2="10" y2="5" stroke="currentColor" strokeWidth="1.2" strokeLinecap="round"/>
            <line x1="3" y1="10" x2="10" y2="10" stroke="currentColor" strokeWidth="1.2" strokeLinecap="round"/>
            <circle cx="11" cy="5" r="1.3" fill="currentColor"/>
            <circle cx="11" cy="10" r="1.3" fill="currentColor"/>
          </svg>
        </div>
        <svg
          onClick={(e) => { e.stopPropagation(); setOpen(o => !o); }}
          width="11" height="7" viewBox="0 0 11 7"
          style={{
            transform: open ? "none" : "rotate(-90deg)",
            transition: "transform .2s", cursor: "pointer", padding: 4, boxSizing: "content-box",
          }}
        >
          <path d="M1 1L5.5 5.5 10 1" stroke={W.textLo} strokeWidth="1.4" fill="none" strokeLinecap="round"/>
        </svg>
      </div>
      {open && task.subtasks && task.subtasks.length > 0 && (
        <div
          style={{
            padding: "4px 14px 10px",
            borderTop: "1px solid rgba(255,255,255,0.04)",
            background: "rgba(0,0,0,0.18)",
            display: "flex",
            flexDirection: "column",
            gap: 4,
          }}
        >
          {task.subtasks.map((sub) => (
            <SubtaskRow
              key={sub.id}
              sub={sub}
              onCheck={() => onCheckSub && onCheckSub(sub.id)}
            />
          ))}
        </div>
      )}
    </div>
  );
}

// Render a single subtask. If it has its own subtasks/progress, show
// the C-style mini-card; otherwise simple checkbox row.
function SubtaskRow({ sub, onCheck }) {
  if (
    sub.type === "C" ||
    (sub.subtasks && sub.subtasks.length > 0) ||
    sub.progress !== undefined
  ) {
    return (
      <div
        style={{
          display: "flex",
          alignItems: "center",
          gap: 12,
          padding: "11px 4px 11px 36px",
          opacity: sub.done ? 0.55 : 1,
        }}
      >
        <SubtaskGlyph small />
        <div
          style={{
            flex: 1,
            minWidth: 0,
            fontFamily: W.mono,
            fontSize: 16,
            fontWeight: 500,
            color: sub.done ? W.textLo : W.textHi,
            letterSpacing: "0.005em",
            textOverflow: "ellipsis",
            overflow: "hidden",
            whiteSpace: "nowrap",
          }}
        >
          {sub.title}
        </div>
        {sub.date && <TaskDate text={sub.date} overdue={sub.overdue} small />}
        <PieGlyph value={sub.progress || subProgress(sub)} />
        <svg width="6" height="10" viewBox="0 0 6 10" style={{ marginLeft: 2 }}>
          <path
            d="M1 1L5 5 1 9"
            stroke={W.textXLo}
            strokeWidth="1.4"
            fill="none"
            strokeLinecap="round"
          />
        </svg>
      </div>
    );
  }
  // simple
  return (
    <div
      style={{
        display: "flex",
        alignItems: "center",
        gap: 12,
        padding: "11px 4px 11px 36px",
        opacity: sub.done ? 0.55 : 1,
      }}
    >
      <button
        onClick={(e) => { e.stopPropagation(); onCheck && onCheck(); }}
        style={{
          width: 17,
          height: 17,
          padding: 0,
          border: 0,
          cursor: "pointer",
          background: sub.done ? "rgba(232,230,224,0.32)" : "transparent",
          boxShadow: sub.done
            ? `0 0 0 1px rgba(232,230,224,0.22), inset 0 1px 2px rgba(0,0,0,0.45)`
            : `0 0 0 1.5px rgba(232,230,224,0.22), inset 0 1px 2px rgba(0,0,0,0.45)`,
          borderRadius: 4,
          position: "relative",
          flexShrink: 0,
        }}
      >
        {sub.done && (
          <svg
            width="9"
            height="9"
            viewBox="0 0 12 12"
            style={{
              position: "absolute",
              left: "50%",
              top: "50%",
              transform: "translate(-50%,-50%)",
            }}
          >
            <path
              d="M2 6.5L4.8 9.2 10 3.5"
              stroke="rgba(232,230,224,0.55)"
              strokeWidth="2"
              fill="none"
            />
          </svg>
        )}
      </button>
      <div
        style={{
          flex: 1,
          minWidth: 0,
          fontFamily: W.mono,
          fontSize: 16,
          fontWeight: 500,
          color: sub.done ? W.textLo : W.textHi,
          letterSpacing: "0.005em",
          textOverflow: "ellipsis",
          overflow: "hidden",
          whiteSpace: "nowrap",
          textDecoration: sub.done ? "line-through" : "none",
        }}
      >
        {sub.title}
      </div>
      {sub.date && <TaskDate text={sub.date} overdue={sub.overdue} small />}
    </div>
  );
}

// ─────────────────────────────────────────────────────────────
// Type C — independent-events container. No checkbox on the main row.
// Shows pie + date + chevron. Expanded by default, sub-items spaced apart.
function TaskRowC({ task, onTap, onCheckSub, defaultOpen = true, depth = 0 }) {
  const [open, setOpen] = useStateH(defaultOpen);
  const progress =
    task.progress !== undefined ? task.progress : subProgress(task);
  return (
    <div
      style={{
        background: "rgba(22,24,28,0.55)",
        border: "0.5px solid rgba(255,255,255,0.04)",
        borderRadius: 10,
        overflow: "hidden",
        opacity: progress >= 0.999 ? 0.55 : 1,
        marginLeft: depth * 18,
      }}
    >
      {/* Main row — no checkbox, tap toggles expand */}
      <div
        onClick={onTap}
        style={{
          display: "flex",
          alignItems: "center",
          gap: 14,
          padding: "14px 16px",
          cursor: "pointer",
        }}
      >
        <SubtaskGlyph />
        <div
          style={{
            flex: 1, minWidth: 0,
            fontFamily: W.mono, fontSize: 16, fontWeight: 500,
            color: progress >= 0.999 ? W.textLo : W.textHi,
            letterSpacing: "0.005em",
            textOverflow: "ellipsis", overflow: "hidden", whiteSpace: "nowrap",
          }}
        >
          {task.title}
        </div>
        {/* Date + pie icon — tight together */}
        <div style={{ display: "flex", alignItems: "center", gap: 4, flexShrink: 0 }}>
          {task.date && <TaskDate text={task.date} overdue={task.overdue} />}
          <PieGlyph value={progress} />
        </div>
        <svg
          onClick={(e) => { e.stopPropagation(); setOpen(o => !o); }}
          width="11" height="7" viewBox="0 0 11 7"
          style={{
            transform: open ? "none" : "rotate(-90deg)",
            transition: "transform .2s", cursor: "pointer", padding: 4, boxSizing: "content-box",
          }}
        >
          <path d="M1 1L5.5 5.5 10 1" stroke={W.textLo} strokeWidth="1.4" fill="none" strokeLinecap="round"/>
        </svg>
      </div>
      {/* Sub-items — independent events, spaced with gap */}
      {open && task.subtasks && task.subtasks.length > 0 && (
        <div
          style={{
            padding: "4px 14px 10px",
            borderTop: "1px solid rgba(255,255,255,0.04)",
            background: "rgba(0,0,0,0.18)",
            display: "flex",
            flexDirection: "column",
            gap: 4,
          }}
        >
          {task.subtasks.map((sub) => (
            <SubtaskRow
              key={sub.id}
              sub={sub}
              onCheck={() => onCheckSub && onCheckSub(sub.id)}
            />
          ))}
        </div>
      )}
    </div>
  );
}

// ─────────────────────────────────────────────────────────────
// Date label — overdue items render with a warm desaturated red.
function TaskDate({ text, overdue, small = false }) {
  return (
    <span
      style={{
        fontFamily: W.mono,
        fontSize: small ? 10.5 : 12,
        color: overdue ? "#ff5252" : W.textLo,
        letterSpacing: "0.04em",
        fontVariantNumeric: "tabular-nums",
        flexShrink: 0,
        marginLeft: 6,
        whiteSpace: "nowrap",
      }}
    >
      {text}
    </span>
  );
}

// "Subtask container" icon — rows-of-bullets glyph.
function SubtaskGlyph({ small = false }) {
  const s = small ? 16 : 18;
  return (
    <svg
      width={s}
      height={s}
      viewBox="0 0 18 18"
      fill="none"
      style={{ flexShrink: 0, color: W.textLo }}
    >
      <rect
        x="1.5"
        y="2.5"
        width="15"
        height="13"
        rx="2"
        stroke="currentColor"
        strokeWidth="1.2"
      />
      <circle cx="5" cy="6" r="0.9" fill="currentColor" />
      <line
        x1="7.5"
        y1="6"
        x2="13.5"
        y2="6"
        stroke="currentColor"
        strokeWidth="1.1"
      />
      <circle cx="5" cy="9" r="0.9" fill="currentColor" />
      <line
        x1="7.5"
        y1="9"
        x2="13.5"
        y2="9"
        stroke="currentColor"
        strokeWidth="1.1"
      />
      <circle cx="5" cy="12" r="0.9" fill="currentColor" />
      <line
        x1="7.5"
        y1="12"
        x2="11.5"
        y2="12"
        stroke="currentColor"
        strokeWidth="1.1"
      />
    </svg>
  );
}

// Pie chart progress glyph — filled sector style.
function PieGlyph({ value = 0 }) {
  const cx = 8, cy = 8, r = 6;
  if (value <= 0) {
    return (
      <svg width="16" height="16" viewBox="0 0 16 16" style={{ flexShrink: 0 }}>
        <circle cx={cx} cy={cy} r={r} fill="rgba(255,255,255,0.1)" />
      </svg>
    );
  }
  if (value >= 0.999) {
    return (
      <svg width="16" height="16" viewBox="0 0 16 16" style={{ flexShrink: 0 }}>
        <circle cx={cx} cy={cy} r={r} fill={W.accentHi} opacity="0.8" />
      </svg>
    );
  }
  const angle = value * 2 * Math.PI;
  const x = cx + r * Math.sin(angle);
  const y = cy - r * Math.cos(angle);
  const largeArc = value > 0.5 ? 1 : 0;
  return (
    <svg width="16" height="16" viewBox="0 0 16 16" style={{ flexShrink: 0 }}>
      <circle cx={cx} cy={cy} r={r} fill="rgba(255,255,255,0.1)" />
      <path
        d={`M ${cx} ${cy} L ${cx} ${cy - r} A ${r} ${r} 0 ${largeArc} 1 ${x} ${y} Z`}
        fill={W.accentHi}
        opacity="0.8"
      />
    </svg>
  );
}

// ─────────────────────────────────────────────────────────────
// Task Detail bottom sheet — shows task info, entry point to Pomodoro
function TaskDetailSheet({ task, open, onClose, onStartTask, onCheck, categories, lang }) {
  if (!task) return null;

  const catLabel = (cat) =>
    typeof cat.label === "object" ? cat.label[lang] || cat.label.en : cat.label;
  const cat = categories.find(c => c.id === task.category);
  const catName = cat ? catLabel(cat) : task.category;

  const sheetStyle = {
    position: "absolute", bottom: 0, left: 0, right: 0,
    background: "#0f1012",
    borderTopLeftRadius: 18, borderTopRightRadius: 18,
    boxShadow: "0 -2px 40px rgba(0,0,0,0.85)",
    transform: open ? "translateY(0)" : "translateY(100%)",
    transition: "transform .32s cubic-bezier(.2,.85,.3,1)",
    height: "88%", maxHeight: "95%", display: "flex", flexDirection: "column",
  };

  return (
    <div style={{ position: "absolute", inset: 0, zIndex: 50, pointerEvents: open ? "auto" : "none" }}>
      <div onClick={onClose} style={{
        position: "absolute", inset: 0, background: "rgba(0,0,0,0.5)",
        opacity: open ? 1 : 0, transition: "opacity .28s",
      }} />
      <div style={sheetStyle}>
        {/* Handle */}
        <div style={{ display: "flex", justifyContent: "center", padding: "10px 0 6px", flexShrink: 0 }}>
          <div style={{ width: 36, height: 4, borderRadius: 2, background: "rgba(255,255,255,0.13)" }} />
        </div>

        {/* Category breadcrumb */}
        <div style={{
          display: "flex", alignItems: "center", gap: 6,
          padding: "4px 20px 10px",
          borderBottom: "0.5px solid rgba(255,255,255,0.06)", flexShrink: 0,
        }}>
          <span style={{ fontFamily: W.display, fontSize: 15, color: W.textHi }}>{catName}</span>
          {task.subCategory && (
            <>
              <span style={{ color: "rgba(255,255,255,0.25)", fontSize: 13 }}>/</span>
              <span style={{ fontFamily: W.display, fontSize: 15, color: W.textHi }}>{task.subCategory}</span>
            </>
          )}
        </div>

        {/* Scrollable body */}
        <div style={{ flex: 1, overflowY: "auto", padding: "18px 20px 10px" }}>

          {/* Title */}
          <div style={{
            fontFamily: W.display, fontSize: 22, fontWeight: 600,
            color: W.textHi, letterSpacing: "-0.01em", marginBottom: 8, lineHeight: 1.25,
          }}>
            {task.title}
          </div>

          {/* Date */}
          {task.date && (
            <div style={{ fontFamily: W.display, fontSize: 16, color: W.accentHi, marginBottom: 14 }}>
              {task.overdue ? `已過期 · ${task.date}` : task.date}
            </div>
          )}

          {/* Pomodoro button */}
          <div
            onClick={() => onStartTask(task.id)}
            style={{
              display: "flex", alignItems: "center", gap: 14,
              padding: "13px 16px", marginBottom: 18,
              background: "rgba(196,166,98,0.07)",
              border: `0.5px solid ${W.accentHi}`,
              borderRadius: 12, cursor: "pointer",
            }}
          >
            <svg width="30" height="30" viewBox="0 0 32 32" fill="none" style={{ flexShrink: 0 }}>
              <circle cx="16" cy="18" r="11" fill="rgba(196,166,98,0.15)" stroke={W.accentHi} strokeWidth="1.2"/>
              <path d="M16 7C16 7 14 4 11 4" stroke={W.accentHi} strokeWidth="1.3" strokeLinecap="round"/>
              <path d="M16 7C16 7 17 3.5 20 4" stroke={W.accentHi} strokeWidth="1.3" strokeLinecap="round"/>
              <line x1="16" y1="7" x2="16" y2="9" stroke={W.accentHi} strokeWidth="1.3" strokeLinecap="round"/>
              <line x1="16" y1="13" x2="16" y2="18" stroke={W.accentHi} strokeWidth="1.5" strokeLinecap="round"/>
              <line x1="16" y1="18" x2="20" y2="21" stroke={W.accentHi} strokeWidth="1.5" strokeLinecap="round"/>
            </svg>
            <div>
              <div style={{ fontFamily: W.display, fontSize: 15, fontWeight: 600, color: W.textHi, letterSpacing: "-0.005em" }}>
                啟動番茄鐘專注
              </div>
              <div style={{ fontFamily: W.mono, fontSize: 12, color: W.accentHi, marginTop: 2, letterSpacing: "0.03em" }}>
                25 分鐘
              </div>
            </div>
          </div>

          {/* Subtasks */}
          {task.subtasks && task.subtasks.length > 0 && (
            <div style={{
              background: "rgba(255,255,255,0.03)", borderRadius: 12,
              border: "0.5px solid rgba(255,255,255,0.06)", overflow: "hidden",
            }}>
              {task.subtasks.map((sub, i) => (
                <div
                  key={sub.id}
                  onClick={() => onCheck(`${task.id}/${sub.id}`)}
                  style={{
                    display: "flex", alignItems: "center", gap: 14,
                    padding: "14px 16px", cursor: "pointer",
                    borderBottom: i < task.subtasks.length - 1 ? "0.5px solid rgba(255,255,255,0.05)" : "none",
                    opacity: sub.done ? 0.5 : 1,
                  }}
                >
                  <div style={{
                    width: 22, height: 22, borderRadius: 9999, flexShrink: 0,
                    border: `1.5px solid ${sub.done ? "rgba(232,230,224,0.4)" : "rgba(232,230,224,0.25)"}`,
                    background: sub.done ? "rgba(232,230,224,0.15)" : "transparent",
                    display: "flex", alignItems: "center", justifyContent: "center",
                  }}>
                    {sub.done && (
                      <svg width="11" height="9" viewBox="0 0 12 10" fill="none">
                        <path d="M1 5L4.5 8.5 11 1" stroke="rgba(232,230,224,0.7)" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"/>
                      </svg>
                    )}
                  </div>
                  <span style={{
                    fontFamily: W.display, fontSize: 17, fontWeight: 500,
                    color: sub.done ? W.textLo : W.textHi,
                    textDecoration: sub.done ? "line-through" : "none",
                  }}>{sub.title}</span>
                </div>
              ))}
              {/* Add subtask hint */}
              <div style={{ display: "flex", alignItems: "center", gap: 14, padding: "12px 16px" }}>
                <div style={{ width: 22, height: 22, borderRadius: 9999, flexShrink: 0, border: "1.5px solid rgba(232,230,224,0.1)" }} />
                <span style={{ fontFamily: W.display, fontSize: 16, color: W.accentHi, fontWeight: 500 }}>+ 新增子任務</span>
              </div>
            </div>
          )}
        </div>
      </div>
    </div>
  );
}

// ─────────────────────────────────────────────────────────────
// Add Task bottom sheet — TickTick-style: title-first, bottom toolbar
function AddTaskSheet({ open, onClose, onConfirm, categories, goalSubCats, initialCategory, initialGoalSub, tasks = [] }) {
  const lang = (typeof window !== "undefined" && window.__witnessLang) || "en";
  const catLabel = (cat) =>
    typeof cat.label === "object" ? cat.label[lang] || cat.label.en : cat.label;

  const firstCat = (categories.find(c => c.id !== "unsorted") || categories[0] || {}).id;

  const getTodayStr = () => {
    const d = new Date();
    return `${d.getFullYear()}-${String(d.getMonth()+1).padStart(2,"0")}-${String(d.getDate()).padStart(2,"0")}`;
  };

  const [category, setCategory] = useStateH(initialCategory || firstCat);
  const [subCat, setSubCat] = useStateH(initialGoalSub || "");
  const [title, setTitle] = useStateH("");
  const [desc, setDesc] = useStateH("");
  const [date, setDate] = useStateH(getTodayStr());
  const [subMode, setSubMode] = useStateH("none");
  const [subs, setSubs] = useStateH([""]);
  const subInputRefs = React.useRef([]);

  const allTaskTitles = React.useMemo(() => {
    const seen = new Set();
    return tasks.map(t => t.title).filter(t => { if (seen.has(t)) return false; seen.add(t); return true; });
  }, [tasks]);
  const [suggestions, setSuggestions] = useStateH([]);
  const [suggFocus, setSuggFocus] = useStateH(-1);
  const titleRef = React.useRef(null);
  const blurTimer = React.useRef(null);

  const computeSugg = (v) => {
    if (!v.trim()) return [];
    const q = v.toLowerCase();
    return allTaskTitles.filter(t => t.toLowerCase().startsWith(q));
  };

  const handleTitleChange = (e) => {
    const v = e.target.value;
    setTitle(v);
    const s = computeSugg(v);
    setSuggestions(s);
    setSuggFocus(-1);
  };

  const pickSuggestion = (s) => {
    setTitle(s);
    setSuggestions([]);
    setSuggFocus(-1);
    if (titleRef.current) titleRef.current.focus();
  };

  const handleTitleKeyDown = (e) => {
    if (!suggestions.length) return;
    if (e.key === "ArrowDown") {
      e.preventDefault();
      setSuggFocus(f => Math.min(f + 1, suggestions.length - 1));
    } else if (e.key === "ArrowUp") {
      e.preventDefault();
      setSuggFocus(f => Math.max(f - 1, -1));
    } else if (e.key === "Enter" && suggFocus >= 0) {
      e.preventDefault();
      pickSuggestion(suggestions[suggFocus]);
    } else if (e.key === "Escape") {
      setSuggestions([]);
      setSuggFocus(-1);
    }
  };

  const handleTitleBlur = () => {
    blurTimer.current = setTimeout(() => {
      setSuggestions([]);
      setSuggFocus(-1);
    }, 150);
  };

  const handleSuggMouseDown = (s) => {
    clearTimeout(blurTimer.current);
    pickSuggestion(s);
  };

  useEffectH(() => {
    if (open) {
      const initCat = initialCategory || firstCat;
      setCategory(initCat);
      setSubCat(initialGoalSub || firstSubCat(initCat));
      setTitle(""); setDesc(""); setDate(getTodayStr());
      setSubMode("none"); setSubs([""]);
      setSuggestions([]); setSuggFocus(-1);
    }
  }, [open]);

  const availableSubCats = (goalSubCats || {})[category] || [];
  const firstSubCat = (cat) => ((goalSubCats || {})[cat] || [])[0]?.id || "";

  const handleConfirm = () => {
    if (!title.trim()) return;
    let day = "today", overdue = false;
    if (date) {
      const sel = new Date(date + "T00:00:00");
      const now = new Date(); now.setHours(0,0,0,0);
      if (sel < now) { day = "overdue"; overdue = true; }
      else if (sel.getTime() === now.getTime()) day = "today";
      else day = "next7";
    }
    let type = "A";
    if (subMode === "check") type = "B";
    else if (subMode === "list") type = "C";

    const newTask = { id: `task-${Date.now()}`, type, title: title.trim(), category, day, done: false, estMin: 30 };
    if (date) {
      const d = new Date(date + "T00:00:00");
      newTask.date = `${d.getMonth() + 1}月${d.getDate()}日`;
      if (overdue) newTask.overdue = true;
    }
    if (subCat) newTask.subCategory = subCat;
    const validSubs = subs.filter(s => s.trim());
    if (validSubs.length > 0 && type !== "A") {
      newTask.subtasks = validSubs.map((s, i) => ({ id: `sub-${Date.now()}-${i}`, title: s.trim(), done: false }));
    }
    onConfirm(newTask);
    onClose();
  };

  const inp = {
    background: "transparent", border: "none", outline: "none",
    fontFamily: W.display, color: W.textHi, caretColor: W.accentHi, boxSizing: "border-box",
  };

  // Inline text-style select (no box)
  const txtSel = {
    background: "transparent", border: "none", outline: "none",
    fontFamily: W.display, fontSize: 17, color: W.textHi,
    cursor: "pointer", appearance: "none", WebkitAppearance: "none",
    padding: "2px 20px 2px 0",
  };

  const orderedCats = [
    ...categories.filter(c => c.id !== "unsorted"),
    ...categories.filter(c => c.id === "unsorted"),
  ];

  const dateDisplay = (() => {
    const d = new Date(date + "T00:00:00");
    const now = new Date(); now.setHours(0,0,0,0);
    const dateStr = `${d.getMonth()+1}月${d.getDate()}日`;
    const prefix = d.getTime() === now.getTime() ? (lang === "zh" ? "今天" : "Today") : "";
    return prefix ? `${prefix}, ${dateStr}` : dateStr;
  })();

  const miniChevron = (
    <svg width="8" height="5" viewBox="0 0 8 5" fill="none"
      style={{ position: "absolute", right: 2, top: "50%", transform: "translateY(-50%)", pointerEvents: "none", color: "rgba(232,230,224,0.35)" }}>
      <path d="M1 1L4 4 7 1" stroke="currentColor" strokeWidth="1.3" strokeLinecap="round"/>
    </svg>
  );

  return (
    <div style={{ position: "absolute", inset: 0, zIndex: 50, pointerEvents: open ? "auto" : "none" }}>
      {/* Scrim */}
      <div onClick={onClose} style={{
        position: "absolute", inset: 0, background: "rgba(0,0,0,0.5)",
        opacity: open ? 1 : 0, transition: "opacity .28s",
      }} />

      {/* Sheet */}
      <div style={{
        position: "absolute", bottom: 0, left: 0, right: 0,
        background: "#0f1012",
        borderTopLeftRadius: 18, borderTopRightRadius: 18,
        boxShadow: "0 -2px 40px rgba(0,0,0,0.85)",
        transform: open ? "translateY(0)" : "translateY(100%)",
        transition: "transform .32s cubic-bezier(.2,.85,.3,1)",
        height: "88%", maxHeight: "95%", display: "flex", flexDirection: "column",
      }}>
        {/* Handle */}
        <div style={{ display: "flex", justifyContent: "center", padding: "10px 0 6px", flexShrink: 0 }}>
          <div style={{ width: 36, height: 4, borderRadius: 2, background: "rgba(255,255,255,0.13)" }} />
        </div>

        {/* Category row — inline text selects */}
        <div style={{
          display: "flex", alignItems: "center", gap: 16,
          padding: "4px 18px 10px",
          borderBottom: "0.5px solid rgba(255,255,255,0.06)",
          flexShrink: 0,
        }}>
          {/* Category select */}
          <div style={{ position: "relative" }}>
            <select value={category} onChange={e => { setCategory(e.target.value); setSubCat(firstSubCat(e.target.value)); }} style={txtSel}>
              {orderedCats.map(c => (
                <option key={c.id} value={c.id} style={{ background: "#18191d" }}>{catLabel(c)}</option>
              ))}
            </select>
            {miniChevron}
          </div>

          {/* Sub-cat select */}
          <div style={{ position: "relative" }}>
            <select value={subCat} onChange={e => setSubCat(e.target.value)} style={txtSel}>
              {availableSubCats.map(s => {
                const lbl = typeof s.label === "object" ? s.label[lang] || s.label.en : s.label;
                return <option key={s.id} value={s.id} style={{ background: "#18191d" }}>{lbl}</option>;
              })}
              <option value="" style={{ background: "#18191d" }}>未分類</option>
            </select>
            {miniChevron}
          </div>
        </div>

        {/* Scrollable body */}
        <div style={{ flex: 1, overflowY: "auto", padding: "14px 20px 10px" }}>

          {/* Title + autocomplete */}
          <div style={{ position: "relative", marginBottom: 8 }}>
            <input
              ref={titleRef}
              type="text"
              placeholder="任務名稱"
              value={title}
              onChange={handleTitleChange}
              onKeyDown={handleTitleKeyDown}
              onBlur={handleTitleBlur}
              style={{
                ...inp, width: "100%", fontSize: 22, fontWeight: 600,
                letterSpacing: "-0.01em", display: "block",
              }}
            />
            {suggestions.length > 0 && (
              <div style={{
                position: "absolute", top: "calc(100% + 6px)", left: -4, right: -4, zIndex: 99,
                background: W.iron,
                border: `0.5px solid rgba(196,166,98,0.28)`,
                borderRadius: 12,
                boxShadow: "0 12px 40px rgba(0,0,0,0.72), 0 0 0 0.5px rgba(255,255,255,0.04) inset",
                overflow: "hidden",
                animation: "sugg-in 0.15s cubic-bezier(.2,.9,.3,1) both",
              }}>
                {/* header label */}
                <div style={{
                  padding: "7px 14px 5px",
                  display: "flex", alignItems: "center", gap: 6,
                  borderBottom: "0.5px solid rgba(255,255,255,0.05)",
                }}>
                  <svg width="11" height="11" viewBox="0 0 12 12" fill="none">
                    <circle cx="6" cy="6" r="5" stroke={W.accentHi} strokeWidth="1.2" strokeOpacity="0.6"/>
                    <path d="M6 3.5V6.2L7.8 7.5" stroke={W.accentHi} strokeWidth="1.2" strokeLinecap="round" strokeOpacity="0.6"/>
                  </svg>
                  <span style={{ fontFamily: W.mono, fontSize: 10, color: W.accentHi, opacity: 0.55, letterSpacing: "0.08em", textTransform: "uppercase" }}>歷史常用</span>
                </div>
                {suggestions.map((s, i) => {
                  const matched = s.slice(0, title.length);
                  const rest = s.slice(title.length);
                  const active = i === suggFocus;
                  return (
                    <div
                      key={i}
                      onMouseDown={() => handleSuggMouseDown(s)}
                      onTouchStart={() => handleSuggMouseDown(s)}
                      style={{
                        padding: "11px 14px",
                        fontFamily: W.display, fontSize: 16, color: active ? W.textHi : W.text,
                        cursor: "pointer",
                        background: active ? `rgba(196,166,98,0.10)` : "transparent",
                        borderBottom: i < suggestions.length - 1 ? "0.5px solid rgba(255,255,255,0.04)" : "none",
                        display: "flex", alignItems: "center", gap: 0,
                        transition: "background 0.1s",
                        borderLeft: active ? `2px solid ${W.accentHi}` : "2px solid transparent",
                      }}
                    >
                      <span style={{ color: W.accentHi, fontWeight: 600 }}>{matched}</span>
                      <span>{rest}</span>
                    </div>
                  );
                })}
              </div>
            )}
          </div>

          {/* Date — below title, clickable */}
          <label style={{ display: "inline-flex", alignItems: "center", cursor: "pointer", marginBottom: 12, position: "relative" }}>
            <span style={{ fontFamily: W.display, fontSize: 16, color: W.accentHi, letterSpacing: "0.01em" }}>
              {dateDisplay}
            </span>
            <input type="date" value={date} onChange={e => setDate(e.target.value)}
              style={{ position: "absolute", inset: 0, opacity: 0, cursor: "pointer", width: "100%", height: "100%" }} />
          </label>

          {/* Pomodoro button */}
          <div style={{
            display: "flex", alignItems: "center", gap: 14,
            padding: "13px 16px", marginBottom: 14,
            background: "rgba(196,166,98,0.07)",
            border: `0.5px solid ${W.accentHi}`,
            borderRadius: 12, cursor: "pointer",
          }}>
            {/* Tomato icon */}
            <svg width="30" height="30" viewBox="0 0 32 32" fill="none" style={{ flexShrink: 0 }}>
              <circle cx="16" cy="18" r="11" fill="rgba(196,166,98,0.15)" stroke={W.accentHi} strokeWidth="1.2"/>
              <path d="M16 7C16 7 14 4 11 4" stroke={W.accentHi} strokeWidth="1.3" strokeLinecap="round"/>
              <path d="M16 7C16 7 17 3.5 20 4" stroke={W.accentHi} strokeWidth="1.3" strokeLinecap="round"/>
              <line x1="16" y1="7" x2="16" y2="9" stroke={W.accentHi} strokeWidth="1.3" strokeLinecap="round"/>
              <line x1="16" y1="13" x2="16" y2="18" stroke={W.accentHi} strokeWidth="1.5" strokeLinecap="round"/>
              <line x1="16" y1="18" x2="20" y2="21" stroke={W.accentHi} strokeWidth="1.5" strokeLinecap="round"/>
            </svg>
            <div>
              <div style={{ fontFamily: W.display, fontSize: 15, fontWeight: 600, color: W.textHi, letterSpacing: "-0.005em" }}>
                啟動番茄鐘專注
              </div>
              <div style={{ fontFamily: W.mono, fontSize: 12, color: W.accentHi, marginTop: 2, letterSpacing: "0.03em" }}>
                25 分鐘
              </div>
            </div>
          </div>

          {/* Description */}
          <textarea
            placeholder="描述"
            value={desc}
            onChange={e => setDesc(e.target.value)}
            rows={2}
            style={{
              ...inp, width: "100%", fontSize: 16,
              color: desc ? W.textHi : "rgba(232,230,224,0.35)",
              resize: "none", lineHeight: 1.65, marginBottom: 14,
            }}
          />

          {/* Subtask inputs — shown when subMode active */}
          {subMode !== "none" && (
            <div style={{ marginBottom: 8 }}>
              {subs.map((sub, i) => (
                <div key={i} style={{ display: "flex", alignItems: "center", gap: 14, padding: "10px 0", borderBottom: "0.5px solid rgba(255,255,255,0.05)" }}>
                  <div style={{
                    width: 22, height: 22, borderRadius: 9999, flexShrink: 0,
                    border: "1.5px solid rgba(232,230,224,0.25)",
                  }} />
                  <input
                    type="text"
                    placeholder="新增子任務"
                    value={sub}
                    ref={el => subInputRefs.current[i] = el}
                    onChange={e => { const n = [...subs]; n[i] = e.target.value; setSubs(n); }}
                    onKeyDown={e => {
                      if (e.key === "Enter") {
                        e.preventDefault();
                        setSubs([...subs, ""]);
                        setTimeout(() => subInputRefs.current[subs.length]?.focus(), 0);
                      } else if (e.key === "Backspace" && sub === "" && subs.length > 1) {
                        e.preventDefault();
                        const n = subs.filter((_, idx) => idx !== i);
                        setSubs(n);
                        setTimeout(() => subInputRefs.current[Math.max(0, i - 1)]?.focus(), 0);
                      }
                    }}
                    style={{
                      ...inp, flex: 1, fontSize: 17, fontWeight: 500,
                    }}
                  />
                </div>
              ))}
              {/* Add row hint */}
              <div style={{ display: "flex", alignItems: "center", gap: 14, padding: "10px 0" }}>
                <div style={{ width: 22, height: 22, borderRadius: 9999, flexShrink: 0, border: "1.5px solid rgba(232,230,224,0.1)" }} />
                <span style={{ fontFamily: W.display, fontSize: 16, color: W.accentHi, fontWeight: 500 }}>
                  + 新增子任務
                </span>
              </div>
            </div>
          )}
        </div>

        {/* Bottom toolbar */}
        <div style={{
          display: "flex", alignItems: "center", justifyContent: "space-between",
          padding: "10px 18px 36px",
          flexShrink: 0,
        }}>
          {/* Left pill — transparent bg, thin border ring, no divider */}
          <div style={{
            display: "flex", alignItems: "center",
            background: "transparent",
            border: "0.5px solid rgba(255,255,255,0.18)",
            borderRadius: 9999,
          }}>
            {/* Subtask toggle */}
            <button onClick={() => setSubMode(subMode === "check" ? "none" : "check")} style={{
              padding: "10px 18px", border: "none", cursor: "pointer", background: "transparent",
              color: subMode === "check" ? W.accentHi : W.textHi,
              display: "flex", alignItems: "center", justifyContent: "center", transition: "color .18s",
            }}>
              <svg width="18" height="18" viewBox="0 0 20 20" fill="none">
                <rect x="2" y="2" width="16" height="16" rx="3.5" stroke="currentColor" strokeWidth="1.4"/>
                <path d="M6 10.5L8.5 13 14 7.5" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round"/>
              </svg>
            </button>

            {/* List toggle */}
            <button onClick={() => setSubMode(subMode === "list" ? "none" : "list")} style={{
              padding: "10px 18px", border: "none", cursor: "pointer", background: "transparent",
              color: subMode === "list" ? W.accentHi : W.textHi,
              display: "flex", alignItems: "center", justifyContent: "center", transition: "color .18s",
            }}>
              <svg width="18" height="18" viewBox="0 0 20 20" fill="none">
                <line x1="4" y1="6" x2="16" y2="6" stroke="currentColor" strokeWidth="1.4" strokeLinecap="round"/>
                <line x1="4" y1="10" x2="16" y2="10" stroke="currentColor" strokeWidth="1.4" strokeLinecap="round"/>
                <line x1="4" y1="14" x2="11" y2="14" stroke="currentColor" strokeWidth="1.4" strokeLinecap="round"/>
              </svg>
            </button>
          </div>

          {/* Right — confirm circle, same ring style */}
          <button onClick={handleConfirm} style={{
            width: 40, height: 40, borderRadius: 9999,
            border: `0.5px solid ${title.trim() ? "transparent" : "rgba(255,255,255,0.18)"}`,
            cursor: "pointer",
            background: title.trim() ? W.accentHi : "transparent",
            color: title.trim() ? W.onAccent : W.textHi,
            display: "flex", alignItems: "center", justifyContent: "center",
            transition: "background .2s, color .2s, border-color .2s", flexShrink: 0,
          }}>
            <svg width="14" height="11" viewBox="0 0 14 11" fill="none">
              <path d="M1 5.5L5 9.5 13 1" stroke="currentColor" strokeWidth="1.8" fill="none" strokeLinecap="round" strokeLinejoin="round"/>
            </svg>
          </button>
        </div>
      </div>
    </div>
  );
}

Object.assign(window, { ScreenHome, SubtaskGlyph, PieGlyph, TaskDate });
