// Article page v3 — full dossier layout, all data from WP REST
// /article/?id=DA-XXXX → fetch slug → render original dossier design dynamically.

const qs_ = new URLSearchParams(location.search);
const pathMatch_ = location.pathname.match(/\/article\/(DA-[A-Za-z0-9-]+)/i);
const ARTICLE_ID = (pathMatch_ ? pathMatch_[1] : (qs_.get('id') || 'DA-0884-C')).toUpperCase();
const ARTICLE_SLUG = ARTICLE_ID.toLowerCase();

const m = (post, k, f = "") => {
  const v = post && post.meta && post.meta[k];
  return v !== undefined && v !== null && v !== "" ? v : f;
};
const mjson = (post, k) => {
  let raw = m(post, k, "");
  if (!raw) return [];
  // Meta is stored as base64(json) to survive WP slash sanitization of embedded quotes.
  if (!raw.trim().startsWith('[') && !raw.trim().startsWith('{')) {
    try { raw = decodeURIComponent(escape(atob(raw))); } catch { /* not b64, try raw */ }
  }
  try { return JSON.parse(raw); } catch { return []; }
};
const stripTags = (h) => (h || "").replace(/<[^>]+>/g, "").trim();

const Header = ({ post }) => (
  <header style={{ borderBottom: "1px solid #2a2620", padding: "22px 48px 18px", position: "relative" }}>
    <div style={{ position: "absolute", top: 0, left: 0, right: 0,
      background: "#8b0000", color: "#f4ecd8", fontFamily: "'JetBrains Mono',monospace",
      fontSize: 10, letterSpacing: 4, padding: "3px 48px",
      display: "flex", justifyContent: "space-between" }}>
      <span>// CLASSIFIED · 仅限内部阅览 · {m(post,'da_classification','PUBLIC')} //</span>
      <span>COPY 001 / 001</span>
    </div>
    <div style={{ display: "flex", justifyContent: "space-between", alignItems: "baseline", paddingTop: 14 }}>
      <a href="/" className="mono" style={{ fontSize: 11, letterSpacing: 2, color: "#a89b78" }}>
        ← 返回档案墙 / BACK TO ARCHIVE
      </a>
      <div className="mono" style={{ fontSize: 10, letterSpacing: 3, color: "#6a6257" }}>
        VOL. XII · ISSUE 04 · 2026 · 阅卷号 {ARTICLE_ID}
      </div>
    </div>
  </header>
);

// Article page uses the shared SiteNav (with hamburger + mobile menu) from chrome.jsx.
const Nav = () => <SiteNav current="ARCHIVE" />;

// Fixed bottom bar on mobile: back to archive + previous/next case.
// On desktop this is hidden by the .da-sticky-cta CSS rule.
const MobileStickyCTA = ({ post }) => {
  const [, force] = React.useState(0);
  React.useEffect(() => {
    const h = () => force(v => v + 1);
    window.addEventListener("da:data-ready", h);
    // tag body so the global CSS can reserve bottom padding
    document.body.classList.add("da-article");
    return () => {
      window.removeEventListener("da:data-ready", h);
      document.body.classList.remove("da-article");
    };
  }, []);
  const cid = ARTICLE_ID;
  const all = (window.CASES || []).slice().sort((a,b) => (b.published_ts||0) - (a.published_ts||0));
  const idx = all.findIndex(c => (c.id || "").toUpperCase() === cid);
  const next = idx >= 0 && idx < all.length - 1 ? all[idx + 1] : null;
  return (
    <div className="da-sticky-cta" role="navigation" aria-label="档案导航">
      <a href="/archive/">← 档案墙</a>
      {next ? (
        <a className="primary" href={`/article/${next.id}/`}>下一卷 · {next.id} →</a>
      ) : (
        <a className="primary" href="/">返回首页 →</a>
      )}
    </div>
  );
};

const Breadcrumb = ({ post }) => (
  <div style={{ padding: "10px 48px", fontFamily: "'JetBrains Mono',monospace",
    fontSize: 11, letterSpacing: 1.5, color: "#6a6257", borderBottom: "1px dashed #2a2620" }}>
    <a href="/">首页</a> / ARCHIVE <span style={{ color: "#4a443a" }}>›</span>{" "}
    <a href="/category/">{m(post,'da_category','档案')} · {m(post,'da_cat_en','FILE')}</a>{" "}
    <span style={{ color: "#4a443a" }}>›</span>{" "}
    <span style={{ color: "#a81515" }}>{ARTICLE_ID} · {stripTags(post.title.rendered)}</span>
  </div>
);

