// Anna's Wall — DESKTOP. Two-pane reader for a normal desktop browser.
// Reuses canonical kit primitives (H, HCard, HAnnaAvatar, HealifyMark, HChevron,
// HPrimaryButton) + Wall components (wall-components.jsx) + detail sub-parts from
// wall-screens.jsx (WallDetailHero, VoicePlayerBar, WallReactionBar, WallCitations).
//
// Layout: top app bar (logo · nav · search · notifications · account)
//         └ body: post-list pane (fixed) + detail reading pane (fluid), each scrolls.

const { useState: useS, useRef: useR, useEffect: useE, useMemo: useM, useCallback: useC } = React;

const PAGE_SIZE_D = 4;

// ════════════════════════════════════════════════════════════════════════
// Store — fakes wall.service with latency (mirrors the mobile prototype).
// ════════════════════════════════════════════════════════════════════════
function useWallStoreD(feedState, forceReactError, onToast) {
  const seed = () => WALL_POSTS.map(p => ({ ...p, reactions: { ...p.reactions } }));
  const [posts, setPosts] = useS([]);
  const [userReactions, setUserReactions] = useS({});
  const [loading, setLoading] = useS(true);
  const [refreshing, setRefreshing] = useS(false);
  const [loadingMore, setLoadingMore] = useS(false);
  const [error, setError] = useS(false);
  const [hasMore, setHasMore] = useS(true);
  const timers = useR([]);
  const after = (ms, fn) => { const id = setTimeout(fn, ms); timers.current.push(id); };

  useE(() => {
    timers.current.forEach(clearTimeout); timers.current = [];
    setUserReactions({});
    if (feedState === 'loaded') { setLoading(false); setError(false); setRefreshing(false); setPosts(seed()); setHasMore(false); }
    else if (feedState === 'loading') { setLoading(true); setError(false); setPosts([]); setHasMore(true); }
    else if (feedState === 'empty') { setLoading(true); setError(false); setPosts([]); setHasMore(false); after(900, () => { setLoading(false); setPosts([]); }); }
    else if (feedState === 'error') { setLoading(true); setError(false); setPosts([]); setHasMore(false); after(850, () => { setLoading(false); setError(true); }); }
    else { setLoading(true); setError(false); setPosts([]); setHasMore(true); after(950, () => { setLoading(false); setPosts(seed().slice(0, PAGE_SIZE_D)); setHasMore(true); }); }
    return () => { timers.current.forEach(clearTimeout); timers.current = []; };
  }, [feedState]);

  const refresh = useC(() => {
    if (refreshing) return;
    setRefreshing(true); setError(false);
    after(800, () => {
      setRefreshing(false);
      if (feedState === 'empty') { setPosts([]); setHasMore(false); }
      else if (feedState === 'error') { setError(true); }
      else { setPosts(seed().slice(0, PAGE_SIZE_D)); setHasMore(true); }
    });
  }, [refreshing, feedState]);

  const loadMore = useC(() => {
    setLoadingMore(true);
    after(700, () => {
      setLoadingMore(false);
      setPosts(prev => {
        const all = seed();
        const next = all.slice(prev.length, prev.length + PAGE_SIZE_D);
        const merged = [...prev, ...next.filter(n => !prev.some(p => p.id === n.id))];
        setHasMore(merged.length < all.length);
        return merged;
      });
    });
  }, []);

  const markRead = useC((postId) => {
    setPosts(prev => prev.map(p => p.id === postId ? { ...p, readAt: new Date().toISOString() } : p));
  }, []);

  const react = useC((postId, key) => {
    const prevReaction = userReactions[postId];
    let snapPosts, snapRx;
    setPosts(prev => { snapPosts = prev; return prev.map(p => {
      if (p.id !== postId) return p;
      const r = { ...p.reactions };
      if (prevReaction === key) r[key] = Math.max(0, r[key] - 1);
      else { if (prevReaction) r[prevReaction] = Math.max(0, r[prevReaction] - 1); r[key] = r[key] + 1; }
      return { ...p, reactions: r };
    }); });
    setUserReactions(prev => { snapRx = prev; const n = { ...prev }; if (prevReaction === key) delete n[postId]; else n[postId] = key; return n; });
    if (forceReactError) setTimeout(() => { setPosts(snapPosts); setUserReactions(snapRx); onToast && onToast("Couldn't save your reaction"); }, 450);
  }, [userReactions, forceReactError, onToast]);

  return { posts, userReactions, loading, refreshing, loadingMore, error, hasMore, refresh, loadMore, markRead, react };
}

