// task-detail.jsx — full-page task view (3-column layout)

const TASK_DETAIL_CSS = `
.tdp { flex: 1; display: flex; flex-direction: column; min-height: 0; background: var(--bg-app); }
.tdp-header {
  background: white; border-bottom: 1px solid var(--border);
  padding: 14px 28px;
  display: flex; align-items: center; gap: 14px;
}
.tdp-back {
  background: none; border: 1px solid var(--border); color: var(--ink-body);
  padding: 6px 12px; border-radius: 6px; font-size: 13px; cursor: pointer;
  font-family: inherit; font-weight: 500;
  display: inline-flex; align-items: center; gap: 6px;
}
.tdp-back:hover { background: var(--bg-subtle); }
.tdp-bc {
  display: flex; align-items: center; gap: 6px;
  font-size: 13px; color: var(--ink-muted);
}
.tdp-bc svg { width: 12px; height: 12px; }
.tdp-bc b { color: var(--ink-strong); font-weight: 600; }
.tdp-id { font-size: 12px; color: var(--ink-faint); letter-spacing: 0.04em; margin-left: auto; }
.tdp-actions { display: flex; gap: 6px; }
.tdp-actions .btn { font-size: 12px; }

.tdp-body {
  flex: 1; overflow-y: auto;
  display: grid;
  grid-template-columns: 200px 1fr 320px;
  gap: 0;
  min-height: 0;
}
.tdp-rail {
  background: white; border-right: 1px solid var(--border);
  padding: 24px 18px; display: flex; flex-direction: column; gap: 18px;
  font-size: 13px;
}
.tdp-rail .rail-label {
  font-size: 10px; font-weight: 700; color: var(--ink-muted);
  letter-spacing: 0.1em; text-transform: uppercase;
}
.tdp-rail .rail-link {
  display: flex; align-items: center; gap: 8px; padding: 6px 8px;
  border-radius: 6px; color: var(--ink-body); cursor: pointer;
  font-size: 13px;
}
.tdp-rail .rail-link:hover { background: var(--bg-subtle); }
.tdp-rail .rail-link.is-active {
  background: rgba(162,93,220,.10); color: var(--brand); font-weight: 600;
}

.tdp-center { padding: 32px 40px 60px; min-width: 0; }
.tdp-title-row { display: flex; align-items: flex-start; gap: 12px; flex-wrap: wrap; }
.tdp-title {
  font-size: 28px; font-weight: 800; color: var(--ink-strong);
  letter-spacing: -0.03em; line-height: 1.2; margin: 0;
  flex: 1; min-width: 0;
  border: 1.5px solid transparent; border-radius: 6px;
  padding: 4px 8px; margin-left: -8px; cursor: text;
}
.tdp-title:hover { background: white; }
.tdp-title:focus { background: white; border-color: var(--brand); outline: none; }

.tdp-pillrow { display: flex; gap: 8px; flex-wrap: wrap; margin: 14px 0 22px; align-items: center; }

.tdp-section { margin: 28px 0; }
.tdp-section-h {
  font-size: 12px; font-weight: 700; color: var(--ink-muted);
  letter-spacing: 0.1em; text-transform: uppercase;
  margin-bottom: 10px;
  display: flex; align-items: center; gap: 8px;
}
.tdp-section-h .count { color: var(--ink-faint); font-weight: 500; }

.tdp-desc {
  background: white; border: 1px solid var(--border); border-radius: 8px;
  padding: 16px 18px; font-size: 14px; color: var(--ink-body); line-height: 1.6;
  white-space: pre-wrap;
  cursor: text; min-height: 80px;
}
.tdp-desc:focus { border-color: var(--brand); outline: none; }
.tdp-desc:empty:not(:focus)::before {
  content: attr(data-placeholder);
  color: #a3a8b6; font-style: italic; pointer-events: none;
}
.tdp-desc img, .tdp-desc-img {
  max-width: 100%; height: auto;
  border-radius: 6px; margin: 8px 0; display: block;
  box-shadow: 0 1px 3px rgba(0,0,0,.12);
  border: 1px solid var(--border-soft);
}
.tdp-desc-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.tdp-desc-tools { display: inline-flex; gap: 6px; }
.tdp-desc-tool {
  display: inline-flex; align-items: center; gap: 5px;
  font: inherit; font-size: 11.5px; font-weight: 600;
  color: var(--ink-muted);
  background: white; border: 1px solid var(--border);
  padding: 4px 8px; border-radius: 6px; cursor: pointer;
  transition: background .12s ease, color .12s ease, border-color .12s ease;
}
.tdp-desc-tool:hover {
  color: var(--ink-strong); background: #f0f1f4;
  border-color: var(--border-strong);
}

.tdp-subtask {
  display: flex; align-items: center; gap: 10px;
  background: white; border: 1px solid var(--border); border-radius: 6px;
  padding: 8px 12px; margin-bottom: 4px; font-size: 13px;
}
.tdp-subtask .checkbox {
  width: 16px; height: 16px; border-radius: 3px;
  border: 1.5px solid var(--border-strong); cursor: pointer;
  display: flex; align-items: center; justify-content: center; color: white;
}
.tdp-subtask.done .checkbox { background: var(--status-done); border-color: var(--status-done); }
.tdp-subtask.done .name { color: var(--ink-muted); text-decoration: line-through; }
.tdp-subtask .name { flex: 1; }
.tdp-subtask .meta { font-size: 11px; color: var(--ink-faint); }

.tdp-progress {
  height: 6px; background: #eceef2; border-radius: 999px; overflow: hidden;
  margin-bottom: 10px;
}
.tdp-progress-fill { height: 100%; background: var(--status-done); transition: width .3s; }

/* Activity stream — interleaved comments + system events */
.tdp-activity { display: flex; flex-direction: column; gap: 18px; }
.tdp-event {
  display: flex; gap: 12px; align-items: flex-start;
  padding: 8px 0;
  font-size: 13px; color: var(--ink-muted);
}
.tdp-event-icon {
  width: 26px; height: 26px; border-radius: 50%;
  background: var(--bg-subtle); color: var(--ink-muted);
  display: grid; place-items: center;
  font-size: 12px; flex-shrink: 0;
}
.tdp-event b { color: var(--ink-strong); font-weight: 600; }
.tdp-event .when { color: var(--ink-faint); font-size: 11px; margin-left: 6px; }

.tdp-comment {
  display: flex; gap: 12px;
}
.tdp-comment .body { flex: 1; }
.tdp-comment .head { display: flex; align-items: baseline; gap: 8px; margin-bottom: 4px; }
.tdp-comment .name { font-weight: 600; font-size: 13px; color: var(--ink-strong); }
.tdp-comment .when { font-size: 11px; color: var(--ink-faint); }
.tdp-comment .text {
  background: white; border: 1px solid var(--border); border-radius: 10px;
  padding: 12px 14px; font-size: 13px; color: var(--ink-body); line-height: 1.55;
}
.tdp-comment .reacts { display: flex; gap: 4px; margin-top: 6px; }
.tdp-react {
  font-size: 11.5px; padding: 2px 8px; border-radius: 12px;
  background: var(--bg-subtle); border: 1px solid var(--border);
  color: var(--ink-body); cursor: pointer;
}
.tdp-react.is-on { background: #f1e6fb; border-color: var(--brand); color: var(--brand); font-weight: 600; }

.tdp-composer {
  display: flex; gap: 10px; align-items: flex-start;
  background: white; border: 1px solid var(--border); border-radius: 10px;
  padding: 12px;
}
.tdp-composer textarea {
  flex: 1; border: none; outline: none; resize: none;
  font: inherit; font-size: 13px; min-height: 40px;
  color: var(--ink-body);
}
.tdp-composer-foot { display: flex; gap: 6px; align-items: center; margin-top: 8px; }
.tdp-composer-foot .tip { font-size: 11px; color: var(--ink-faint); margin-right: auto; }

/* Right rail */
.tdp-side { background: white; border-left: 1px solid var(--border); padding: 24px 22px; overflow-y: auto; }
.tdp-side-h { font-size: 11px; font-weight: 700; color: var(--ink-muted);
              letter-spacing: 0.1em; text-transform: uppercase; margin: 0 0 12px; }
.tdp-prop { display: flex; flex-direction: column; gap: 4px; margin-bottom: 14px; }
.tdp-prop dt { font-size: 11px; color: var(--ink-muted); font-weight: 500; }
.tdp-prop dd { margin: 0; font-size: 13px; display: flex; align-items: center; gap: 6px; }

.tdp-attach {
  display: flex; gap: 10px; padding: 10px;
  border: 1px solid var(--border); border-radius: 8px;
  margin-bottom: 6px; background: var(--bg-subtle);
}
.tdp-attach-icon {
  width: 36px; height: 36px; border-radius: 6px;
  background: white; display: grid; place-items: center;
  font-size: 14px; font-weight: 700; color: var(--brand);
  border: 1px solid var(--border); flex-shrink: 0;
}
.tdp-attach .name { font-size: 13px; font-weight: 500; color: var(--ink-strong); }
.tdp-attach .meta { font-size: 11px; color: var(--ink-faint); }

.tdp-link-row {
  font-size: 13px; padding: 6px 10px;
  border-left: 3px solid var(--brand); margin-bottom: 4px;
  background: var(--bg-subtle); border-radius: 0 6px 6px 0;
  display: flex; align-items: center; gap: 8px;
}
.tdp-late-banner {
  background: linear-gradient(90deg, #fef4e6, #fef9f0);
  border: 1px solid #fbe0b6; border-left: 4px solid #d97f1f;
  padding: 12px 16px; border-radius: 8px;
  display: flex; gap: 12px; align-items: flex-start;
  margin: 0 0 18px;
}
.tdp-late-banner .ic { font-size: 18px; }
.tdp-late-banner .t { font-size: 13.5px; color: #6b3d0c; font-weight: 600; }
.tdp-late-banner .s { font-size: 12.5px; color: #855322; margin-top: 3px; line-height: 1.4; }
`;