const TitleBlock = ({ post }) => {
  const feat = post._embedded && post._embedded['wp:featuredmedia'] && post._embedded['wp:featuredmedia'][0];
  const imgUrl = feat && feat.source_url;
  return (
    <section className="da-title-section" style={{ padding: "56px 48px 40px", display: "grid",
      gridTemplateColumns: "1.2fr 1fr", gap: 60, position: "relative" }}>
      <div>
        <div style={{ display: "flex", gap: 14, alignItems: "center", marginBottom: 24 }}>
          <div className="mono" style={{ fontSize: 11, letterSpacing: 2, color: "#8b0000",
            padding: "3px 10px", border: "1px solid #8b0000" }}>
            ▸ {m(post,'da_cat_en','FILE')} / {m(post,'da_category','档案')}
          </div>
          <span className="mono" style={{ fontSize: 12, letterSpacing: 1.5, color: "#a89b78" }}>
            FILE № <strong style={{ color: "#e8e2d0" }}>{ARTICLE_ID}</strong>
          </span>
          <span className="mono" style={{ fontSize: 11, color: "#6a6257", letterSpacing: 1 }}>
            {m(post,'da_date','—')}
          </span>
        </div>
        <h1 style={{ fontFamily: "'Noto Serif SC','EB Garamond',serif",
          fontSize: 54, fontWeight: 500, lineHeight: 1.15, letterSpacing: 1,
          color: "#f4ecd8", marginBottom: 16 }}
          dangerouslySetInnerHTML={{ __html: post.title.rendered }} />
        <div style={{ fontFamily: "'Special Elite',monospace", fontSize: 17,
          color: "#8a6f49", letterSpacing: 1, fontStyle: "italic", marginBottom: 26 }}>
          — {m(post,'da_title_en','')}
        </div>
        <p style={{ fontSize: 20, lineHeight: 1.6, color: "#c9bda0",
          fontStyle: "italic", borderLeft: "2px solid #8b0000",
          paddingLeft: 20, marginBottom: 32, textWrap: "pretty" }}
          dangerouslySetInnerHTML={{ __html: stripTags(m(post,'da_subtitle', stripTags(post.excerpt.rendered))) }} />
        <div className="mono" style={{ display: "flex", gap: 24, fontSize: 11,
          letterSpacing: 1.5, color: "#6a6257", flexWrap: "wrap" }}>
          <span>归档 · {m(post,'da_filed','—')}</span>
          <span>复审 · {m(post,'da_reviewed','—')}</span>
          <span>编辑 · {m(post,'da_editor','档案员 06')}</span>
          <span>字数 · {m(post,'da_word_count','—')}</span>
        </div>
      </div>
      <div style={{ position: "relative" }}>
        {imgUrl ? (
          <div style={{ position: "relative", border: "1px solid #2a2620",
            background: "#0a0806", maxHeight: 420, overflow: "hidden" }}>
            <img src={imgUrl} alt={stripTags(post.title.rendered)}
              style={{ width: "100%", height: "auto", maxHeight: 420,
                objectFit: "contain", display: "block",
                filter: "contrast(0.9) brightness(0.85) sepia(0.2)" }} />
            <div style={{ position: "absolute", top: 8, left: 10,
              fontFamily: "'JetBrains Mono',monospace", fontSize: 10,
              letterSpacing: 2, color: "rgba(200,185,150,0.9)",
              textShadow: "0 1px 2px rgba(0,0,0,0.8)" }}>
              + EVIDENCE · {ARTICLE_ID}
            </div>
          </div>
        ) : (
          <EvidencePlaceholder caseId={ARTICLE_ID} label={m(post,'da_cat_en','FILE')} seed={14} variant="kraft" />
        )}
        <div style={{ position: "absolute", top: 20, right: 20, zIndex: 3 }}>
          <Stamp text={m(post,'da_status_en','FILED').split(" ")[0]} rot={-10} size={1.6} />
        </div>
        <div style={{ position: "absolute", bottom: -14, left: 20, right: 20,
          background: "#14110f", border: "1px solid #2a2620", padding: "6px 12px",
          fontFamily: "'JetBrains Mono',monospace", fontSize: 10,
          letterSpacing: 1.5, color: "#a89b78" }}>
          {m(post,'da_cover_caption', '封面证物 · ' + ARTICLE_ID)}
        </div>
      </div>
    </section>
  );
};