// ════════════════════════════════════════════════════════════════════════
// Top app bar
// ════════════════════════════════════════════════════════════════════════
function DeskNavItem({ label, active, onClick }) {
  return (
    <button onClick={onClick} style={{
      fontFamily: H.body, fontWeight: active ? 600 : 400, fontSize: 14.5,
      letterSpacing: -0.2, color: active ? H.fg1 : H.fg2,
      background: active ? 'var(--quartz-soft-bg)' : 'transparent',
      border: 0, padding: '8px 14px', borderRadius: 999, cursor: 'pointer',
      transition: 'background 140ms, color 140ms',
    }}>{label}</button>
  );
}

function DeskTopBar({ activeNav, onNav, unread, notifOpen, setNotifOpen, latestPost, onOpenNotif, onSimulate }) {
  return (
    <header style={{
      height: 62, flexShrink: 0, background: 'var(--surface-80, rgba(255,255,255,0.86))',
      backdropFilter: 'blur(18px) saturate(1.4)', WebkitBackdropFilter: 'blur(18px) saturate(1.4)',
      borderBottom: '1px solid var(--border-subtle)', display: 'flex', alignItems: 'center',
      padding: '0 22px', gap: 18, position: 'relative', zIndex: 50,
    }}>
      {/* brand */}
      <div style={{ display: 'flex', alignItems: 'center', gap: 10, flexShrink: 0 }}>
        <HealifyMark size={30} />
        <span style={{ fontFamily: H.display, fontWeight: 600, fontSize: 19, letterSpacing: -0.4, color: H.fg1 }}>Healify</span>
      </div>

      {/* primary nav */}
      <nav style={{ display: 'flex', alignItems: 'center', gap: 2, marginLeft: 8 }}>
        {['Home', 'Fitness', 'Wall', 'Progress', 'More'].map(n => (
          <DeskNavItem key={n} label={n} active={activeNav === n} onClick={() => onNav(n)} />
        ))}
      </nav>

      <div style={{ flex: 1 }} />

      {/* search */}
      <div style={{
        display: 'flex', alignItems: 'center', gap: 8, height: 38, padding: '0 14px',
        background: H.bgSecondary, borderRadius: 999, minWidth: 220, color: H.fg3,
      }}>
        <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.9" strokeLinecap="round" strokeLinejoin="round"><circle cx="11" cy="11" r="7" /><path d="m20 20-3.2-3.2" /></svg>
        <span style={{ fontFamily: H.body, fontSize: 13.5 }}>Search your wall</span>
      </div>

      {/* notifications (desktop deep-link demo) */}
      <div style={{ position: 'relative' }}>
        <button onClick={() => setNotifOpen(o => !o)} aria-label="Notifications" style={{
          width: 40, height: 40, borderRadius: 999, border: 0, background: notifOpen ? H.bgSecondary : 'transparent',
          display: 'grid', placeItems: 'center', cursor: 'pointer', position: 'relative',
        }}>
          <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke={H.fg1} strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"><path d="M18 8a6 6 0 0 0-12 0c0 7-3 9-3 9h18s-3-2-3-9" /><path d="M13.7 21a2 2 0 0 1-3.4 0" /></svg>
          {unread > 0 && <span style={{ position: 'absolute', top: 6, right: 6, minWidth: 16, height: 16, padding: '0 4px', boxSizing: 'border-box', borderRadius: 999, background: 'var(--brand-orange-vibey)', border: '2px solid var(--bg-app)', color: '#fff', fontFamily: H.body, fontWeight: 600, fontSize: 9.5, display: 'grid', placeItems: 'center', lineHeight: 1 }}>{unread}</span>}
        </button>
        {notifOpen && (
          <NotifPanel latestPost={latestPost} unread={unread} onOpenNotif={onOpenNotif} onSimulate={onSimulate} onClose={() => setNotifOpen(false)} />
        )}
      </div>

      {/* account */}
      <div style={{ display: 'flex', alignItems: 'center', gap: 9, paddingLeft: 4 }}>
        <div style={{ width: 38, height: 38, borderRadius: 999, background: H.black, display: 'grid', placeItems: 'center', color: '#fff', fontFamily: H.body, fontWeight: 600, fontSize: 14, letterSpacing: 0.3 }}>K</div>
      </div>
    </header>
  );
}

