'use client'; interface PrdViewerProps { content: string; } /** * Lightweight markdown-to-HTML renderer for PRD content. * Supports headings, bold, italic, inline code, code blocks, and lists. * No external dependency — keeps bundle size minimal. */ function renderMarkdown(md: string): string { let html = md // Escape HTML entities first to prevent XSS .replace(/&/g, '&') .replace(//g, '>'); // Code blocks (must run before inline code) html = html.replace(/```[\w]*\n?([\s\S]*?)```/g, (_match, code: string) => { return `
${code.trim()}
`; }); // Headings html = html.replace( /^#### (.+)$/gm, '

$1

', ); html = html.replace( /^### (.+)$/gm, '

$1

', ); html = html.replace( /^## (.+)$/gm, '

$1

', ); html = html.replace( /^# (.+)$/gm, '

$1

', ); // Horizontal rule html = html.replace(/^---$/gm, '
'); // Unordered list items html = html.replace( /^[-*] (.+)$/gm, '
  • $1
  • ', ); // Ordered list items html = html.replace( /^\d+\. (.+)$/gm, '
  • $1
  • ', ); // Bold + italic html = html.replace(/\*\*\*(.+?)\*\*\*/g, '$1'); // Bold html = html.replace( /\*\*(.+?)\*\*/g, '$1', ); // Italic html = html.replace(/\*(.+?)\*/g, '$1'); // Inline code html = html.replace( /`([^`]+)`/g, '$1', ); // Paragraphs — wrap lines that aren't already wrapped in a block element const lines = html.split('\n'); const result: string[] = []; for (const line of lines) { const trimmed = line.trim(); if (trimmed === '') { result.push(''); } else if ( trimmed.startsWith('${trimmed}

    `); } } return result.join('\n'); } export function PrdViewer({ content }: PrdViewerProps): React.ReactElement { const html = renderMarkdown(content); return
    ; }