const FactSheet = ({ post }) => {
  const cell = (label, value, red) => (
    <div>
      <div className="mono" style={{ fontSize: 10, letterSpacing: 2, color: "#6a6257", marginBottom: 4 }}>{label}</div>
      <div style={{ fontFamily: "'Special Elite',monospace", fontSize: 15,
        color: red ? "#a81515" : "#e8e2d0", letterSpacing: 0.5 }}>{value}</div>
    </div>
  );
  const cred = parseInt(m(post,'da_credibility','3'),10) || 3;
  const evidence = mjson(post,'da_evidence');
  const related = mjson(post,'da_related');
  return (
    <section className="da-fact-sheet" style={{ margin: "0 48px", border: "1px solid #2a2620", background: "#14110f" }}>
      <div className="da-fact-sheet-header" style={{ padding: "10px 24px", borderBottom: "1px solid #2a2620",
        display: "flex", justifyContent: "space-between", alignItems: "center", background: "#1a1612" }}>
        <span className="mono" style={{ fontSize: 11, letterSpacing: 3, color: "#a89b78" }}>
          ▸ 案件基本信息 / CASE FACT SHEET
        </span>
        <span className="mono da-fact-sheet-sub" style={{ fontSize: 10, letterSpacing: 2, color: "#6a6257" }}>
          本页所有数据经 §VII 条款审核 · 部分精度降级
        </span>
      </div>
      <div className="da-fact-sheet-grid" style={{ display: "grid", gridTemplateColumns: "repeat(6, 1fr)",
        gap: 24, padding: "20px 24px" }}>
        {cell("发生时间 / PERIOD", m(post,'da_date','—'))}
        {cell("结案时间 / CLOSED", m(post,'da_date_closed','—'))}
        {cell("事发地点 / LOCATION", m(post,'da_loc_name', m(post,'da_loc','—')))}
        {cell("精确坐标 / COORDINATES", m(post,'da_loc_coord','—'))}
        {cell("案件状态 / STATUS", m(post,'da_status','—'), true)}
        {cell("目击 / 涉案 / WITNESSES", m(post,'da_witnesses','—'))}
      </div>
      <div className="da-fact-sheet-row" style={{ padding: "16px 24px", borderTop: "1px dashed #2a2620",
        display: "grid", gridTemplateColumns: "2fr 1fr 1fr", gap: 24, alignItems: "center" }}>
        <div>
          <div className="mono" style={{ fontSize: 10, letterSpacing: 2, color: "#6a6257", marginBottom: 4 }}>可信度评估 / CREDIBILITY</div>
          <div style={{ display: "flex", gap: 12, alignItems: "center" }}>
            <Credibility n={cred} />
            <span className="mono" style={{ fontSize: 11, color: "#a89b78" }}>{cred}/5 · 经公开资料交叉确认</span>
          </div>
        </div>
        <div>
          <div className="mono" style={{ fontSize: 10, letterSpacing: 2, color: "#6a6257", marginBottom: 4 }}>证物数量 / EVIDENCE</div>
          <div className="type" style={{ fontSize: 15 }}>{evidence.length || '—'} 项选录</div>
        </div>
        <div>
          <div className="mono" style={{ fontSize: 10, letterSpacing: 2, color: "#6a6257", marginBottom: 4 }}>相关案件 / LINKED</div>
          <div className="type" style={{ fontSize: 15 }}>{related.length || 0} 卷 · 见文末</div>
        </div>
      </div>
    </section>
  );
};

// Parse post.content.rendered into sectioned body. Splits on <h2> boundaries.
// Strips any embedded <figure> tags — inline images now come from da_inline_images meta.
function parseBodySections(html) {
  if (!html) return [];
  // Strip all <figure>...</figure> blocks from body HTML
  html = html.replace(/<figure\b[^>]*>[\s\S]*?<\/figure>/gi, '');
  const parser = new DOMParser();
  const doc = parser.parseFromString('<div>' + html + '</div>', 'text/html');
  const root = doc.body.firstChild;
  const out = [];
  let cur = null;
  for (const node of Array.from(root.childNodes)) {
    if (node.nodeType === 1 && node.tagName === 'H2') {
      if (cur) out.push(cur);
      cur = { heading: node.textContent.trim(), html: '' };
    } else {
      const h = node.nodeType === 1 ? node.outerHTML : (node.textContent || '');
      if (!cur) { cur = { heading: '', html: '' }; }
      cur.html += h;
    }
  }
  if (cur) out.push(cur);
  return out;
}

// Parse "40.7°N, 116.4°E (±12 km)" → {lat, lon}
function parseCoord(s) {
  if (!s) return null;
  const m = s.match(/(-?[\d.]+)\s*°?\s*([NS])?[,，\s]+\s*(-?[\d.]+)\s*°?\s*([EW])?/i);
  if (!m) return null;
  let lat = parseFloat(m[1]); if ((m[2]||'').toUpperCase() === 'S') lat = -lat;
  let lon = parseFloat(m[3]); if ((m[4]||'').toUpperCase() === 'W') lon = -lon;
  if (isNaN(lat) || isNaN(lon)) return null;
  return { lat, lon };
}