function NotifPanel({ latestPost, unread, onOpenNotif, onSimulate, onClose }) {
  return (
    <>
      <div onClick={onClose} style={{ position: 'fixed', inset: 0, zIndex: 60 }} />
      <div style={{
        position: 'absolute', top: 48, right: 0, width: 340, zIndex: 61,
        background: '#fff', borderRadius: 18, boxShadow: '0 18px 50px rgba(3,4,13,0.18), 0 0 0 0.5px rgba(3,4,13,0.05)',
        overflow: 'hidden', animation: 'deskPop 180ms cubic-bezier(.22,.7,.3,1) both',
      }}>
        <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', padding: '14px 16px 10px' }}>
          <span style={{ fontFamily: H.body, fontWeight: 600, fontSize: 15, color: H.fg1 }}>Notifications</span>
          <span style={{ fontFamily: H.body, fontSize: 12, color: H.fg3 }}>{unread} unread</span>
        </div>
        {latestPost ? (
          <div onClick={() => { onOpenNotif(latestPost.id); onClose(); }} style={{
            display: 'flex', gap: 11, padding: '12px 16px', cursor: 'pointer', borderTop: '0.5px solid ' + H.border,
            background: latestPost.readAt === null ? 'linear-gradient(180deg, rgba(255,244,240,0.6), #fff)' : '#fff',
          }}>
            <div style={{ width: 34, height: 34, borderRadius: 8, overflow: 'hidden', flexShrink: 0 }}><HealifyMark size={34} /></div>
            <div style={{ flex: 1, minWidth: 0 }}>
              <div style={{ fontFamily: H.body, fontWeight: 600, fontSize: 13.5, color: H.fg1 }}>New insight from Anna</div>
              <div style={{ fontFamily: H.body, fontSize: 12.5, lineHeight: 1.35, color: H.fg2, marginTop: 2, display: '-webkit-box', WebkitLineClamp: 2, WebkitBoxOrient: 'vertical', overflow: 'hidden' }}>{latestPost.caption}</div>
              <div style={{ fontFamily: H.body, fontSize: 11.5, color: H.fg3, marginTop: 4 }}>{relativeTime(latestPost.createdAt)}</div>
            </div>
            {latestPost.readAt === null && <span style={{ width: 8, height: 8, borderRadius: 999, background: 'var(--brand-orange-vibey)', flexShrink: 0, marginTop: 4 }} />}
          </div>
        ) : (
          <div style={{ padding: '18px 16px', fontFamily: H.body, fontSize: 13, color: H.fg3, borderTop: '0.5px solid ' + H.border }}>No notifications yet.</div>
        )}
        <button onClick={() => { onSimulate(); onClose(); }} style={{
          width: '100%', border: 0, borderTop: '0.5px solid ' + H.border, background: '#fff',
          padding: '11px 16px', cursor: 'pointer', fontFamily: H.body, fontWeight: 500, fontSize: 13,
          color: 'var(--brand-orange-vibey)', textAlign: 'left',
        }}>Simulate a new push →</button>
      </div>
    </>
  );
}

// ════════════════════════════════════════════════════════════════════════
// List pane
// ════════════════════════════════════════════════════════════════════════
function DeskListItem({ post, active, selected, userReaction, unreadStyle, density, onSelect }) {
  const p = pillarOf(post);
  const unread = post.readAt === null;
  const compact = density === 'compact';
  const tint = unread && unreadStyle === 'tint';
  const accent = unread && unreadStyle === 'accent';
  const total = Object.values(post.reactions).reduce((a, b) => a + b, 0);

  return (
    <button onClick={onSelect} className={'desk-list-item' + (selected ? ' is-selected' : '')} style={{
      position: 'relative', width: '100%', textAlign: 'left', cursor: 'pointer',
      border: 0, borderRadius: 16, padding: compact ? '11px 13px' : '14px 15px',
      display: 'flex', gap: 12, alignItems: 'flex-start',
      background: selected ? 'var(--quartz-soft-bg)' : (tint ? 'linear-gradient(180deg, rgba(255,244,240,0.7), #fff 70%)' : '#fff'),
      boxShadow: selected ? 'inset 0 0 0 1.5px var(--brand-orange-vibey)' : 'inset 0 0 0 1px var(--border-subtle)',
      transition: 'background 130ms, box-shadow 130ms',
    }}>
      {accent && <span style={{ position: 'absolute', left: 0, top: 12, bottom: 12, width: 3, borderRadius: 3, background: 'var(--brand-orange-vibey)' }} />}
      <div style={{ flex: 1, minWidth: 0, display: 'flex', flexDirection: 'column', gap: 7 }}>
        <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
          <WallPillarChip tag={post.pillarTag} />
          {unread && unreadStyle !== 'none' && <span style={{ width: 7, height: 7, borderRadius: 999, background: 'var(--brand-orange-vibey)', flexShrink: 0 }} />}
          <span style={{ flex: 1 }} />
          <span style={{ fontFamily: H.body, fontSize: 11.5, color: H.fg3, flexShrink: 0 }}>{relativeTime(post.createdAt)}</span>
        </div>
        <div style={{
          fontFamily: H.body, fontWeight: 600, fontSize: 15, lineHeight: 1.3, color: H.fg1, letterSpacing: -0.2,
          display: '-webkit-box', WebkitLineClamp: 2, WebkitBoxOrient: 'vertical', overflow: 'hidden',
        }}>{post.caption}</div>
        {!compact && (
          <div style={{
            fontFamily: H.body, fontSize: 12.5, lineHeight: 1.45, color: H.fg2,
            display: '-webkit-box', WebkitLineClamp: 2, WebkitBoxOrient: 'vertical', overflow: 'hidden',
          }}>{post.annaCommentary.replace(/\n+/g, ' ')}</div>
        )}
        <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
          <WallTypeBadge type={post.type} />
          {total > 0 && (
            <span style={{ display: 'inline-flex', alignItems: 'center', gap: 4, fontFamily: H.body, fontSize: 12, color: H.fg3 }}>
              <span style={{ fontSize: 12 }}>{REACTIONS.find(r => post.reactions[r.key] === Math.max(...REACTIONS.map(x => post.reactions[x.key]))).emoji}</span>
              {total}
            </span>
          )}
        </div>
      </div>
      {post.mediaUrl && (
        <div style={{ marginTop: 2 }}><WallMiniMedia post={post} /></div>
      )}
    </button>
  );
}