if (typeof document !== "undefined" && !document.getElementById("task-detail-css")) {
  const s = document.createElement("style");
  s.id = "task-detail-css"; s.textContent = TASK_DETAIL_CSS;
  document.head.appendChild(s);
}

const TDP_REACTS = ["👍", "🎉", "👀"];

function TaskDetailPage({ task, onBack, onUpdate }) {
  const [tab, setTab] = React.useState("activity"); // activity | files | links
  const tdpDescRef = React.useRef(null);
  const tdpDescFileRef = React.useRef(null);

  React.useEffect(() => {
    if (tdpDescRef.current && task) {
      tdpDescRef.current.innerHTML = task.description || task._description || "";
    }
  }, [task?.id]);

  function tdpCommitDescription() {
    if (!tdpDescRef.current || !task) return;
    const html = tdpDescRef.current.innerHTML;
    const current = task.description || task._description || "";
    if (html !== current) {
      onUpdate && onUpdate(task.id, { _description: html, description: html });
    }
  }
  function tdpInsertHtmlAtCaret(html) {
    if (!tdpDescRef.current) return;
    tdpDescRef.current.focus();
    const sel = window.getSelection();
    let range;
    if (sel && sel.rangeCount > 0 && tdpDescRef.current.contains(sel.anchorNode)) {
      range = sel.getRangeAt(0);
    } else {
      range = document.createRange();
      range.selectNodeContents(tdpDescRef.current);
      range.collapse(false);
    }
    range.deleteContents();
    const tpl = document.createElement("template");
    tpl.innerHTML = html;
    const frag = tpl.content;
    const lastNode = frag.lastChild;
    range.insertNode(frag);
    if (lastNode && sel) {
      const r = document.createRange();
      r.setStartAfter(lastNode); r.collapse(true);
      sel.removeAllRanges(); sel.addRange(r);
    }
    tdpCommitDescription();
  }
  function tdpReadImageFile(file) {
    if (!file || !file.type || !file.type.startsWith("image/")) return;
    const reader = new FileReader();
    reader.onload = () => {
      const url = String(reader.result || "");
      if (!url) return;
      const safeName = (file.name || "image").replace(/"/g, "");
      tdpInsertHtmlAtCaret(`<img class="tdp-desc-img" src="${url}" alt="${safeName}" />`);
    };
    reader.readAsDataURL(file);
  }
  function tdpOnPaste(e) {
    const items = (e.clipboardData && e.clipboardData.items) || [];
    for (const it of items) {
      if (it && it.type && it.type.startsWith("image/")) {
        const f = it.getAsFile();
        if (f) { e.preventDefault(); tdpReadImageFile(f); return; }
      }
    }
  }
  function tdpOnDrop(e) {
    const files = e.dataTransfer && e.dataTransfer.files;
    if (!files || !files.length) return;
    const f = Array.from(files).find(x => x.type && x.type.startsWith("image/"));
    if (f) { e.preventDefault(); tdpReadImageFile(f); }
  }
  const [comments, setComments] = React.useState([
    { id: 1, who: "pr", text: "Blocked on design review — pinged @Hannah on Slack.", when: "6h ago", reacts: { "👍": ["mj"] } },
    { id: 2, who: "mj", text: "Pushed v1 to staging. Places API key is rotated. Please test edge cases with partial postcodes (UK addresses esp.).", when: "3h ago", reacts: { "🎉": ["ay","pr"] } },
  ]);
  const [events] = React.useState([
    { kind: "status",  who: "mj", text: "changed status from To Do to In Progress", when: "4h ago" },
    { kind: "owner",   who: "ay", text: "assigned Marcus Jin", when: "2d ago" },
    { kind: "create",  who: "ay", text: "created this task", when: "3d ago" },
  ]);
  const [draft, setDraft] = React.useState("");
  const [subs, setSubs] = React.useState([
    { id: 1, name: "Design address form with inline validation", done: true,  who: "pr" },
    { id: 2, name: "Integrate Google Places autocomplete API",   done: true,  who: "mj" },
    { id: 3, name: "Handle API rate-limit errors gracefully",    done: false, who: "mj" },
    { id: 4, name: "Add fallback to manual entry after 2 failures", done: false, who: "df" },
    { id: 5, name: "Unit tests for address normalization",       done: false, who: "le" },
  ]);

  if (!task) return null;

  const epic = task.epicId ? EPICS.find(e => e.id === task.epicId) : null;
  const sprintObj = SPRINTS.find(s => s.id === task.sprint);
  const doneCount = subs.filter(s => s.done).length;
  const subPct = subs.length ? (doneCount / subs.length) * 100 : 0;
  const late = isCompletedLate(task);

  function postComment() {
    const t = draft.trim(); if (!t) return;
    setComments(cs => [...cs, { id: Date.now(), who: "ay", text: t, when: "just now", reacts: {} }]);
    setDraft("");
  }
  function toggleReact(commentId, emoji) {
    setComments(cs => cs.map(c => {
      if (c.id !== commentId) return c;
      const next = { ...(c.reacts || {}) };
      const arr = next[emoji] || [];
      next[emoji] = arr.includes("ay") ? arr.filter(x => x !== "ay") : [...arr, "ay"];
      if (next[emoji].length === 0) delete next[emoji];
      return { ...c, reacts: next };
    }));
  }

  // Interleave comments + events by their "when" — for the prototype we
  // just show events first then comments chronologically.
  const stream = [
    ...events.map(e => ({ ...e, _kind: "event" })),
    ...comments.map(c => ({ ...c, _kind: "comment" })),
  ];

  return (
    <div className="tdp">
      <div className="tdp-header">
        <button className="tdp-back" onClick={onBack}>
          <Icons.ChevronRt size={14} style={{ transform: "rotate(180deg)" }}/> Back to board
        </button>
        <div className="tdp-bc">
          Checkout v2 <Icons.ChevronRt/> {epic?.title || "Quick tasks"} <Icons.ChevronRt/> <b>{task.name}</b>
        </div>
        <div className="tdp-id">#{(task.id || "").toUpperCase()}</div>
        <div className="tdp-actions">
          {/* Copy a shareable URL to this task. Uses the same
              CopyTaskLinkButton component the side drawer mounts;
              the URL is the hash form #/tasks/<id>, recognised by
              the global hash-watcher in app.jsx so pasting it in
              any tab lands the recipient on this exact task. */}
          {typeof CopyTaskLinkButton !== "undefined"
            ? <CopyTaskLinkButton task={task}/>
            : <button className="btn"><Icons.Link size={12}/> Copy link</button>}
          <button className="btn"><Icons.More size={12}/></button>
        </div>
      </div>

      <div className="tdp-body">
        {/* Left rail */}
        <aside className="tdp-rail">
          <div>
            <div className="rail-label" style={{ marginBottom: 6 }}>Status</div>
            <StatusPill status={task.status} fill={false}/>
          </div>
          <div>
            <div className="rail-label" style={{ marginBottom: 8 }}>Section</div>
            <div className={`rail-link is-active`}><Icons.Activity size={13}/> Activity</div>
            <div className="rail-link"><Icons.Paperclip size={13}/> Files <span style={{ marginLeft: "auto", fontSize: 11, color: "var(--ink-faint)" }}>3</span></div>
            <div className="rail-link"><Icons.Link size={13}/> Links <span style={{ marginLeft: "auto", fontSize: 11, color: "var(--ink-faint)" }}>2</span></div>
            <div className="rail-link"><Icons.GitBranch size={13}/> Subtasks <span style={{ marginLeft: "auto", fontSize: 11, color: "var(--ink-faint)" }}>{doneCount}/{subs.length}</span></div>
          </div>
          <div>
            <div className="rail-label" style={{ marginBottom: 6 }}>Watchers</div>
            <AvatarStack ids={task.owners || ["ay","mj"]} max={5} size="sm"/>
          </div>
        </aside>

        {/* Center */}
        <main className="tdp-center">
          {late && (
            <div className="tdp-late-banner">
              <span className="ic">⏱</span>
              <div>
                <div className="t">Completed {daysLate(task)} day{daysLate(task) === 1 ? "" : "s"} late</div>
                <div className="s">
                  Due <b>{task.due}</b> · Closed <b>{task.completedAt}</b>
                  {task.delayReason ? <> · Reason: <b>{(DELAY_REASONS.find(r => r.id === task.delayReason) || {}).label}</b></> : null}
                  {task.delayNote ? <><br/>“{task.delayNote}”</> : null}
                </div>
              </div>
            </div>
          )}

          <div className="tdp-title-row">
            <h1 className="tdp-title" contentEditable suppressContentEditableWarning
                onBlur={(e) => onUpdate && onUpdate(task.id, { name: e.currentTarget.textContent.trim() })}>
              {task.name}
            </h1>
          </div>

          <div className="tdp-pillrow">
            <StatusPill status={task.status} fill={false}/>
            <PriorityPill prio={task.prio} fill={false}/>
            <span className="sprint-tag"><span className="dot"/>{sprintObj?.label || "No sprint"}</span>
            <OutcomePill task={task}/>
            <LateBadge task={task}/>
          </div>

          <div className="tdp-section">
            <div className="tdp-section-h tdp-desc-head">
              <span>Description</span>
              <div className="tdp-desc-tools">
                <button type="button" className="tdp-desc-tool"
                        onClick={() => tdpDescFileRef.current?.click()}
                        title="Insert image">
                  <Icons.Image size={13}/> Add image
                </button>
                <input ref={tdpDescFileRef} type="file" accept="image/*"
                       style={{ display: "none" }}
                       onChange={(e) => {
                         const f = e.target.files && e.target.files[0];
                         if (f) tdpReadImageFile(f);
                         e.target.value = "";
                       }}/>
              </div>
            </div>
            <div ref={tdpDescRef}
                 className="tdp-desc"
                 contentEditable suppressContentEditableWarning
                 data-placeholder="Add a description… (paste or drop images)"
                 onBlur={tdpCommitDescription}
                 onPaste={tdpOnPaste}
                 onDragOver={(e) => e.preventDefault()}
                 onDrop={tdpOnDrop}/>
          </div>

          <div className="tdp-section">
            <div className="tdp-section-h">
              <Icons.GitBranch size={14}/> Subtasks <span className="count">· {doneCount} of {subs.length} done</span>
            </div>
            <div className="tdp-progress"><div className="tdp-progress-fill" style={{ width: `${subPct}%` }}/></div>
            {subs.map(s => (
              <div key={s.id} className={`tdp-subtask ${s.done ? "done" : ""}`}>
                <span className="checkbox" onClick={() => setSubs(list => list.map(x => x.id === s.id ? { ...x, done: !x.done } : x))}>
                  {s.done && <Icons.Check size={11}/>}
                </span>
                <span className="name">{s.name}</span>
                <span className="meta">
                  {(() => { const p = PEOPLE.find(p => p.id === s.who); return p ? <Avatar person={p} size="sm"/> : null; })()}
                </span>
              </div>
            ))}
          </div>

          <div className="tdp-section">
            <div className="tdp-section-h">
              <Icons.Activity size={14}/> Activity <span className="count">· {events.length + comments.length} entries</span>
            </div>
            <div className="tdp-composer">
              <Avatar person={PEOPLE[0]} size="sm"/>
              <div style={{ flex: 1 }}>
                <textarea rows={2} value={draft}
                          onChange={(e) => setDraft(e.target.value)}
                          onKeyDown={(e) => { if (e.key === "Enter" && (e.metaKey || e.ctrlKey)) postComment(); }}
                          placeholder="Write a comment… (⌘+Enter to post)"/>
                <div className="tdp-composer-foot">
                  <span className="tip">Markdown supported · @mention to ping</span>
                  <button className="btn btn-primary" onClick={postComment} disabled={!draft.trim()}>Comment</button>
                </div>
              </div>
            </div>

            <div className="tdp-activity" style={{ marginTop: 18 }}>
              {stream.map((s, i) => s._kind === "event" ? (
                <div key={"e"+i} className="tdp-event">
                  <span className="tdp-event-icon">{s.kind === "status" ? "↻" : s.kind === "owner" ? "@" : "✦"}</span>
                  <div>
                    <b>{(PEOPLE.find(p => p.id === s.who) || {}).name}</b> {s.text}
                    <span className="when">{s.when}</span>
                  </div>
                </div>
              ) : (
                <div key={"c"+i} className="tdp-comment">
                  <Avatar person={PEOPLE.find(p => p.id === s.who)} size="sm"/>
                  <div className="body">
                    <div className="head">
                      <span className="name">{(PEOPLE.find(p => p.id === s.who) || {}).name}</span>
                      <span className="when">{s.when}</span>
                    </div>
                    <div className="text">{s.text}</div>
                    <div className="reacts">
                      {Object.entries(s.reacts || {}).map(([emo, who]) => (
                        <span key={emo} className={`tdp-react ${who.includes("ay") ? "is-on" : ""}`}
                              onClick={() => toggleReact(s.id, emo)}>{emo} {who.length}</span>
                      ))}
                      {TDP_REACTS.filter(e => !s.reacts || !s.reacts[e]).map(emo => (
                        <span key={emo} className="tdp-react" onClick={() => toggleReact(s.id, emo)}>{emo}</span>
                      ))}
                    </div>
                  </div>
                </div>
              ))}
            </div>
          </div>
        </main>

        {/* Right rail — properties */}
        <aside className="tdp-side">
          <div className="tdp-side-h">Details</div>

          <dl className="tdp-prop"><dt>Assignees</dt><dd><AvatarStack ids={task.owners || ["ay"]} max={5} size="sm"/></dd></dl>
          <dl className="tdp-prop"><dt>Sprint</dt><dd>{sprintObj ? <span className="sprint-tag"><span className="dot"/>{sprintObj.label}</span> : "—"}</dd></dl>
          <dl className="tdp-prop"><dt>Epic</dt><dd>{epic ? <><span style={{ width: 10, height: 10, borderRadius: 3, background: epic.color }}/> {epic.title}</> : "—"}</dd></dl>
          <dl className="tdp-prop"><dt>Priority</dt><dd><PriorityPill prio={task.prio} fill={false}/></dd></dl>
          <dl className="tdp-prop"><dt>Due date</dt><dd><Icons.Calendar size={13}/> {task.due}</dd></dl>
          <dl className="tdp-prop"><dt>Story points</dt><dd><span className="points" style={{ background: "var(--brand)", color: "white" }}>{task.points}</span></dd></dl>
          <dl className="tdp-prop"><dt>Outcome</dt><dd><OutcomePill task={task}/></dd></dl>
          {task.completedAt && <dl className="tdp-prop"><dt>Completed</dt><dd>{task.completedAt}</dd></dl>}
          <dl className="tdp-prop"><dt>Reporter</dt><dd><Avatar person={PEOPLE[0]} size="sm"/> Aya Okafor</dd></dl>
          <dl className="tdp-prop"><dt>Labels</dt><dd>
            <span className="pill pill-prio-low" style={{ fontSize: 10 }}>frontend</span>
            <span className="pill pill-prio-medium" style={{ fontSize: 10 }}>checkout</span>
          </dd></dl>

          <div className="tdp-side-h" style={{ marginTop: 24 }}>Files (3)</div>
          <div className="tdp-attach">
            <div className="tdp-attach-icon">IMG</div>
            <div><div className="name">checkout-mockup.png</div><div className="meta">412 KB · Marcus, 2d</div></div>
          </div>
          <div className="tdp-attach">
            <div className="tdp-attach-icon">PDF</div>
            <div><div className="name">PCI-spec-v3.pdf</div><div className="meta">2.1 MB · Hannah, 5d</div></div>
          </div>
          <div className="tdp-attach">
            <div className="tdp-attach-icon" style={{ color: "var(--status-todo)" }}>↗</div>
            <div><div className="name">Figma — Address form v3</div><div className="meta">figma.com · Aya, 1w</div></div>
          </div>

          <div className="tdp-side-h" style={{ marginTop: 24 }}>Linked items (2)</div>
          <div className="tdp-link-row"><span style={{ fontFamily: "monospace", fontSize: 11, color: "var(--ink-faint)" }}>blocks</span> Klarna BNPL integration</div>
          <div className="tdp-link-row"><span style={{ fontFamily: "monospace", fontSize: 11, color: "var(--ink-faint)" }}>related</span> A11y: VoiceOver field order</div>
        </aside>
      </div>
    </div>
  );
}

Object.assign(window, { TaskDetailPage });