const LocationMap = ({ locName, locCoord }) => {
  const c = parseCoord(locCoord);
  // Zoom span in degrees — small bbox for city-level, wider if coarse
  const pad = 0.08;
  const osmSrc = c
    ? `https://www.openstreetmap.org/export/embed.html?bbox=${c.lon - pad*2},${c.lat - pad},${c.lon + pad*2},${c.lat + pad}&layer=mapnik&marker=${c.lat},${c.lon}`
    : null;
  const externalLink = c ? `https://www.openstreetmap.org/?mlat=${c.lat}&mlon=${c.lon}#map=10/${c.lat}/${c.lon}` : null;
  return (
    <div style={{ border: "1px solid #2a2620", background: "#14110f" }}>
      <div className="mono" style={{ fontSize: 10, letterSpacing: 3, color: "#a81515", padding: "14px 20px 8px" }}>
        ▸ 事发位置 / LOCATION
      </div>
      <div style={{ position: "relative", height: 200,
        borderTop: "1px solid #2a2620", borderBottom: "1px solid #2a2620",
        overflow: "hidden", background: "#0a0806" }}>
        {osmSrc ? (
          <>
            <iframe
              src={osmSrc}
              title="事发位置"
              loading="lazy"
              style={{
                width: "100%", height: "100%", border: 0, display: "block",
                filter: "invert(0.92) hue-rotate(200deg) saturate(0.7) brightness(0.95) contrast(1.05)",
              }}
            />
            {/* Crosshair overlay on top of map center */}
            <div style={{ position: "absolute", top: "50%", left: "50%",
              transform: "translate(-50%, -50%)", pointerEvents: "none" }}>
              <svg width="48" height="48" viewBox="0 0 48 48">
                <circle cx="24" cy="24" r="18" fill="rgba(139,0,0,0.15)" stroke="#a81515" strokeWidth="0.8" strokeDasharray="3 3"/>
                <circle cx="24" cy="24" r="8" fill="rgba(139,0,0,0.25)" stroke="#a81515" strokeWidth="1"/>
                <circle cx="24" cy="24" r="2" fill="#a81515"/>
                <line x1="24" y1="2" x2="24" y2="12" stroke="#a81515" strokeWidth="1"/>
                <line x1="24" y1="36" x2="24" y2="46" stroke="#a81515" strokeWidth="1"/>
                <line x1="2" y1="24" x2="12" y2="24" stroke="#a81515" strokeWidth="1"/>
                <line x1="36" y1="24" x2="46" y2="24" stroke="#a81515" strokeWidth="1"/>
              </svg>
            </div>
            {/* Corner label */}
            <div className="mono" style={{ position: "absolute", top: 6, left: 8,
              fontSize: 9, letterSpacing: 2, color: "rgba(232,226,208,0.85)",
              background: "rgba(10,6,4,0.7)", padding: "2px 6px",
              textShadow: "0 1px 2px #000" }}>
              OSM · 坐标精度降级
            </div>
          </>
        ) : (
          <svg viewBox="0 0 300 200" style={{ position: "absolute", inset: 0, width: "100%", height: "100%" }}>
            <g transform="translate(150 100)">
              <circle r="22" fill="rgba(139,0,0,0.15)" stroke="#a81515" strokeWidth="0.6" strokeDasharray="2 3"/>
              <circle r="3" fill="#a81515"/>
            </g>
            <text x="150" y="140" fontSize="10" fontFamily="monospace" textAnchor="middle" fill="#a89b78">坐标未提供</text>
          </svg>
        )}
      </div>
      <div style={{ padding: "12px 20px 16px" }}>
        <div className="type" style={{ fontSize: 14, color: "#e8e2d0", lineHeight: 1.4 }}>{locName}</div>
        <div className="mono" style={{ fontSize: 11, color: "#a81515", marginTop: 4, letterSpacing: 1.5 }}>
          ✚ {locCoord}
        </div>
        {externalLink && (
          <a href={externalLink} target="_blank" rel="noopener"
            className="mono" style={{ display: "inline-block", marginTop: 8, fontSize: 10,
              letterSpacing: 1.5, color: "#6a6257", borderBottom: "1px dashed #2a2620",
              paddingBottom: 1 }}>
            在 OpenStreetMap 打开 →
          </a>
        )}
      </div>
    </div>
  );
};

// Figure block — reused for inline body images
const Figure = ({ src, caption }) => (
  <figure className="da-figure" style={{ margin: "28px 0" }}>
    <img src={src} alt={caption || ''} style={{ width: "100%", display: "block",
      border: "1px solid #2a2620", filter: "contrast(.95) brightness(.9) sepia(.15)" }} />
    {caption && (
      <figcaption style={{ fontFamily: "'JetBrains Mono',monospace", fontSize: 11,
        color: "#8a6f49", letterSpacing: 1, padding: "8px 2px 0",
        borderTop: "1px dashed #2a2620", marginTop: 6 }}>{caption}</figcaption>
    )}
  </figure>
);