function DeskListSkeleton() {
  const Bar = ({ w, h = 12, r = 6, mt = 0 }) => <div className="wall-shimmer" style={{ width: w, height: h, borderRadius: r, marginTop: mt }} />;
  return (
    <div style={{ borderRadius: 16, padding: '14px 15px', boxShadow: 'inset 0 0 0 1px var(--border-subtle)', background: '#fff', display: 'flex', gap: 12 }}>
      <div style={{ flex: 1 }}>
        <Bar w={84} h={18} r={999} />
        <Bar w="94%" h={15} mt={11} />
        <Bar w="70%" h={15} mt={7} />
        <Bar w={70} h={18} r={999} mt={12} />
      </div>
      <div className="wall-shimmer" style={{ width: 64, height: 64, borderRadius: 14, flexShrink: 0 }} />
    </div>
  );
}

function DeskListPane({ store, settings, selectedId, onSelect }) {
  const { posts, loading, error, refreshing, loadingMore, hasMore, refresh, loadMore, userReactions } = store;
  const scrollRef = useR(null);
  const unread = posts.filter(p => p.readAt === null).length;

  const onScroll = () => {
    const el = scrollRef.current;
    if (!el || loadingMore || !hasMore || loading || error) return;
    if (el.scrollHeight - (el.scrollTop + el.clientHeight) < el.clientHeight * 0.35) loadMore();
  };

  // keep the selected row visible when navigating via keyboard (no scrollIntoView)
  useE(() => {
    const el = scrollRef.current; if (!el || !selectedId) return;
    const item = el.querySelector('[data-post-id="' + selectedId + '"]');
    if (!item) return;
    const ir = item.getBoundingClientRect(), cr = el.getBoundingClientRect();
    if (ir.top < cr.top + 8) el.scrollTop -= (cr.top + 8 - ir.top);
    else if (ir.bottom > cr.bottom - 8) el.scrollTop += (ir.bottom - (cr.bottom - 8));
  }, [selectedId]);

  return (
    <aside style={{
      width: 408, flexShrink: 0, height: '100%', display: 'flex', flexDirection: 'column',
      borderRight: '1px solid var(--border-subtle)', background: H.bg,
    }}>
      <div style={{ padding: '22px 22px 14px', flexShrink: 0 }}>
        <div style={{ display: 'flex', alignItems: 'flex-start', justifyContent: 'space-between' }}>
          <div>
            <div style={{ display: 'flex', alignItems: 'center', gap: 9 }}>
              <h1 style={{ fontFamily: H.display, fontWeight: 600, fontSize: 26, letterSpacing: -0.5, color: H.fg1, margin: 0, lineHeight: 1.05, whiteSpace: 'nowrap' }}>Your Wall</h1>
              {unread > 0 && <span style={{ fontFamily: H.body, fontWeight: 600, fontSize: 11.5, color: 'var(--brand-orange-vibey)', background: 'rgba(255,105,66,0.12)', padding: '4px 9px', borderRadius: 999, whiteSpace: 'nowrap' }}>{unread} new</span>}
            </div>
            <div style={{ display: 'flex', alignItems: 'center', gap: 6, marginTop: 7 }}>
              <img src="anna.png" alt="" width="17" height="17" style={{ width: 17, height: 17, borderRadius: 999, objectFit: 'cover' }} />
              <span style={{ fontFamily: H.body, fontSize: 12.5, color: H.fg2 }}>Curated by Anna · twice a week</span>
            </div>
          </div>
          <button onClick={refresh} aria-label="Refresh" disabled={refreshing} style={{
            width: 36, height: 36, borderRadius: 999, border: '1px solid var(--border-subtle)', background: '#fff',
            display: 'grid', placeItems: 'center', cursor: refreshing ? 'default' : 'pointer', flexShrink: 0,
          }}>
            <svg width="17" height="17" viewBox="0 0 24 24" fill="none" stroke={H.fg1} strokeWidth="1.9" strokeLinecap="round" strokeLinejoin="round" style={{ animation: refreshing ? 'wallSpin 0.8s linear infinite' : 'none' }}><path d="M3 12a9 9 0 1 0 3-6.7L3 8" /><path d="M3 3v5h5" /></svg>
          </button>
        </div>
      </div>

      <div ref={scrollRef} onScroll={onScroll} className="no-scrollbar" style={{ flex: 1, overflowY: 'auto', padding: '0 14px 24px' }}>
        {loading ? (
          <div style={{ display: 'flex', flexDirection: 'column', gap: 10 }}>{[0, 1, 2, 3].map(i => <DeskListSkeleton key={i} />)}</div>
        ) : error ? (
          <div style={{ padding: '40px 18px', textAlign: 'center' }}>
            <div style={{ fontFamily: H.body, fontSize: 13.5, color: H.fg2, marginBottom: 14 }}>Couldn't load your wall.</div>
            <HPrimaryButton type="outline" onClick={refresh}>Try again</HPrimaryButton>
          </div>
        ) : posts.length === 0 ? (
          <div style={{ padding: '40px 18px', textAlign: 'center', fontFamily: H.body, fontSize: 13.5, color: H.fg3 }}>No insights yet — Anna is preparing your first one.</div>
        ) : (
          <div style={{ display: 'flex', flexDirection: 'column', gap: 18 }}>
            {(() => { let gi = 0; return groupByRecency(posts).map(group => (
              <div key={group.key}>
                <div style={{ fontFamily: H.body, fontWeight: 500, fontSize: 11, letterSpacing: 1.3, textTransform: 'uppercase', color: H.fg3, padding: '2px 4px 9px' }}>{group.label}</div>
                <div style={{ display: 'flex', flexDirection: 'column', gap: 10 }}>
                  {group.items.map(post => {
                    const delay = Math.min(gi++, 7) * 40;
                    return (
                      <div key={post.id} data-post-id={post.id} className="wall-card-in" style={{ animationDelay: delay + 'ms' }}>
                        <DeskListItem
                          post={post}
                          selected={post.id === selectedId}
                          userReaction={userReactions[post.id]}
                          unreadStyle={settings.unreadStyle}
                          density={settings.density}
                          onSelect={() => onSelect(post.id)}
                        />
                      </div>
                    );
                  })}
                </div>
              </div>
            )); })()}
            {loadingMore && <WallLoadingFooter done={false} />}
            {!hasMore && !loadingMore && <div style={{ textAlign: 'center', padding: '12px 0 2px', fontFamily: H.body, fontSize: 12, color: H.fg3 }}>You're all caught up</div>}
          </div>
        )}
      </div>
    </aside>
  );
}

// ════════════════════════════════════════════════════════════════════════
// Detail reading pane
// ════════════════════════════════════════════════════════════════════════
function DeskDetailPane({ post, store, onAskAnna }) {
  const [toast, setToast] = useS(null);
  const scrollRef = useR(null);
  useE(() => { if (post && post.readAt === null) store.markRead(post.id); }, [post && post.id]);
  // reset reading position when switching posts
  useE(() => { if (scrollRef.current) scrollRef.current.scrollTop = 0; }, [post && post.id]);

  if (!post) {
    return (
      <main style={{ flex: 1, height: '100%', display: 'grid', placeItems: 'center', background: H.bg, padding: 40 }}>
        <div style={{ textAlign: 'center', maxWidth: 320 }}>
          <div style={{ width: 64, height: 64, borderRadius: 999, background: H.bgSecondary, display: 'grid', placeItems: 'center', margin: '0 auto 18px' }}>
            <svg width="28" height="28" viewBox="0 0 24 24" fill="none" stroke={H.fg3} strokeWidth="1.7" strokeLinecap="round" strokeLinejoin="round"><rect x="3" y="3" width="18" height="7" rx="2" /><rect x="3" y="13" width="18" height="8" rx="2" /></svg>
          </div>
          <div style={{ fontFamily: H.display, fontWeight: 600, fontSize: 20, letterSpacing: -0.4, color: H.fg1 }}>Select an insight</div>
          <div style={{ fontFamily: H.body, fontSize: 14, lineHeight: 1.5, color: H.fg2, marginTop: 8 }}>Pick a post from your wall to read Anna's full note, sources, and react.</div>
        </div>
      </main>
    );
  }

  const p = pillarOf(post);
  const share = () => { setToast('Link copied to clipboard'); setTimeout(() => setToast(null), 1800); };

  return (
    <main ref={scrollRef} style={{ flex: 1, height: '100%', overflowY: 'auto', background: H.bg, position: 'relative' }} className="no-scrollbar">
      {/* sticky action header */}
      <div style={{
        position: 'sticky', top: 0, zIndex: 10, display: 'flex', alignItems: 'center', gap: 10,
        padding: '14px 40px', background: 'var(--surface-80, rgba(240,243,245,0.82))',
        backdropFilter: 'blur(14px) saturate(1.3)', WebkitBackdropFilter: 'blur(14px) saturate(1.3)',
        borderBottom: '1px solid var(--border-subtle)',
      }}>
        <WallPillarChip tag={post.pillarTag} />
        <WallTypeBadge type={post.type} />
        <div style={{ flex: 1 }} />
        <button onClick={share} style={{ display: 'inline-flex', alignItems: 'center', gap: 7, height: 38, padding: '0 15px', borderRadius: 999, border: '1px solid var(--border-subtle)', background: '#fff', cursor: 'pointer', fontFamily: H.body, fontWeight: 500, fontSize: 13.5, color: H.fg1 }}>
          <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke={H.fg1} strokeWidth="1.9" strokeLinecap="round" strokeLinejoin="round"><path d="M12 3v13M8 7l4-4 4 4" /><path d="M5 12v7a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2v-7" /></svg>
          Share
        </button>
        <button onClick={onAskAnna} style={{ display: 'inline-flex', alignItems: 'center', gap: 7, height: 38, padding: '0 16px', borderRadius: 999, border: 0, background: H.black, cursor: 'pointer', fontFamily: H.body, fontWeight: 500, fontSize: 13.5, color: '#fff' }}>
          <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="#fff" strokeWidth="1.9" strokeLinecap="round" strokeLinejoin="round"><path d="M4 6a2 2 0 0 1 2-2h12a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2H9l-4 3v-3H6a2 2 0 0 1-2-2z" /></svg>
          Ask Anna
        </button>
      </div>

      {/* article */}
      <article key={post.id} className="screen-enter" style={{ maxWidth: 720, margin: '0 auto', padding: '30px 40px 90px' }}>
        <h1 style={{ fontFamily: H.display, fontWeight: 600, fontSize: 36, lineHeight: 1.14, letterSpacing: -0.8, color: H.fg1, margin: '0 0 18px' }}>{post.caption}</h1>

        {/* byline */}
        <div style={{ display: 'flex', alignItems: 'center', gap: 11, marginBottom: 24 }}>
          <img src="anna.png" alt="Anna" width="44" height="44" style={{ width: 44, height: 44, borderRadius: 999, objectFit: 'cover' }} />
          <div>
            <div style={{ fontFamily: H.body, fontWeight: 600, fontSize: 15, color: H.fg1 }}>Anna</div>
            <div style={{ fontFamily: H.body, fontSize: 12.5, color: H.fg3 }}>Your AI health coach · {relativeTime(post.createdAt)}</div>
          </div>
        </div>

        {post.mediaUrl && <div style={{ marginBottom: 26 }}><WallDetailHero post={post} /></div>}

        <div style={{ display: 'flex', flexDirection: 'column', gap: 18 }}>
          {post.annaCommentary.split('\n').filter(Boolean).map((para, i) => (
            <p key={i} style={{ fontFamily: H.body, fontSize: 17.5, lineHeight: 1.62, color: H.fg1, letterSpacing: -0.2, margin: 0 }}>{para}</p>
          ))}
        </div>

        {/* reactions */}
        <div style={{ margin: '32px 0 26px' }}>
          <div style={{ fontFamily: H.body, fontWeight: 500, fontSize: 12.5, letterSpacing: 1, textTransform: 'uppercase', color: H.fg3, marginBottom: 12 }}>How does this land?</div>
          <div style={{ maxWidth: 440 }}><WallReactionBar post={post} userReaction={store.userReactions[post.id]} onReact={store.react} /></div>
        </div>

        {post.citationUrls && post.citationUrls.length > 0 && (
          <div style={{ marginBottom: 28 }}><WallCitations urls={post.citationUrls} /></div>
        )}

        <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 16, padding: '20px 22px', borderRadius: 18, background: 'linear-gradient(180deg, rgba(255,244,240,0.65), #fff)', boxShadow: 'inset 0 0 0 1px var(--border-subtle)' }}>
          <div style={{ display: 'flex', alignItems: 'center', gap: 12 }}>
            <img src="anna.png" alt="Anna" width="40" height="40" style={{ width: 40, height: 40, borderRadius: 999, objectFit: 'cover' }} />
            <div>
              <div style={{ fontFamily: H.body, fontWeight: 600, fontSize: 14.5, color: H.fg1 }}>Have a question about this?</div>
              <div style={{ fontFamily: H.body, fontSize: 13, color: H.fg2 }}>Anna can go deeper on anything in this note.</div>
            </div>
          </div>
          <button onClick={onAskAnna} style={{ flexShrink: 0, display: 'inline-flex', alignItems: 'center', gap: 7, height: 40, padding: '0 18px', borderRadius: 999, border: 0, background: H.black, cursor: 'pointer', fontFamily: H.body, fontWeight: 500, fontSize: 14, color: '#fff' }}>Ask Anna</button>
        </div>

        <div style={{ fontFamily: H.body, fontSize: 11, lineHeight: 1.5, color: H.fg3, textAlign: 'center', padding: '26px 30px 0' }}>
          For educational purposes only. Not medical advice. Anna's notes draw on peer-reviewed literature and your own data.
        </div>
      </article>

      {toast && (
        <div style={{ position: 'fixed', left: '50%', bottom: 34, transform: 'translateX(-50%)', background: H.black, color: '#fff', fontFamily: H.body, fontSize: 13.5, padding: '11px 18px', borderRadius: 999, boxShadow: '0 8px 24px rgba(3,4,13,0.3)', display: 'flex', alignItems: 'center', gap: 8, whiteSpace: 'nowrap', zIndex: 200 }}>
          <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="#fff" strokeWidth="2.2" strokeLinecap="round" strokeLinejoin="round"><path d="m5 12 5 5L20 7" /></svg>
          {toast}
        </div>
      )}
    </main>
  );
}