const ArticleBody = ({ post }) => {
  const sections = parseBodySections(post.content.rendered);
  const rawEvidence = mjson(post, 'da_evidence');
  const sources = mjson(post, 'da_sources');
  const inline = mjson(post, 'da_inline_images');
  // Cover URL (featured image) for evidence fallback
  const feat = post._embedded && post._embedded['wp:featuredmedia'] && post._embedded['wp:featuredmedia'][0];
  const coverUrl = feat && feat.source_url;
  // Build unique fallback pool from cover + all inline images (dedupe)
  const seen = new Set();
  const imgPool = [coverUrl, ...inline.map(i => i?.src)].filter(u => {
    if (!u || seen.has(u)) return false;
    seen.add(u); return true;
  });
  // Fill empty evidence slots with unique fallbacks only; if pool exhausted, leave null
  // (JSX will render EvidencePlaceholder). Prefer explicit e.img; avoid duplicating what's
  // already assigned to a prior evidence slot.
  const usedImgs = new Set(rawEvidence.map(e => e.img).filter(Boolean));
  let fallbackIdx = 0;
  const evidence = rawEvidence.map((e) => {
    if (e.img) return { ...e };
    while (fallbackIdx < imgPool.length && usedImgs.has(imgPool[fallbackIdx])) fallbackIdx++;
    if (fallbackIdx < imgPool.length) {
      const pick = imgPool[fallbackIdx++];
      usedImgs.add(pick);
      return { ...e, img: pick };
    }
    return { ...e, img: null };
  });
  return (
    <article className="da-article-body" style={{ padding: "56px 48px 40px",
      display: "grid", gridTemplateColumns: "minmax(0, 680px) 1fr",
      gap: 56, alignItems: "start" }}>
      <div className="da-article-main">
        {sections.map((s, i) => (
          <React.Fragment key={i}>
            <section style={{ marginBottom: 40 }}>
              {s.heading && (
                <h2 style={{ fontFamily: "'Noto Serif SC','EB Garamond',serif",
                  fontSize: 26, fontWeight: 500, color: "#f4ecd8",
                  borderBottom: "1px solid #2a2620", paddingBottom: 10,
                  marginBottom: 20, letterSpacing: 1 }}>{s.heading}</h2>
              )}
              <div className="da-body-section"
                dangerouslySetInnerHTML={{ __html: s.html }} />
            </section>
            {/* Inject inline body images after §1 and §2 */}
            {inline[0] && i === 0 && <Figure src={inline[0].src} caption={inline[0].cap} />}
            {inline[1] && i === 1 && <Figure src={inline[1].src} caption={inline[1].cap} />}
          </React.Fragment>
        ))}

        {/* § 5 Evidence */}
        {evidence.length > 0 && (
          <section style={{ marginTop: 48 }}>
            <h2 style={{ fontFamily: "'Noto Serif SC',serif", fontSize: 24,
              fontWeight: 500, color: "#f4ecd8", borderBottom: "1px solid #2a2620",
              paddingBottom: 10, marginBottom: 20, letterSpacing: 1 }}>§ 5 · 证物选录</h2>
            <div className="da-evidence-grid" style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 20 }}>
              {evidence.map((e, i) => (
                <div key={e.id || i} className="da-evidence-card" style={{ border: "1px solid #2a2620", background: "#14110f" }}>
                  {e.img ? (
                    <div style={{ position: "relative", aspectRatio: "4/3", overflow: "hidden", background: "#0a0806" }}>
                      <img src={e.img} alt={e.label || ''}
                        style={{ width: "100%", height: "100%", objectFit: "cover", display: "block",
                          filter: "contrast(.95) brightness(.82) sepia(.18)" }} />
                      <div className="mono" style={{ position: "absolute", top: 8, left: 10, fontSize: 9,
                        letterSpacing: 2, color: "rgba(200,185,150,0.85)",
                        textShadow: "0 1px 2px rgba(0,0,0,0.8)" }}>+ {(e.label || '').split(" ")[0].slice(0,16)}</div>
                      <div className="mono" style={{ position: "absolute", top: 8, right: 10, fontSize: 9,
                        letterSpacing: 1, color: "rgba(200,185,150,0.7)",
                        textShadow: "0 1px 2px rgba(0,0,0,0.8)" }}>{e.id}</div>
                    </div>
                  ) : (
                    <EvidencePlaceholder caseId={e.id} label={(e.label || '').split(" ")[0].slice(0,16)}
                      seed={i*13+3} variant={i%2 === 0 ? "kraft" : "dark"} />
                  )}
                  <div style={{ padding: "12px 14px" }}>
                    <div className="mono" style={{ fontSize: 10, letterSpacing: 1.5, color: "#a81515", marginBottom: 4 }}>{e.id}</div>
                    <div style={{ fontFamily: "'Noto Serif SC',serif", fontSize: 15, color: "#f4ecd8", marginBottom: 4 }}>{e.label}</div>
                    <div className="mono" style={{ fontSize: 11, color: "#a89b78", lineHeight: 1.5 }}>{e.desc}</div>
                  </div>
                </div>
              ))}
            </div>
          </section>
        )}

        {/* § 6 Sources */}
        {sources.length > 0 && (
          <section style={{ marginTop: 48 }}>
            <h2 style={{ fontFamily: "'Noto Serif SC',serif", fontSize: 24,
              fontWeight: 500, color: "#f4ecd8", borderBottom: "1px solid #2a2620",
              paddingBottom: 10, marginBottom: 20, letterSpacing: 1 }}>§ 6 · 来源与参考</h2>
            <ol style={{ listStyle: "none", padding: 0 }}>
              {sources.map((s, i) => (
                <li key={i} className="da-source-row" style={{ display: "grid", gridTemplateColumns: "30px 1fr auto",
                  gap: 16, padding: "10px 0", borderBottom: "1px dashed #2a2620",
                  fontSize: 14, lineHeight: 1.5, color: "#c9bda0" }}>
                  <span className="mono" style={{ color: "#a81515" }}>[{String(i+1).padStart(2,"0")}]</span>
                  <span>{s.url ? <a href={s.url} target="_blank" rel="noopener nofollow">{s.label}</a> : s.label}</span>
                  <span className="mono" style={{ fontSize: 11, color: "#6a6257", letterSpacing: 1 }}>{s.note || ''}</span>
                </li>
              ))}
            </ol>
          </section>
        )}

        {/* END OF FILE */}
        <div style={{ marginTop: 60, paddingTop: 28, borderTop: "1px solid #2a2620",
          display: "flex", justifyContent: "space-between", alignItems: "center" }}>
          <div>
            <div className="mono" style={{ fontSize: 10, letterSpacing: 3, color: "#6a6257", marginBottom: 6 }}>
              // 本卷宗结束 / END OF FILE
            </div>
            <div style={{ fontStyle: "italic", color: "#a89b78" }}>
              如您掌握本案未公开的信息，可匿名寄往 <span className="mono" style={{ color: "#a81515" }}>aidarkfile@gmail.com</span>
            </div>
          </div>
          <Stamp text="ARCHIVED" rot={-6} size={1.4} />
        </div>
      </div>

      <Sidebar post={post} sections={sections} />

      <style>{`
        .da-body-section p{font-family:'Noto Serif SC','EB Garamond',serif;font-size:17px;line-height:1.9;
          color:#d4c9a8;margin:0 0 18px;text-indent:2em;text-wrap:pretty}
        .da-body-section h3{font-family:'Noto Serif SC',serif;font-size:20px;color:#e8e2d0;margin:24px 0 10px;letter-spacing:.5px}
        .da-body-section a{color:#a81515;border-bottom:1px solid rgba(168,21,21,.4)}
        .da-body-section img{max-width:100%;height:auto;margin:22px 0;border:1px solid #2a2620;filter:contrast(.95) brightness(.9) sepia(.15)}
        .da-body-section figure{margin:24px 0}
        .da-body-section figcaption{font-family:'JetBrains Mono',monospace;font-size:11px;
          color:#8a6f49;letter-spacing:1px;padding-top:8px;border-top:1px dashed #2a2620;margin-top:6px}
        .da-body-section blockquote{border-left:3px solid #8b0000;background:#14110f;
          padding:16px 22px;margin:22px 0;font-family:'Special Elite',monospace;
          font-size:16px;line-height:1.7;color:#e8e2d0;font-style:italic;text-indent:0}
        .da-body-section table{width:100%;border-collapse:collapse;margin:24px 0;font-size:14px;text-indent:0}
        .da-body-section th,.da-body-section td{border:1px solid #2a2620;padding:10px 14px;text-align:left}
        .da-body-section th{background:#1a1612;color:#f4ecd8;font-family:'JetBrains Mono',monospace;font-size:12px;letter-spacing:2px}
        .da-body-section .tldr{background:#1a1612;border:1px solid #8b0000;padding:18px 24px;
          margin:0 0 28px;font-size:16px;line-height:1.75;text-indent:0}
        .da-body-section .tldr strong{color:#a81515;font-family:'JetBrains Mono',monospace;
          letter-spacing:2px;display:block;margin-bottom:8px}
      `}</style>
    </article>
  );
};

const Sidebar = ({ post, sections }) => {
  const timeline = mjson(post, 'da_timeline');
  const tags = (m(post,'da_tags','') || '').split(',').map(s => s.trim()).filter(Boolean);
  const locName = m(post,'da_loc_name', m(post,'da_loc','—'));
  const locCoord = m(post,'da_loc_coord','—');
  const toc = sections.map(s => s.heading).filter(Boolean);
  const evidence = mjson(post, 'da_evidence');
  const sources = mjson(post, 'da_sources');
  return (
    <aside className="da-article-sidebar" style={{ position: "sticky", top: 20, display: "flex", flexDirection: "column", gap: 24 }}>
      {/* TOC */}
      <div style={{ border: "1px solid #2a2620", background: "#14110f", padding: "18px 20px" }}>
        <div className="mono" style={{ fontSize: 10, letterSpacing: 3, color: "#a81515", marginBottom: 12 }}>
          ▸ 目录 / CONTENTS
        </div>
        <ol style={{ listStyle: "none", padding: 0, display: "flex", flexDirection: "column", gap: 10 }}>
          {toc.map((t, i) => (
            <li key={i} style={{ display: "grid", gridTemplateColumns: "34px 1fr", gap: 10,
              borderLeft: "2px solid transparent", paddingLeft: 10,
              fontSize: 13, color: "#a89b78" }}>
              <span className="mono" style={{ color: "#6a6257" }}>§ {i+1}</span>
              <span>{t.replace(/^§\s*\d+\s*·?\s*/, '')}</span>
            </li>
          ))}
          {evidence.length > 0 && (
            <li style={{ display:"grid",gridTemplateColumns:"34px 1fr",gap:10,paddingLeft:10,fontSize:13,color:"#a89b78"}}>
              <span className="mono" style={{color:"#6a6257"}}>§ {toc.length+1}</span><span>证物选录</span>
            </li>
          )}
          {sources.length > 0 && (
            <li style={{ display:"grid",gridTemplateColumns:"34px 1fr",gap:10,paddingLeft:10,fontSize:13,color:"#a89b78"}}>
              <span className="mono" style={{color:"#6a6257"}}>§ {toc.length+2}</span><span>来源与参考</span>
            </li>
          )}
        </ol>
      </div>

      {/* Timeline */}
      {timeline.length > 0 && (
        <div style={{ border: "1px solid #2a2620", background: "#14110f", padding: "18px 20px" }}>
          <div className="mono" style={{ fontSize: 10, letterSpacing: 3, color: "#a81515", marginBottom: 14 }}>
            ▸ 事件时间线 / TIMELINE
          </div>
          <div style={{ position: "relative", paddingLeft: 18 }}>
            <div style={{ position: "absolute", left: 5, top: 6, bottom: 6, width: 1, background: "#2a2620" }} />
            {timeline.map((t, i) => (
              <div key={i} style={{ position: "relative", paddingBottom: 18 }}>
                <div style={{ position: "absolute", left: -17, top: 5,
                  width: 9, height: 9, border: "1px solid #a81515",
                  background: "#0a0a0a", transform: "rotate(45deg)" }} />
                <div className="mono" style={{ fontSize: 10, color: "#a81515",
                  letterSpacing: 1.5, marginBottom: 3 }}>
                  {t.t} · {t.label}
                </div>
                <div style={{ fontSize: 12.5, lineHeight: 1.55, color: "#c9bda0",
                  marginBottom: 4, textWrap: "pretty" }}>{t.desc}</div>
                {t.tag && (
                  <div className="mono" style={{ fontSize: 10, color: "#6a6257", fontStyle: "italic" }}>{t.tag}</div>
                )}
              </div>
            ))}
          </div>
        </div>
      )}

      {/* Location — real OpenStreetMap with dark filter */}
      <LocationMap locName={locName} locCoord={locCoord} />

      {/* Tags */}
      {tags.length > 0 && (
        <div style={{ border: "1px solid #2a2620", background: "#14110f", padding: "16px 20px" }}>
          <div className="mono" style={{ fontSize: 10, letterSpacing: 3, color: "#a81515", marginBottom: 10 }}>
            ▸ 标签 / TAGS
          </div>
          <div className="da-tag-list" style={{ display: "flex", flexWrap: "wrap", gap: 6 }}>
            {tags.map(t => (
              <a key={t} href={`/search/?q=${encodeURIComponent(t)}`} className="mono" style={{
                fontSize: 10, letterSpacing: 1, padding: "3px 9px",
                border: "1px solid #2a2620", color: "#a89b78" }}>#{t}</a>
            ))}
          </div>
        </div>
      )}

      {/* Notice */}
      <div style={{ border: "1px solid #2a2620", padding: "14px 18px", background: "#1a0808" }}>
        <div className="mono" style={{ fontSize: 10, letterSpacing: 3, color: "#a81515", marginBottom: 8 }}>
          ! 阅读须知 / NOTE
        </div>
        <div style={{ fontSize: 12, lineHeight: 1.6, color: "#c9bda0", fontStyle: "italic" }}>
          本站收录内容皆为公开资料之再整理。部分证物、坐标、姓名已做降级与脱敏处理。不构成司法结论，亦不鼓励读者前往任何事发现场。
        </div>
      </div>
    </aside>
  );
};