// ════════════════════════════════════════════════════════════════════════
// Mobile collapse — reuses the canonical mobile WallScreen / PostDetailScreen
// (from wall-screens.jsx) full-bleed, with a compact bottom tab bar. Shares the
// SAME store instance so read-state + reactions persist across a resize.
// ════════════════════════════════════════════════════════════════════════
function MobileTabBar({ active, unread, onSelect }) {
  const Icon = ({ k, on }) => {
    const c = on ? 'var(--brand-orange-vibey)' : H.fg2; const sw = on ? 2.2 : 1.8;
    const common = { width: 23, height: 23, viewBox: '0 0 24 24', fill: 'none', stroke: c, strokeWidth: sw, strokeLinecap: 'round', strokeLinejoin: 'round' };
    if (k === 'home') return <svg {...common}><path d="M3.5 10.5 12 3l8.5 7.5V20a1 1 0 0 1-1 1h-5v-6h-5v6H4.5a1 1 0 0 1-1-1Z" /></svg>;
    if (k === 'fitness') return <svg {...common}><path d="M4 12h3l2-5 4 10 2-6 2 3h4" /></svg>;
    if (k === 'wall') return <svg {...common}><rect x="3" y="3" width="18" height="7" rx="2" /><rect x="3" y="13" width="18" height="8" rx="2" /></svg>;
    if (k === 'menu') return <svg {...common}><path d="M4 7h16M4 12h16M4 17h16" /></svg>;
    return null;
  };
  const Tab = ({ k }) => {
    const on = active === k;
    return (
      <button onClick={() => onSelect(k)} style={{ position: 'relative', flex: 1, alignSelf: 'stretch', cursor: 'pointer', border: 0, background: 'transparent', display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
        <span style={{ display: 'grid', placeItems: 'center', width: 46, height: 46, borderRadius: 999, background: on ? 'var(--quartz-soft-bg)' : 'transparent' }}><Icon k={k} on={on} /></span>
        {k === 'wall' && unread > 0 && <span style={{ position: 'absolute', top: 6, right: 'calc(50% - 18px)', minWidth: 16, height: 16, padding: '0 4px', boxSizing: 'border-box', borderRadius: 999, background: 'var(--brand-orange-vibey)', border: '1.5px solid #fff', color: '#fff', fontFamily: H.body, fontWeight: 600, fontSize: 9.5, display: 'grid', placeItems: 'center', lineHeight: 1 }}>{unread}</span>}
      </button>
    );
  };
  return (
    <div style={{ position: 'absolute', left: 16, right: 16, bottom: 'calc(14px + env(safe-area-inset-bottom, 0px))', height: 62, boxSizing: 'border-box', background: '#fff', borderRadius: 999, padding: '0 6px', border: '1px solid rgba(3,4,13,0.04)', boxShadow: '0 8px 17px rgba(166,166,166,0.12), 0 31px 31px rgba(166,166,166,0.08)', display: 'flex', alignItems: 'center', zIndex: 40 }}>
      <Tab k="home" /><Tab k="fitness" />
      <div style={{ width: 72, position: 'relative', alignSelf: 'stretch', flexShrink: 0, display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
        <button onClick={() => onSelect('chat')} aria-label="Talk to Anna" style={{ position: 'relative', width: 54, height: 54, borderRadius: 999, border: 0, padding: 0, cursor: 'pointer', boxShadow: '0 6px 14px rgba(3,4,13,0.18)' }}>
          <HealifyMark size={54} />
          <span style={{ position: 'absolute', top: -1, right: -1, width: 13, height: 13, borderRadius: 999, background: '#22C55E', border: '2px solid #fff' }} />
        </button>
      </div>
      <Tab k="wall" /><Tab k="menu" />
    </div>
  );
}

function MobileChatStub({ onBack }) {
  return (
    <div className="screen-enter" style={{ height: '100%', display: 'flex', flexDirection: 'column', background: H.bg }}>
      <HTopBar onBack={onBack} title="Anna" />
      <div style={{ flex: 1, display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', textAlign: 'center', padding: '0 40px 80px', gap: 14 }}>
        <img src="anna.png" alt="Anna" width="68" height="68" style={{ width: 68, height: 68, borderRadius: 999, objectFit: 'cover', boxShadow: '0 4px 14px rgba(3,4,13,0.14)' }} />
        <div style={{ fontFamily: H.display, fontWeight: 600, fontSize: 22, letterSpacing: -0.5, color: H.fg1 }}>Chat with Anna</div>
        <div style={{ fontFamily: H.body, fontSize: 14, lineHeight: 1.5, color: H.fg2, maxWidth: 260 }}>The full Anna chat lives in the main app. This view focuses on the Wall.</div>
      </div>
    </div>
  );
}

function WallMobileApp({ store, settings }) {
  const [stack, setStack] = useS([{ name: 'wall', params: {} }]);
  const top = stack[stack.length - 1];
  const push = (name, params = {}) => setStack(s => [...s, { name, params }]);
  const pop = () => setStack(s => s.length > 1 ? s.slice(0, -1) : s);
  const navigate = (route, params = {}) => { if (route === 'wall') { setStack([{ name: 'wall', params: {} }]); return; } push(route, params); };
  const unread = store.posts.filter(p => p.readAt === null).length;
  const screen = top.name;
  const hideTab = screen === 'post-detail' || screen === 'chat';
  return (
    <div style={{ height: '100%', position: 'relative', display: 'flex', flexDirection: 'column', background: H.bg, overflow: 'hidden' }} data-screen-label={screen}>
      <div key={screen + stack.length} style={{ flex: 1, minHeight: 0, position: 'relative' }}>
        {screen === 'wall' && <WallScreen onNavigate={navigate} store={store} settings={settings} />}
        {screen === 'post-detail' && <PostDetailScreen onNavigate={navigate} onBack={pop} postId={top.params.postId} store={store} settings={settings} />}
        {screen === 'chat' && <MobileChatStub onBack={pop} />}
      </div>
      {!hideTab && <MobileTabBar active="wall" unread={unread} onSelect={(k) => { if (k === 'wall') setStack([{ name: 'wall', params: {} }]); else if (k === 'chat') push('chat'); }} />}
    </div>
  );
}

Object.assign(window, {
  useWallStoreD, DeskTopBar, NotifPanel, DeskNavItem, DeskListItem, DeskListSkeleton,
  DeskListPane, DeskDetailPane, MobileTabBar, MobileChatStub, WallMobileApp,
});