const RelatedStrip = ({ post }) => {
  const related = mjson(post, 'da_related');
  if (!related.length) return null;
  return (
    <section style={{ padding: "40px 48px", borderTop: "1px solid #2a2620" }}>
      <div style={{ display: "flex", justifyContent: "space-between", alignItems: "baseline", marginBottom: 20 }}>
        <h2 style={{ fontSize: 20, fontWeight: 500, letterSpacing: 4, color: "#e8e2d0" }}>
          相关案件 <span className="mono" style={{ fontSize: 12, color: "#6a6257", letterSpacing: 2, marginLeft: 10 }}>/ LINKED FILES · {related.length}</span>
        </h2>
        <a href="/map/" className="mono" style={{ fontSize: 11, letterSpacing: 2, color: "#a81515" }}>查看全部红线关联 →</a>
      </div>
      <div className="da-related-grid" style={{ display: "grid", gridTemplateColumns: "repeat(3, 1fr)", gap: 20 }}>
        {related.map(r => (
          <a key={r.id} href={`/article/${r.id}/`} style={{
            border: "1px solid #2a2620", background: "#14110f",
            padding: "20px 22px", display: "flex", flexDirection: "column", gap: 8, position: "relative" }}>
            <div className="mono" style={{ fontSize: 10, letterSpacing: 2, color: "#8b0000" }}>
              ▸ {r.cat} · {r.id}
            </div>
            <div style={{ fontFamily: "'Noto Serif SC',serif", fontSize: 18, color: "#f4ecd8", lineHeight: 1.35 }}>{r.title}</div>
            <div className="type" style={{ fontSize: 12, color: "#a89b78", fontStyle: "italic",
              borderTop: "1px dashed #2a2620", paddingTop: 10, marginTop: 6 }}>关联 · {r.tie}</div>
            <div className="mono" style={{ fontSize: 10, color: "#6a6257", letterSpacing: 1.5 }}>阅卷 → OPEN FILE</div>
          </a>
        ))}
      </div>
    </section>
  );
};

const Footer = () => (
  <footer style={{ borderTop: "1px solid #2a2620", padding: "40px 48px 28px",
    display: "grid", gridTemplateColumns: "1fr 1fr 1fr", gap: 40, fontSize: 13 }}>
    <div>
      <div className="mono" style={{ fontSize: 10, letterSpacing: 3, color: "#6a6257", marginBottom: 10 }}>// 本站声明 / DISCLAIMER</div>
      <p style={{ lineHeight: 1.7, color: "#a89b78", fontStyle: "italic" }}>
        本站收录内容皆为公开资料之再整理与个人记录。所有观点不代表司法结论。
      </p>
    </div>
    <div>
      <div className="mono" style={{ fontSize: 10, letterSpacing: 3, color: "#6a6257", marginBottom: 10 }}>// 归档索引 / INDEX</div>
      <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: "4px 20px", color: "#c9bda0" }}>
        <a href="/archive/">· 按年份</a>
        <a href="/archive/">· 按地区</a>
        <a href="/category/">· 按类型</a>
        <a href="/archive/">· 按状态</a>
        <a href="/tag/">· 标签云</a>
        <a href="/about/">· RSS 订阅</a>
      </div>
    </div>
    <div style={{ textAlign: "right" }}>
      <Stamp text="ARCHIVED" rot={3} />
      <div className="mono" style={{ fontSize: 10, letterSpacing: 2, color: "#6a6257", marginTop: 20 }}>
        暗黑收集站 · EST. 2017<br/>
        © AI DARK FILE · ALL FILES RESERVED
      </div>
    </div>
  </footer>
);

const Loading = () => (
  <div style={{ minHeight: "60vh", display: "grid", placeItems: "center",
    fontFamily: "'JetBrains Mono',monospace", color: "#6a6257", letterSpacing: 3 }}>
    ▸ LOADING FILE · {ARTICLE_ID} · 正在解密...
  </div>
);

const NotFound = ({ msg }) => (
  <div style={{ minHeight: "60vh", display: "grid", placeItems: "center", textAlign: "center" }}>
    <div>
      <div className="mono" style={{ fontSize: 12, letterSpacing: 3, color: "#a81515", marginBottom: 12 }}>
        ▸ ERROR · 档案不存在或已封存
      </div>
      <div style={{ fontFamily: "'Noto Serif SC',serif", fontSize: 22, color: "#f4ecd8", marginBottom: 6 }}>
        未找到 {ARTICLE_ID}
      </div>
      <div style={{ fontSize: 13, color: "#6a6257", marginBottom: 22 }}>{msg}</div>
      <a href="/" className="mono" style={{ border: "1px solid #8b0000",
        padding: "8px 20px", color: "#a81515", letterSpacing: 2, fontSize: 12 }}>返回档案墙 →</a>
    </div>
  </div>
);

const App = () => {
  const [post, setPost] = React.useState(null);
  const [err, setErr] = React.useState(null);
  React.useEffect(() => {
    fetch(`/wp-json/wp/v2/posts?slug=${encodeURIComponent(ARTICLE_SLUG)}&_embed`)
      .then(r => r.json())
      .then(d => {
        if (!Array.isArray(d) || d.length === 0) setErr('Slug: ' + ARTICLE_SLUG);
        else {
          setPost(d[0]);
          document.title = stripTags(d[0].title.rendered) + ' · 暗黑收集站';
        }
      })
      .catch(e => setErr(String(e)));
  }, []);

  if (err) return (
    <>
      <div style={{ background: "#8b0000", color: "#f4ecd8", fontFamily: "'JetBrains Mono',monospace",
        fontSize: 10, letterSpacing: 4, padding: "3px 48px", display: "flex", justifyContent: "space-between" }}>
        <span>// CLASSIFIED · 仅限内部阅览 //</span><span>COPY 001 / 001</span>
      </div>
      <Nav />
      <NotFound msg={err} />
      <Footer />
    </>
  );
  if (!post) return <Loading />;

  return (
    <>
      <Header post={post} />
      <Nav />
      <Breadcrumb post={post} />
      <TitleBlock post={post} />
      <FactSheet post={post} />
      <ArticleBody post={post} />
      <RelatedStrip post={post} />
      <Footer />
      <MobileStickyCTA post={post} />
    </>
  );
};

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