"""
Markdown 轉 HTML 網站產生器 v3
==============================
新增功能：
- 字體大小調整
- 回到頂部按鈕
- 程式碼複製按鈕
- 閱讀進度條
- 全站搜尋
"""

import sys
sys.stdout.reconfigure(encoding='utf-8')

import subprocess
import re
import json
from pathlib import Path
from html import escape
from datetime import datetime
from collections import defaultdict
import shutil
import argparse

# ===== 功能模組定義 =====
# 每個功能模組包含：id, 名稱, 說明, 依賴關係
FEATURE_MODULES = {
    'notes': {
        'name': '三層筆記系統',
        'desc': '網站筆記、文件筆記、段落筆記',
        'depends': [],
        'default': True,
    },
    'note_center': {
        'name': '筆記中心',
        'desc': '在首頁查看所有筆記、跨頁跳轉',
        'depends': ['notes'],
        'default': True,
    },
    'search': {
        'name': '全站搜尋',
        'desc': 'Ctrl+K 快捷鍵即時搜尋',
        'depends': [],
        'default': True,
    },
    'dark_mode': {
        'name': '深色模式',
        'desc': '自動儲存主題偏好',
        'depends': [],
        'default': True,
    },
    'pip_video': {
        'name': 'PIP 影片播放',
        'desc': '滾動時自動啟用子母畫面',
        'depends': [],
        'default': True,
    },
    'reading_time': {
        'name': '閱讀時間估算',
        'desc': '顯示預估閱讀時間',
        'depends': [],
        'default': True,
    },
    'help_modal': {
        'name': '使用說明',
        'desc': '❓ 按鈕開啟功能說明',
        'depends': [],
        'default': True,
    },
    'export': {
        'name': '匯出筆記',
        'desc': '選擇匯出範圍和格式',
        'depends': ['notes'],
        'default': True,
    },
    'floating_toc': {
        'name': '浮動目錄',
        'desc': 'Notion 風格懸浮目錄（預設隱藏，hover 滑出）',
        'depends': [],
        'default': False,  # 預設使用固定目錄
    },
    'watermark': {
        'name': '浮水印',
        'desc': '可自訂文字、日期的浮水印保護',
        'depends': [],
        'default': False,
    },
}

# 預設啟用的功能
DEFAULT_FEATURES = [f for f, cfg in FEATURE_MODULES.items() if cfg['default']]

def resolve_dependencies(features):
    """解析功能依賴，自動加入必要的依賴功能"""
    resolved = set(features)
    changed = True
    while changed:
        changed = False
        for f in list(resolved):
            if f in FEATURE_MODULES:
                for dep in FEATURE_MODULES[f]['depends']:
                    if dep not in resolved:
                        resolved.add(dep)
                        changed = True
    return list(resolved)

def parse_features(args):
    """從命令列參數解析啟用的功能"""
    # 如果指定了 --features，則只啟用指定的功能（從空集合開始）
    # 如果沒有指定 --features，則使用預設功能
    if hasattr(args, 'features') and args.features:
        features = set()
        for f in args.features.split(','):
            f = f.strip()
            if f == 'all':
                features = set(FEATURE_MODULES.keys())
            elif f == 'none':
                features = set()
            elif f in FEATURE_MODULES:
                features.add(f)
    else:
        features = set(DEFAULT_FEATURES)

    # 處理 --no-features 參數
    if hasattr(args, 'no_features') and args.no_features:
        for f in args.no_features.split(','):
            f = f.strip()
            features.discard(f)

    # 解析依賴關係
    return resolve_dependencies(list(features))

def process_template(template: str, features: list) -> str:
    """
    根據啟用的功能處理模板，移除未啟用功能的區塊。

    模板中使用以下標記：
    <!-- FEATURE:feature_name -->
    ... 該功能的 HTML/CSS/JS ...
    <!-- /FEATURE:feature_name -->

    如果 feature_name 不在 features 列表中，整個區塊會被移除。
    """
    import re

    # 匹配功能區塊的正則表達式
    # 支援多行匹配，非貪婪模式
    pattern = r'<!-- FEATURE:(\w+) -->(.*?)<!-- /FEATURE:\1 -->'

    def replace_feature_block(match):
        feature_name = match.group(1)
        feature_content = match.group(2)

        if feature_name in features:
            # 保留內容（移除標記本身）
            return feature_content
        else:
            # 移除整個區塊
            return ''

    # 使用 DOTALL 讓 . 可以匹配換行
    processed = re.sub(pattern, replace_feature_block, template, flags=re.DOTALL)

    return processed

# ===== 首頁模板 =====
INDEX_TEMPLATE = '''<!DOCTYPE html>
<html lang="zh-TW">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>{site_title}</title>
    <style>
        :root {{
            --bg-color: #ffffff;
            --text-color: #333333;
            --heading-color: #1a1a1a;
            --card-bg: #ffffff;
            --card-border: #e8e8e8;
            --card-shadow: rgba(0,0,0,0.08);
            --link-color: #0066cc;
            --category-bg: #f8f9fa;
            --hover-bg: #f0f7ff;
            --search-bg: #f5f5f5;
        }}

        [data-theme="dark"] {{
            --bg-color: #1a1a2e;
            --text-color: #e0e0e0;
            --heading-color: #ffffff;
            --card-bg: #252545;
            --card-border: #3a3a5a;
            --card-shadow: rgba(0,0,0,0.3);
            --link-color: #6db3f2;
            --category-bg: #1e1e38;
            --hover-bg: #2a2a4a;
            --search-bg: #252540;
        }}

        * {{ box-sizing: border-box; }}

        body {{
            font-family: "微軟正黑體", "Microsoft JhengHei", sans-serif;
            line-height: 1.6;
            color: var(--text-color);
            background: var(--bg-color);
            margin: 0;
            padding: 0;
        }}

        .header {{
            background: #333;
            color: white;
            padding: 40px 20px 30px;
            text-align: center;
        }}

        .header h1 {{
            margin: 0 0 10px 0;
            font-size: 1.8em;
        }}

        .header p {{
            margin: 0 0 20px 0;
            opacity: 0.85;
        }}

        <!-- FEATURE:search -->
        /* 搜尋框 */
        .search-box {{
            max-width: 500px;
            margin: 0 auto;
            position: relative;
        }}

        .search-box input {{
            width: 100%;
            padding: 12px 20px;
            font-size: 1em;
            border: none;
            border-radius: 25px;
            background: rgba(255,255,255,0.95);
            color: #333;
        }}

        .search-box input:focus {{
            outline: none;
            box-shadow: 0 0 0 3px rgba(255,255,255,0.3);
        }}

        .search-results {{
            position: absolute;
            top: 100%;
            left: 0;
            right: 0;
            background: var(--card-bg);
            border: 1px solid var(--card-border);
            border-radius: 8px;
            margin-top: 8px;
            max-height: 400px;
            overflow-y: auto;
            display: none;
            box-shadow: 0 4px 20px var(--card-shadow);
            z-index: 1000;
        }}

        .search-results.active {{
            display: block;
        }}

        .search-result-item {{
            padding: 12px 20px;
            border-bottom: 1px solid var(--card-border);
            cursor: pointer;
            text-decoration: none;
            display: block;
            color: var(--text-color);
        }}

        .search-result-item:hover {{
            background: var(--hover-bg);
        }}

        .search-result-item:last-child {{
            border-bottom: none;
        }}

        .search-result-item .title {{
            font-weight: bold;
            color: var(--link-color);
            margin-bottom: 4px;
        }}

        .search-result-item .excerpt {{
            font-size: 0.85em;
            opacity: 0.7;
        }}

        .search-result-item .excerpt mark {{
            background: #fff3cd;
            color: #333;
            padding: 1px 3px;
            border-radius: 2px;
        }}
        <!-- /FEATURE:search -->

        .toolbar {{
            position: fixed;
            top: 20px;
            right: 20px;
            z-index: 1000;
        }}

        .toolbar button {{
            padding: 8px 15px;
            border: none;
            background: rgba(255,255,255,0.2);
            color: white;
            border-radius: 6px;
            cursor: pointer;
        }}

        .toolbar button:hover {{
            background: rgba(255,255,255,0.3);
        }}

        .container {{
            max-width: 1000px;
            margin: 0 auto;
            padding: 30px 20px;
        }}

        .stats {{
            display: flex;
            gap: 20px;
            justify-content: center;
            margin: -25px auto 30px;
            flex-wrap: wrap;
        }}

        .stat-card {{
            background: var(--card-bg);
            border: 1px solid var(--card-border);
            border-radius: 8px;
            padding: 15px 25px;
            text-align: center;
            box-shadow: 0 2px 8px var(--card-shadow);
        }}

        .stat-card .number {{
            font-size: 1.5em;
            font-weight: bold;
            color: var(--link-color);
        }}

        .stat-card .label {{
            font-size: 0.85em;
            color: var(--text-color);
            opacity: 0.7;
        }}

        .category {{
            background: var(--category-bg);
            border-radius: 8px;
            padding: 20px;
            margin-bottom: 20px;
        }}

        .category h2 {{
            margin: 0 0 15px 0;
            font-size: 1.1em;
            color: var(--heading-color);
        }}

        .doc-grid {{
            display: grid;
            grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
            gap: 12px;
        }}

        .doc-card {{
            background: var(--card-bg);
            border: 1px solid var(--card-border);
            border-radius: 6px;
            padding: 15px;
            text-decoration: none;
            color: var(--text-color);
            transition: all 0.2s;
            display: block;
        }}

        .doc-card:hover {{
            background: var(--hover-bg);
            transform: translateY(-2px);
            box-shadow: 0 4px 12px var(--card-shadow);
        }}

        .doc-card h3 {{
            margin: 0 0 6px 0;
            font-size: 0.95em;
            color: var(--link-color);
        }}

        .doc-card .desc {{
            font-size: 0.8em;
            opacity: 0.65;
            margin: 0;
        }}

        .footer {{
            text-align: center;
            padding: 25px;
            color: var(--text-color);
            opacity: 0.5;
            font-size: 0.85em;
        }}

        /* 範例作品區塊 */
        .demos {{
            background: #333;
            border-radius: 12px;
            padding: 25px;
            margin-top: 30px;
            color: white;
        }}

        .demos h2 {{
            margin: 0 0 15px 0;
            font-size: 1.2em;
            color: white;
        }}

        .demo-grid {{
            display: grid;
            grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
            gap: 12px;
        }}

        .demo-card {{
            background: rgba(255,255,255,0.15);
            border: 1px solid rgba(255,255,255,0.2);
            border-radius: 8px;
            padding: 15px;
            text-decoration: none;
            color: white;
            transition: all 0.2s;
            display: block;
        }}

        .demo-card:hover {{
            background: rgba(255,255,255,0.25);
            transform: translateY(-2px);
        }}

        .demo-card h3 {{
            margin: 0 0 6px 0;
            font-size: 0.95em;
        }}

        .demo-card .demo-type {{
            font-size: 0.75em;
            opacity: 0.8;
        }}

        @media (max-width: 600px) {{
            .header h1 {{ font-size: 1.4em; }}
            .stats {{ flex-direction: column; align-items: center; }}
            .doc-grid {{ grid-template-columns: 1fr; }}
            .demo-grid {{ grid-template-columns: 1fr; }}
        }}

        <!-- FEATURE:note_center -->
        /* ===== 筆記中心 Modal ===== */
        .note-center-modal {{
            display: none;
            position: fixed;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            background: rgba(0, 0, 0, 0.5);
            z-index: 3000;
            justify-content: center;
            align-items: center;
        }}
        .note-center-modal.active {{ display: flex; }}
        .note-center-container {{
            background: var(--bg-color);
            border-radius: 12px;
            width: 90%;
            max-width: 800px;
            max-height: 85vh;
            display: flex;
            flex-direction: column;
            box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);
        }}
        .note-center-header {{
            padding: 20px 24px;
            border-bottom: 1px solid var(--border-color, #e0e0e0);
            display: flex;
            justify-content: space-between;
            align-items: center;
        }}
        .note-center-header h2 {{ margin: 0; font-size: 20px; }}
        .note-center-header .close-btn {{
            background: none;
            border: none;
            font-size: 24px;
            cursor: pointer;
            color: var(--text-color);
            opacity: 0.6;
        }}
        .note-center-header .close-btn:hover {{ opacity: 1; }}
        .note-center-tabs {{
            display: flex;
            padding: 0 24px;
            border-bottom: 1px solid var(--border-color, #e0e0e0);
            background: #f5f5f5;
        }}
        [data-theme="dark"] .note-center-tabs {{ background: #2a2a2a; }}
        .note-center-tab {{
            padding: 14px 20px;
            border: none;
            background: none;
            cursor: pointer;
            font-size: 14px;
            color: var(--text-color);
            opacity: 0.6;
            border-bottom: 3px solid transparent;
            margin-bottom: -1px;
        }}
        .note-center-tab:hover {{ opacity: 0.8; }}
        .note-center-tab.active {{
            opacity: 1;
            border-bottom-color: var(--link-color);
            font-weight: 600;
        }}
        .note-center-tab .badge {{
            display: inline-block;
            background: var(--link-color);
            color: white;
            font-size: 11px;
            padding: 2px 6px;
            border-radius: 10px;
            margin-left: 6px;
        }}
        .note-center-content {{
            flex: 1;
            overflow-y: auto;
            padding: 20px 24px;
        }}
        .note-center-empty {{
            text-align: center;
            padding: 60px 20px;
            color: var(--text-color);
            opacity: 0.5;
        }}
        .note-center-empty .icon {{ font-size: 48px; margin-bottom: 16px; }}
        .note-group {{
            margin-bottom: 24px;
            border: 1px solid var(--border-color, #e0e0e0);
            border-radius: 8px;
            overflow: hidden;
        }}
        .note-group-header {{
            background: #f5f5f5;
            padding: 12px 16px;
            display: flex;
            justify-content: space-between;
            align-items: center;
            cursor: pointer;
        }}
        [data-theme="dark"] .note-group-header {{ background: #2a2a2a; }}
        .note-group-title {{ font-weight: 600; font-size: 14px; }}
        .note-group-count {{ font-size: 12px; opacity: 0.6; }}
        .note-group-actions {{ display: flex; gap: 8px; align-items: center; }}
        .note-group-actions button {{
            padding: 6px 12px;
            font-size: 12px;
            border: 1px solid var(--border-color, #e0e0e0);
            background: var(--bg-color);
            border-radius: 4px;
            cursor: pointer;
            color: var(--text-color);
        }}
        .note-group-actions button:hover {{ border-color: var(--link-color); color: var(--link-color); }}
        .note-group-items {{ padding: 12px 16px; }}
        .note-center-item {{
            padding: 12px;
            border: 1px solid var(--border-color, #e0e0e0);
            border-radius: 6px;
            margin-bottom: 10px;
            background: var(--bg-color);
        }}
        .note-center-item:last-child {{ margin-bottom: 0; }}
        .note-center-item-context {{
            font-size: 12px;
            color: var(--text-color);
            opacity: 0.6;
            margin-bottom: 8px;
            padding: 8px;
            background: #f5f5f5;
            border-radius: 4px;
            border-left: 3px solid var(--link-color);
        }}
        [data-theme="dark"] .note-center-item-context {{ background: #2a2a2a; }}
        .note-center-item-content {{ font-size: 14px; line-height: 1.6; margin-bottom: 10px; }}
        .note-center-item-footer {{ display: flex; justify-content: space-between; align-items: center; }}
        .note-center-item-time {{ font-size: 11px; opacity: 0.5; }}
        .note-center-item-actions {{ display: flex; gap: 6px; }}
        .note-center-item-actions button {{
            padding: 4px 10px;
            font-size: 12px;
            border: 1px solid var(--border-color, #e0e0e0);
            background: var(--bg-color);
            border-radius: 4px;
            cursor: pointer;
            color: var(--text-color);
        }}
        .note-center-item-actions button:hover {{ border-color: var(--link-color); color: var(--link-color); }}
        .note-center-item-actions button.jump-btn {{
            background: var(--link-color);
            border-color: var(--link-color);
            color: white;
        }}
        .note-center-footer {{
            padding: 16px 24px;
            border-top: 1px solid var(--border-color, #e0e0e0);
            background: #f5f5f5;
            font-size: 13px;
            display: flex;
            justify-content: space-between;
            align-items: center;
        }}
        [data-theme="dark"] .note-center-footer {{ background: #2a2a2a; }}
        .note-center-stats {{ display: flex; gap: 16px; }}
        .note-center-stats span {{ opacity: 0.7; }}
        <!-- /FEATURE:note_center -->
    </style>
</head>
<body>
    <div class="toolbar">
        <!-- FEATURE:dark_mode -->
        <button onclick="toggleTheme()" id="theme-btn">🌙</button>
        <!-- /FEATURE:dark_mode -->
        <!-- FEATURE:note_center -->
        <button class="toolbar-note-btn" onclick="openNoteCenter()" title="筆記中心">📝 筆記</button>
        <!-- /FEATURE:note_center -->
        <!-- FEATURE:help_modal -->
        <button onclick="openHelpModal()" title="使用說明">❓</button>
        <!-- /FEATURE:help_modal -->
    </div>

    <header class="header">
        <h1>{site_title}</h1>
        <p>{site_description}</p>
        <!-- FEATURE:search -->
        <div class="search-box">
            <input type="text" id="search-input" placeholder="🔍 搜尋文件內容..." autocomplete="off">
            <div class="search-results" id="search-results"></div>
        </div>
        <!-- /FEATURE:search -->
    </header>

    <div class="container">
        <div class="stats">
            <div class="stat-card">
                <div class="number">{total_docs}</div>
                <div class="label">文件數量</div>
            </div>
            <div class="stat-card">
                <div class="number">{total_categories}</div>
                <div class="label">分類數量</div>
            </div>
            <div class="stat-card">
                <div class="number">{generated_date}</div>
                <div class="label">生成日期</div>
            </div>
        </div>

        {categories_html}

        {demos_html}
    </div>

    <footer class="footer">
        <div>可離線瀏覽 | 按 Ctrl+K 搜尋</div>
        <div style="margin-top: 12px; padding-top: 12px; border-top: 1px solid rgba(128,128,128,0.2);">
            本教材由 <strong>漢娜不動產估價師聯合事務所</strong> 製作<br>
            <span style="font-size: 0.85em;">專業不動產估價 · AI 輔助查估應用</span>
        </div>
    </footer>

    <script>
        <!-- FEATURE:search -->
        // 搜尋索引（直接嵌入，避免 file:// 協議的 CORS 限制）
        const searchIndex = {search_index_json};

        const searchInput = document.getElementById('search-input');
        const searchResults = document.getElementById('search-results');

        // 搜尋功能
        if (searchInput) {{
            searchInput.addEventListener('input', function() {{
                const query = this.value.trim().toLowerCase();
                if (query.length < 2) {{
                    searchResults.classList.remove('active');
                    return;
                }}

                const results = searchIndex.filter(doc =>
                    doc.title.toLowerCase().includes(query) ||
                    doc.content.toLowerCase().includes(query)
                ).slice(0, 8);

                if (results.length === 0) {{
                    searchResults.innerHTML = '<div class="search-result-item"><span class="excerpt">找不到相關內容</span></div>';
                }} else {{
                    searchResults.innerHTML = results.map(doc => {{
                        let excerpt = doc.content;
                        const idx = excerpt.toLowerCase().indexOf(query);
                        if (idx > -1) {{
                            const start = Math.max(0, idx - 30);
                            const end = Math.min(excerpt.length, idx + query.length + 50);
                            excerpt = (start > 0 ? '...' : '') +
                                      excerpt.slice(start, end).replace(new RegExp(query, 'gi'), '<mark>$&</mark>') +
                                      (end < excerpt.length ? '...' : '');
                        }} else {{
                            excerpt = excerpt.slice(0, 80) + '...';
                        }}
                        return `<a href="${{doc.url}}?highlight=${{encodeURIComponent(query)}}" class="search-result-item">
                            <div class="title">${{doc.title}}</div>
                            <div class="excerpt">${{excerpt}}</div>
                        </a>`;
                    }}).join('');
                }}
                searchResults.classList.add('active');
            }});

            // 點擊外部關閉搜尋結果
            document.addEventListener('click', function(e) {{
                if (!e.target.closest('.search-box')) {{
                    searchResults.classList.remove('active');
                }}
            }});

            // Ctrl+K 快捷鍵
            document.addEventListener('keydown', function(e) {{
                if ((e.ctrlKey || e.metaKey) && e.key === 'k') {{
                    e.preventDefault();
                    searchInput.focus();
                }}
                if (e.key === 'Escape') {{
                    searchResults.classList.remove('active');
                    searchInput.blur();
                }}
            }});
        }}
        <!-- /FEATURE:search -->

        <!-- FEATURE:dark_mode -->
        // 夜間模式
        function toggleTheme() {{
            const html = document.documentElement;
            const btn = document.getElementById('theme-btn');
            if (html.getAttribute('data-theme') === 'dark') {{
                html.removeAttribute('data-theme');
                btn.textContent = '🌙';
                localStorage.setItem('theme', 'light');
            }} else {{
                html.setAttribute('data-theme', 'dark');
                btn.textContent = '☀️';
                localStorage.setItem('theme', 'dark');
            }}
        }}

        if (localStorage.getItem('theme') === 'dark') {{
            document.documentElement.setAttribute('data-theme', 'dark');
            document.getElementById('theme-btn').textContent = '☀️';
        }}
        <!-- /FEATURE:dark_mode -->

        <!-- FEATURE:note_center -->
        // ===== 筆記中心功能 =====
        let siteNotes = JSON.parse(localStorage.getItem('site-notes') || '[]');
        let allDocNotes = [];
        let allParaNotes = [];
        let noteCenterTab = 'site';

        // 收集所有頁面的筆記
        function collectAllNotes() {{
            allDocNotes = [];
            allParaNotes = [];

            // 遍歷 localStorage 收集所有筆記
            for (let i = 0; i < localStorage.length; i++) {{
                const key = localStorage.key(i);

                if (key.startsWith('doc-notes:')) {{
                    const pageId = key.replace('doc-notes:', '');
                    const notes = JSON.parse(localStorage.getItem(key) || '[]');
                    notes.forEach(note => {{
                        allDocNotes.push({{
                            ...note,
                            pageId,
                            pageTitle: note.pageTitle || getPageTitle(pageId)
                        }});
                    }});
                }}

                if (key.startsWith('para-notes:')) {{
                    const pageId = key.replace('para-notes:', '');
                    const notes = JSON.parse(localStorage.getItem(key) || '[]');
                    notes.forEach(note => {{
                        allParaNotes.push({{
                            ...note,
                            pageId,
                            pageTitle: note.pageTitle || getPageTitle(pageId)
                        }});
                    }});
                }}
            }}

            // 按時間排序（最新在前）
            allDocNotes.sort((a, b) => (b.updated || b.created) - (a.updated || a.created));
            allParaNotes.sort((a, b) => (b.updated || b.created) - (a.updated || a.created));
        }}

        // 從頁面路徑推測標題
        function getPageTitle(pageId) {{
            const filename = pageId.split('/').pop().replace('.html', '');
            return decodeURIComponent(filename) || '未知頁面';
        }}

        // 開啟筆記中心
        function openNoteCenter() {{
            collectAllNotes();
            updateNoteCenterCounts();
            switchNoteCenterTab('site');
            document.getElementById('note-center-modal').classList.add('active');
        }}

        // 關閉筆記中心
        function closeNoteCenter() {{
            document.getElementById('note-center-modal').classList.remove('active');
        }}

        // 切換筆記中心分頁
        function switchNoteCenterTab(tab) {{
            noteCenterTab = tab;

            // 更新分頁按鈕狀態
            document.querySelectorAll('.note-center-tab').forEach(t => {{
                t.classList.toggle('active', t.dataset.tab === tab);
            }});

            // 渲染內容
            renderNoteCenterContent();
        }}

        // 更新筆記中心計數
        function updateNoteCenterCounts() {{
            document.getElementById('nc-site-count').textContent = siteNotes.length;
            document.getElementById('nc-doc-count').textContent = allDocNotes.length;
            document.getElementById('nc-para-count').textContent = allParaNotes.length;

            const total = siteNotes.length + allDocNotes.length + allParaNotes.length;
            document.getElementById('note-center-stats').innerHTML = `
                <span>🌐 網站 ${{siteNotes.length}} 則</span>
                <span>📄 文件 ${{allDocNotes.length}} 則</span>
                <span>📝 段落 ${{allParaNotes.length}} 則</span>
                <span style="font-weight: 600;">| 共 ${{total}} 則</span>
            `;
        }}

        // 渲染筆記中心內容
        function renderNoteCenterContent() {{
            const container = document.getElementById('note-center-content');

            if (noteCenterTab === 'site') {{
                container.innerHTML = renderSiteNotesCenter();
            }} else if (noteCenterTab === 'doc') {{
                container.innerHTML = renderDocNotesCenter();
            }} else {{
                container.innerHTML = renderParaNotesCenter();
            }}
        }}

        // 渲染網站筆記（筆記中心）
        function renderSiteNotesCenter() {{
            // 新增筆記輸入框
            let html = `
                <div style="margin-bottom: 20px; padding: 16px; background: #f9f9f9; border-radius: 8px; border: 1px solid var(--border-color, #e0e0e0);">
                    <div style="font-weight: 600; margin-bottom: 10px;">✏️ 新增網站筆記</div>
                    <textarea id="new-site-note" placeholder="寫下你對整個網站的心得..." style="width: 100%; min-height: 80px; padding: 10px; border: 1px solid var(--border-color, #e0e0e0); border-radius: 6px; resize: vertical; font-family: inherit; box-sizing: border-box;"></textarea>
                    <button onclick="addSiteNoteFromCenter()" style="margin-top: 10px; padding: 8px 20px; background: var(--link-color); color: white; border: none; border-radius: 5px; cursor: pointer;">💾 儲存筆記</button>
                </div>
            `;

            if (siteNotes.length === 0) {{
                html += `
                    <div class="note-center-empty">
                        <div class="icon">🌐</div>
                        <div>尚無網站筆記</div>
                        <div style="font-size: 13px; margin-top: 8px;">在上方輸入框新增你的第一則筆記</div>
                    </div>
                `;
            }} else {{
                html += `<div style="font-weight: 600; margin-bottom: 12px;">📋 已保存的筆記 (${{siteNotes.length}})</div>`;
                siteNotes.forEach(note => {{
                    html += `
                        <div class="note-center-item">
                            <div class="note-center-item-content">${{escapeHtml(note.content)}}</div>
                            <div class="note-center-item-footer">
                                <div class="note-center-item-time">${{formatTime(note.updated || note.created)}}</div>
                                <div class="note-center-item-actions">
                                    <button onclick="deleteSiteNoteFromCenter('${{note.id}}')">🗑️ 刪除</button>
                                </div>
                            </div>
                        </div>
                    `;
                }});
            }}
            return html;
        }}

        // 從筆記中心新增網站筆記
        function addSiteNoteFromCenter() {{
            const textarea = document.getElementById('new-site-note');
            const content = textarea.value.trim();
            if (!content) return;

            siteNotes.push({{
                id: 'site-' + Date.now(),
                content,
                created: Date.now(),
                updated: Date.now()
            }});
            localStorage.setItem('site-notes', JSON.stringify(siteNotes));

            textarea.value = '';
            updateNoteCenterCounts();
            renderNoteCenterContent();
        }}

        // 從筆記中心刪除網站筆記
        function deleteSiteNoteFromCenter(id) {{
            if (!confirm('確定要刪除這則筆記嗎？')) return;
            siteNotes = siteNotes.filter(n => n.id !== id);
            localStorage.setItem('site-notes', JSON.stringify(siteNotes));
            updateNoteCenterCounts();
            renderNoteCenterContent();
        }}

        // 渲染文件筆記（筆記中心）- 按頁面分組
        function renderDocNotesCenter() {{
            if (allDocNotes.length === 0) {{
                return `
                    <div class="note-center-empty">
                        <div class="icon">📄</div>
                        <div>尚無文件筆記</div>
                        <div style="font-size: 13px; margin-top: 8px;">進入任一文件，切換到「文件」分頁開始記錄</div>
                    </div>
                `;
            }}

            // 按頁面分組
            const grouped = {{}};
            allDocNotes.forEach(note => {{
                if (!grouped[note.pageId]) {{
                    grouped[note.pageId] = {{
                        pageTitle: note.pageTitle,
                        pageId: note.pageId,
                        notes: []
                    }};
                }}
                grouped[note.pageId].notes.push(note);
            }});

            let html = '';
            Object.values(grouped).forEach(group => {{
                html += `
                    <div class="note-group">
                        <div class="note-group-header">
                            <div class="note-group-title">📄 ${{escapeHtml(group.pageTitle)}}</div>
                            <div class="note-group-actions">
                                <span class="note-group-count">${{group.notes.length}} 則筆記</span>
                                <button onclick="jumpToPage('${{group.pageId}}')">前往 →</button>
                            </div>
                        </div>
                        <div class="note-group-items">
                `;
                group.notes.forEach(note => {{
                    html += `
                        <div class="note-center-item">
                            <div class="note-center-item-content">${{escapeHtml(note.content)}}</div>
                            <div class="note-center-item-footer">
                                <div class="note-center-item-time">${{formatTime(note.updated || note.created)}}</div>
                            </div>
                        </div>
                    `;
                }});
                html += `</div></div>`;
            }});
            return html;
        }}

        // 渲染段落筆記（筆記中心）- 按頁面分組
        function renderParaNotesCenter() {{
            if (allParaNotes.length === 0) {{
                return `
                    <div class="note-center-empty">
                        <div class="icon">📝</div>
                        <div>尚無段落筆記</div>
                        <div style="font-size: 13px; margin-top: 8px;">進入任一文件，在段落旁點擊 📝 開始記錄</div>
                    </div>
                `;
            }}

            // 按頁面分組
            const grouped = {{}};
            allParaNotes.forEach(note => {{
                if (!grouped[note.pageId]) {{
                    grouped[note.pageId] = {{
                        pageTitle: note.pageTitle,
                        pageId: note.pageId,
                        notes: []
                    }};
                }}
                grouped[note.pageId].notes.push(note);
            }});

            let html = '';
            Object.values(grouped).forEach(group => {{
                html += `
                    <div class="note-group">
                        <div class="note-group-header">
                            <div class="note-group-title">📄 ${{escapeHtml(group.pageTitle)}}</div>
                            <div class="note-group-actions">
                                <span class="note-group-count">${{group.notes.length}} 則筆記</span>
                                <button onclick="jumpToPage('${{group.pageId}}')">前往 →</button>
                            </div>
                        </div>
                        <div class="note-group-items">
                `;
                group.notes.forEach(note => {{
                    html += `
                        <div class="note-center-item">
                            <div class="note-center-item-context">「${{escapeHtml(note.context || '').slice(0, 60)}}...」</div>
                            <div class="note-center-item-content">${{escapeHtml(note.content)}}</div>
                            <div class="note-center-item-footer">
                                <div class="note-center-item-time">${{formatTime(note.updated || note.created)}}</div>
                                <div class="note-center-item-actions">
                                    <button class="jump-btn" onclick="jumpToParaNote('${{group.pageId}}', '${{note.paraId}}')">📍 跳轉</button>
                                </div>
                            </div>
                        </div>
                    `;
                }});
                html += `</div></div>`;
            }});
            return html;
        }}

        // 跳轉到頁面
        function jumpToPage(pageId) {{
            window.location.href = pageId;
        }}

        // 跳轉到段落筆記
        function jumpToParaNote(pageId, paraId) {{
            window.location.href = pageId + '?scrollTo=' + encodeURIComponent(paraId);
        }}

        // 開啟筆記面板（首頁無法新增段落筆記，跳轉到筆記中心）
        function openNotePanel(tab) {{
            openNoteCenter();
        }}
        <!-- /FEATURE:note_center -->

        <!-- FEATURE:help_modal -->
        // 開啟使用說明
        function openHelpModal() {{
            alert('📚 使用說明\\n\\n📝 筆記功能\\n- 🌐 網站筆記：記錄整體心得\\n- 📄 文件筆記：記錄單篇文件重點\\n- 📝 段落筆記：在段落旁點擊記錄\\n\\n🔍 搜尋功能\\n- 點擊搜尋框或按 Ctrl+K 快速搜尋\\n\\n🎨 其他功能\\n- 🌙 深色模式：右上角切換\\n- 📚 筆記中心：查看所有筆記');
        }}
        <!-- /FEATURE:help_modal -->

        <!-- FEATURE:export -->
        // 開啟匯出 Modal（首頁簡化版）
        function openExportModal() {{
            collectAllNotes();
            const total = siteNotes.length + allDocNotes.length + allParaNotes.length;
            if (total === 0) {{
                alert('目前沒有任何筆記可匯出');
                return;
            }}

            const content = generateExportContent();
            const blob = new Blob([content], {{ type: 'text/markdown;charset=utf-8' }});
            const url = URL.createObjectURL(blob);
            const a = document.createElement('a');
            a.href = url;
            a.download = '全站筆記匯出.md';
            a.click();
            URL.revokeObjectURL(url);

            closeNoteCenter();
        }}

        // 生成匯出內容
        function generateExportContent() {{
            let content = `# 學習筆記匯出\\n\\n`;
            content += `> 匯出時間：${{new Date().toLocaleString('zh-TW')}}\\n\\n`;

            if (siteNotes.length > 0) {{
                content += `## 🌐 網站筆記\\n\\n`;
                siteNotes.forEach(note => {{
                    content += `${{note.content}}\\n\\n---\\n\\n`;
                }});
            }}

            if (allDocNotes.length > 0) {{
                content += `## 📄 文件筆記\\n\\n`;
                const grouped = {{}};
                allDocNotes.forEach(note => {{
                    if (!grouped[note.pageId]) grouped[note.pageId] = [];
                    grouped[note.pageId].push(note);
                }});
                Object.entries(grouped).forEach(([pageId, notes]) => {{
                    content += `### ${{notes[0].pageTitle || pageId}}\\n\\n`;
                    notes.forEach(note => {{
                        content += `${{note.content}}\\n\\n`;
                    }});
                    content += `---\\n\\n`;
                }});
            }}

            if (allParaNotes.length > 0) {{
                content += `## 📝 段落筆記\\n\\n`;
                const grouped = {{}};
                allParaNotes.forEach(note => {{
                    if (!grouped[note.pageId]) grouped[note.pageId] = [];
                    grouped[note.pageId].push(note);
                }});
                Object.entries(grouped).forEach(([pageId, notes]) => {{
                    content += `### ${{notes[0].pageTitle || pageId}}\\n\\n`;
                    notes.forEach(note => {{
                        if (note.context) content += `> ${{note.context.slice(0, 80)}}...\\n\\n`;
                        content += `${{note.content}}\\n\\n---\\n\\n`;
                    }});
                }});
            }}

            const total = siteNotes.length + allDocNotes.length + allParaNotes.length;
            content += `\\n---\\n共 ${{total}} 則筆記`;
            return content;
        }}
        <!-- /FEATURE:export -->

        // 輔助函數
        function escapeHtml(text) {{
            if (!text) return '';
            const div = document.createElement('div');
            div.textContent = text;
            return div.innerHTML;
        }}

        function formatTime(timestamp) {{
            if (!timestamp) return '';
            const date = new Date(timestamp);
            return date.toLocaleString('zh-TW', {{ month: 'short', day: 'numeric', hour: '2-digit', minute: '2-digit' }});
        }}

        <!-- FEATURE:note_center -->
        // ESC 關閉
        document.addEventListener('keydown', function(e) {{
            if (e.key === 'Escape') {{
                closeNoteCenter();
            }}
        }});

        // 點擊背景關閉
        document.getElementById('note-center-modal').addEventListener('click', function(e) {{
            if (e.target === this) {{
                closeNoteCenter();
            }}
        }});
        <!-- /FEATURE:note_center -->
    </script>

    <!-- FEATURE:note_center -->
    <!-- 筆記中心 Modal -->
    <div class="note-center-modal" id="note-center-modal">
        <div class="note-center-container">
            <div class="note-center-header">
                <h2>📚 筆記中心</h2>
                <button class="close-btn" onclick="closeNoteCenter()">✕</button>
            </div>
            <div class="note-center-tabs">
                <button class="note-center-tab active" data-tab="site" onclick="switchNoteCenterTab('site')">
                    🌐 網站筆記 <span class="badge" id="nc-site-count">0</span>
                </button>
                <button class="note-center-tab" data-tab="doc" onclick="switchNoteCenterTab('doc')">
                    📄 文件筆記 <span class="badge" id="nc-doc-count">0</span>
                </button>
                <button class="note-center-tab" data-tab="para" onclick="switchNoteCenterTab('para')">
                    📝 段落筆記 <span class="badge" id="nc-para-count">0</span>
                </button>
            </div>
            <div class="note-center-content" id="note-center-content">
                <!-- 動態載入內容 -->
            </div>
            <div class="note-center-footer">
                <div class="note-center-stats" id="note-center-stats">
                    載入中...
                </div>
                <button onclick="openExportModal()" style="padding: 8px 16px; border-radius: 5px; border: 1px solid var(--code-border); background: var(--bg-color); cursor: pointer; color: var(--text-color);">
                    📤 匯出全部
                </button>
            </div>
        </div>
    </div>
    <!-- /FEATURE:note_center -->

    <footer class="site-footer">
        v1.2.0 | Markdown to HTML Site Generator
    </footer>
</body>
</html>
'''

# ===== 文件頁面模板 =====
DOC_TEMPLATE = '''<!DOCTYPE html>
<html lang="zh-TW">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>{title}</title>
    <style>
        :root {{
            --bg-color: #ffffff;
            --text-color: #333333;
            --heading-color: #1a1a1a;
            --code-bg: #f5f5f5;
            --code-border: #ddd;
            --nav-bg: #f8f8f8;
            --nav-border: #ddd;
            --toc-border: #eee;
            --link-color: #0066cc;
            --table-header-bg: #f8f8f8;
            --progress-color: #0066cc;
            --font-size: 16px;
        }}

        [data-theme="dark"] {{
            --bg-color: #1a1a2e;
            --text-color: #e0e0e0;
            --heading-color: #ffffff;
            --code-bg: #252540;
            --code-border: #3a3a5a;
            --nav-bg: #16162a;
            --nav-border: #2a2a4a;
            --toc-border: #2a2a4a;
            --link-color: #6db3f2;
            --table-header-bg: #252540;
            --progress-color: #6db3f2;
        }}

        * {{ box-sizing: border-box; }}

        html {{
            font-size: var(--font-size);
        }}

        body {{
            font-family: "微軟正黑體", "Microsoft JhengHei", sans-serif;
            line-height: 1.8;
            color: var(--text-color);
            background: var(--bg-color);
            margin: 0;
            padding: 0;
            transition: background-color 0.3s, color 0.3s;
        }}

        /* 閱讀進度條 */
        .progress-bar {{
            position: fixed;
            top: 0;
            left: 0;
            height: 3px;
            background: var(--progress-color);
            width: 0%;
            z-index: 9999;
            transition: width 0.1s;
        }}

        /* 頂部導航 */
        .nav {{
            background: var(--nav-bg);
            border-bottom: 1px solid var(--nav-border);
            padding: 10px 30px;
            font-size: 0.85em;
            display: flex;
            justify-content: space-between;
            align-items: center;
            position: sticky;
            top: 0;
            z-index: 100;
        }}

        .nav a {{
            color: var(--link-color);
            text-decoration: none;
        }}

        .nav a:hover {{
            text-decoration: underline;
        }}

        .nav .sep {{
            color: #999;
            margin: 0 8px;
        }}

        .nav-left {{
            display: flex;
            align-items: center;
            min-width: 0;
            flex: 1;
        }}

        .nav-category {{
            color: var(--text-color);
            opacity: 0.7;
        }}

        .nav-title {{
            color: var(--heading-color);
            font-weight: 500;
            white-space: nowrap;
            overflow: hidden;
            text-overflow: ellipsis;
            max-width: 300px;
        }}

        .nav .tools {{
            display: flex;
            gap: 6px;
            align-items: center;
        }}

        .nav button {{
            padding: 5px 10px;
            border: 1px solid var(--nav-border);
            background: var(--bg-color);
            color: var(--text-color);
            border-radius: 4px;
            cursor: pointer;
            font-size: 13px;
        }}

        .nav button:hover {{
            opacity: 0.8;
        }}

        .font-size-controls {{
            display: flex;
            gap: 2px;
        }}

        .font-size-controls button {{
            padding: 5px 8px;
            font-weight: bold;
        }}

        /* 主要佈局 */
        .wrapper {{
            display: flex;
            max-width: 1200px;
            margin: 0 auto;
        }}

        /* 側邊目錄 */
        .toc {{
            width: 220px;
            min-width: 220px;
            padding: 25px 20px;
            border-right: 1px solid var(--toc-border);
            font-size: 0.85em;
            position: sticky;
            top: 50px;
            height: calc(100vh - 50px);
            overflow-y: auto;
            background: var(--bg-color);
        }}

        .toc h2 {{
            font-size: 0.9em;
            color: var(--text-color);
            opacity: 0.7;
            margin-bottom: 12px;
            padding-bottom: 8px;
            border-bottom: 1px solid var(--toc-border);
        }}

        .toc ul {{
            list-style: none;
            padding: 0;
            margin: 0;
        }}

        .toc li {{
            margin: 6px 0;
        }}

        .toc a {{
            color: var(--text-color);
            opacity: 0.8;
            text-decoration: none;
            display: block;
            padding: 3px 0;
        }}

        .toc a:hover {{
            color: var(--link-color);
            opacity: 1;
        }}

        .toc-h3 {{
            padding-left: 12px;
            font-size: 0.95em;
        }}

        <!-- FEATURE:floating_toc -->
        /* 浮動目錄（Notion 風格） */
        .toc {{
            position: fixed;
            left: 0;
            top: 50px;
            width: 280px;
            height: calc(100vh - 50px);
            transform: translateX(-260px);
            transition: transform 0.3s ease, box-shadow 0.3s ease;
            z-index: 50;
            box-shadow: none;
            border-right: none;
            background: var(--bg-color);
            padding: 25px 20px;
        }}

        .toc::before {{
            content: '≡';
            position: absolute;
            right: -36px;
            top: 80px;
            width: 36px;
            height: 36px;
            background: var(--card-bg, var(--bg-color));
            border: 1px solid var(--toc-border);
            border-left: none;
            border-radius: 0 8px 8px 0;
            display: flex;
            align-items: center;
            justify-content: center;
            cursor: pointer;
            font-size: 18px;
            font-weight: bold;
            color: var(--text-color);
            opacity: 0.5;
            transition: opacity 0.2s, background 0.2s;
            box-shadow: 2px 2px 8px rgba(0,0,0,0.1);
        }}

        .toc:hover::before,
        .toc::before:hover {{
            opacity: 0.8;
            background: var(--hover-bg, #f5f5f5);
        }}

        .toc:hover {{
            transform: translateX(0);
            box-shadow: 4px 0 25px rgba(0,0,0,0.15);
            border-right: 1px solid var(--toc-border);
        }}

        .toc:hover::before {{
            opacity: 0;
            pointer-events: none;
        }}

        /* 浮動目錄時，內容保持置中 */
        .wrapper {{
            max-width: 900px;
            margin: 0 auto;
            display: block;
        }}

        .wrapper .content {{
            max-width: 100%;
            margin: 0 auto;
        }}
        <!-- /FEATURE:floating_toc -->

        /* 主要內容 */
        .content {{
            flex: 1;
            padding: 30px 50px;
            max-width: 800px;
        }}

        h1 {{
            font-size: 1.6em;
            margin: 0 0 25px 0;
            padding-bottom: 12px;
            border-bottom: 2px solid var(--heading-color);
            color: var(--heading-color);
        }}

        h2 {{
            font-size: 1.25em;
            margin: 35px 0 15px 0;
            padding-bottom: 8px;
            border-bottom: 1px solid var(--toc-border);
            color: var(--heading-color);
        }}

        h3 {{
            font-size: 1.05em;
            margin: 25px 0 10px 0;
            color: var(--heading-color);
        }}

        p {{
            margin: 12px 0;
        }}

        /* 程式碼區塊 */
        pre {{
            background: var(--code-bg);
            border: 1px solid var(--code-border);
            padding: 15px;
            overflow-x: auto;
            margin: 15px 0;
            font-size: 13px;
            border-radius: 4px;
            position: relative;
        }}

        pre code {{
            font-family: "Cascadia Code", "Consolas", "Source Code Pro", monospace;
            line-height: 1.5;
            color: var(--text-color);
        }}

        .copy-btn {{
            position: absolute;
            top: 8px;
            right: 8px;
            padding: 4px 10px;
            font-size: 12px;
            background: var(--link-color);
            color: white;
            border: none;
            border-radius: 4px;
            cursor: pointer;
            opacity: 0;
            transition: opacity 0.2s;
        }}

        pre:hover .copy-btn {{
            opacity: 1;
        }}

        code {{
            font-family: "Cascadia Code", "Consolas", monospace;
            background: var(--code-bg);
            padding: 2px 5px;
            font-size: 0.9em;
            border-radius: 3px;
        }}

        pre code {{
            background: none;
            padding: 0;
        }}

        /* 表格 */
        table {{
            border-collapse: collapse;
            width: 100%;
            margin: 15px 0;
            font-size: 0.9em;
        }}

        th, td {{
            border: 1px solid var(--code-border);
            padding: 10px 12px;
            text-align: left;
        }}

        th {{
            background: var(--table-header-bg);
            font-weight: bold;
        }}

        /* 引用 */
        blockquote {{
            border-left: 3px solid var(--link-color);
            margin: 15px 0;
            padding: 10px 20px;
            background: var(--code-bg);
            border-radius: 0 4px 4px 0;
        }}

        hr {{
            border: none;
            border-top: 1px solid var(--toc-border);
            margin: 30px 0;
        }}

        a {{
            color: var(--link-color);
        }}

        /* 底部導航 */
        .doc-nav {{
            display: flex;
            justify-content: space-between;
            margin-top: 40px;
            padding-top: 20px;
            border-top: 1px solid var(--toc-border);
            font-size: 0.9em;
        }}

        .doc-nav a {{
            text-decoration: none;
        }}

        .doc-nav a:hover {{
            text-decoration: underline;
        }}

        /* 回到頂部按鈕 */
        .back-to-top {{
            position: fixed;
            bottom: 30px;
            right: 30px;
            width: 45px;
            height: 45px;
            background: var(--link-color);
            color: white;
            border: none;
            border-radius: 50%;
            cursor: pointer;
            font-size: 20px;
            display: none;
            align-items: center;
            justify-content: center;
            box-shadow: 0 2px 10px rgba(0,0,0,0.2);
            z-index: 1000;
        }}

        .back-to-top:hover {{
            transform: scale(1.1);
        }}

        .back-to-top.visible {{
            display: flex;
        }}

        /* 影片區塊 */
        .video-section {{
            background: var(--code-bg);
            border: 1px solid var(--code-border);
            border-radius: 8px;
            padding: 15px;
            margin-bottom: 25px;
        }}

        .video-section h3 {{
            margin: 0 0 12px 0;
            font-size: 0.95em;
            color: var(--text-color);
            opacity: 0.8;
        }}

        .video-section video {{
            width: 100%;
            border-radius: 6px;
            background: #000;
        }}

        /* 懸浮影片播放器 (Picture-in-Picture 風格) */
        .pip-player {{
            position: fixed;
            bottom: 90px;
            right: 20px;
            width: 480px;
            background: #000;
            border-radius: 8px;
            box-shadow: 0 8px 32px rgba(0,0,0,0.4);
            z-index: 1500;
            display: none;
            overflow: hidden;
            transition: all 0.3s ease;
        }}

        .pip-player.active {{
            display: block;
            animation: pipSlideIn 0.3s ease;
        }}

        @keyframes pipSlideIn {{
            from {{
                opacity: 0;
                transform: translateY(20px) scale(0.9);
            }}
            to {{
                opacity: 1;
                transform: translateY(0) scale(1);
            }}
        }}

        .pip-player video {{
            width: 100%;
            display: block;
        }}

        .pip-controls {{
            display: flex;
            align-items: center;
            justify-content: space-between;
            padding: 8px 12px;
            background: linear-gradient(to top, rgba(0,0,0,0.9), rgba(0,0,0,0.7));
            position: absolute;
            bottom: 0;
            left: 0;
            right: 0;
        }}

        .pip-controls button {{
            background: none;
            border: none;
            color: white;
            cursor: pointer;
            padding: 6px;
            font-size: 16px;
            opacity: 0.9;
            transition: all 0.2s;
            border-radius: 4px;
        }}

        .pip-controls button:hover {{
            opacity: 1;
            background: rgba(255,255,255,0.2);
        }}

        .pip-left-controls,
        .pip-right-controls {{
            display: flex;
            gap: 4px;
            align-items: center;
        }}

        .pip-time {{
            color: white;
            font-size: 11px;
            opacity: 0.8;
            margin: 0 8px;
            font-family: monospace;
        }}

        .pip-progress {{
            position: absolute;
            top: 0;
            left: 0;
            right: 0;
            height: 3px;
            background: rgba(255,255,255,0.3);
            cursor: pointer;
        }}

        .pip-progress-bar {{
            height: 100%;
            background: #0066cc;
            width: 0%;
            transition: width 0.1s;
        }}

        .pip-close {{
            position: absolute;
            top: 8px;
            right: 8px;
            background: rgba(60,60,60,0.9) !important;
            color: #fff !important;
            border: 1px solid rgba(255,255,255,0.3) !important;
            border-radius: 50% !important;
            width: 28px;
            height: 28px;
            display: flex;
            align-items: center;
            justify-content: center;
            font-size: 14px !important;
            font-weight: bold !important;
            cursor: pointer !important;
            z-index: 15;
            transition: all 0.2s !important;
        }}

        .pip-close:hover {{
            background: rgba(200,60,60,0.9) !important;
            border-color: rgba(255,100,100,0.5) !important;
        }}

        .pip-back-to-video {{
            position: absolute;
            top: 8px;
            left: 8px;
            background: rgba(60,60,60,0.9) !important;
            color: #fff !important;
            border: 1px solid rgba(255,255,255,0.3) !important;
            border-radius: 4px !important;
            font-size: 11px !important;
            font-weight: bold !important;
            padding: 4px 10px !important;
            cursor: pointer !important;
            z-index: 15;
            opacity: 0;
            transition: all 0.2s !important;
        }}

        .pip-player:hover .pip-back-to-video {{
            opacity: 1;
        }}

        .pip-back-to-video:hover {{
            background: rgba(80,80,80,0.95) !important;
            border-color: rgba(255,255,255,0.5) !important;
        }}

        /* PIP 拖拽調整大小 */
        .pip-resize-handle {{
            position: absolute;
            width: 20px;
            height: 20px;
            cursor: nwse-resize;
            z-index: 10;
        }}

        .pip-resize-handle.top-left {{
            top: 0;
            left: 0;
            cursor: nwse-resize;
        }}

        .pip-resize-handle.bottom-right {{
            bottom: 0;
            right: 0;
            cursor: nwse-resize;
        }}

        .pip-resize-handle::after {{
            content: '';
            position: absolute;
            bottom: 3px;
            right: 3px;
            width: 8px;
            height: 8px;
            border-right: 2px solid rgba(255,255,255,0.5);
            border-bottom: 2px solid rgba(255,255,255,0.5);
        }}

        .pip-resize-handle.top-left::after {{
            top: 3px;
            left: 3px;
            bottom: auto;
            right: auto;
            border-right: none;
            border-bottom: none;
            border-left: 2px solid rgba(255,255,255,0.5);
            border-top: 2px solid rgba(255,255,255,0.5);
        }}

        /* PIP 大小預設按鈕 */
        .pip-size-controls {{
            position: absolute;
            top: 8px;
            left: 50%;
            transform: translateX(-50%);
            display: flex;
            gap: 6px;
            opacity: 0;
            transition: opacity 0.2s;
            z-index: 15;
        }}

        .pip-player:hover .pip-size-controls {{
            opacity: 1;
        }}

        .pip-size-btn {{
            background: rgba(60,60,60,0.9) !important;
            color: #fff !important;
            border: 1px solid rgba(255,255,255,0.3) !important;
            border-radius: 4px !important;
            font-size: 11px !important;
            font-weight: bold !important;
            padding: 4px 8px !important;
            min-width: auto !important;
            cursor: pointer !important;
            transition: all 0.2s !important;
        }}

        .pip-size-btn:hover {{
            background: rgba(80,80,80,0.95) !important;
            border-color: rgba(255,255,255,0.5) !important;
        }}

        .pip-size-btn.active {{
            background: rgba(0,120,215,0.9) !important;
            border-color: rgba(100,180,255,0.8) !important;
        }}

        /* 閱讀時間估計 */
        .reading-meta {{
            display: flex;
            gap: 20px;
            padding: 12px 16px;
            background: var(--code-bg);
            border-radius: 6px;
            font-size: 0.85em;
            color: var(--text-color);
            opacity: 0.8;
            margin-bottom: 20px;
        }}

        .reading-meta span {{
            display: flex;
            align-items: center;
            gap: 6px;
        }}

        /* 筆記功能 */
        .note-btn {{
            position: absolute;
            right: -30px;
            top: 0;
            width: 24px;
            height: 24px;
            background: var(--code-bg);
            border: 1px solid var(--code-border);
            border-radius: 4px;
            cursor: pointer;
            opacity: 0;
            transition: opacity 0.2s;
            font-size: 12px;
            display: flex;
            align-items: center;
            justify-content: center;
        }}

        .note-target {{
            position: relative;
        }}

        .note-target:hover .note-btn {{
            opacity: 0.6;
        }}

        .note-btn:hover {{
            opacity: 1 !important;
            background: var(--link-color);
            color: white;
        }}

        .note-btn.has-note {{
            opacity: 1;
            background: #ffc107;
            color: #333;
            border-color: #ffc107;
        }}

        .note-popup {{
            position: fixed;
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%);
            background: var(--bg-color);
            border: 1px solid var(--code-border);
            border-radius: 8px;
            padding: 20px;
            width: 400px;
            max-width: 90vw;
            box-shadow: 0 10px 40px rgba(0,0,0,0.3);
            z-index: 2000;
            display: none;
        }}

        .note-popup.active {{
            display: block;
        }}

        .note-popup h4 {{
            margin: 0 0 10px 0;
            font-size: 0.9em;
            color: var(--text-color);
            opacity: 0.7;
        }}

        .note-popup textarea {{
            width: 100%;
            height: 120px;
            padding: 10px;
            border: 1px solid var(--code-border);
            border-radius: 4px;
            background: var(--code-bg);
            color: var(--text-color);
            font-family: inherit;
            font-size: 14px;
            resize: vertical;
        }}

        .note-popup .note-actions {{
            display: flex;
            justify-content: flex-end;
            gap: 8px;
            margin-top: 12px;
        }}

        .note-popup button {{
            padding: 6px 14px;
            border: 1px solid var(--code-border);
            border-radius: 4px;
            cursor: pointer;
            font-size: 13px;
            background: var(--bg-color);
            color: var(--text-color);
        }}

        .note-popup button.save {{
            background: var(--link-color);
            color: white;
            border-color: var(--link-color);
        }}

        .note-popup button.delete {{
            color: #dc3545;
            border-color: #dc3545;
        }}

        .note-overlay {{
            position: fixed;
            top: 0;
            left: 0;
            right: 0;
            bottom: 0;
            background: rgba(0,0,0,0.5);
            z-index: 1999;
            display: none;
        }}

        .note-overlay.active {{
            display: block;
        }}

        /* 筆記匯出按鈕 */
        .export-notes-btn {{
            position: fixed;
            bottom: 30px;
            left: 30px;
            padding: 10px 16px;
            background: #ffc107;
            color: #333;
            border: none;
            border-radius: 6px;
            cursor: pointer;
            font-size: 13px;
            display: none;
            align-items: center;
            gap: 6px;
            box-shadow: 0 2px 10px rgba(0,0,0,0.2);
            z-index: 1000;
        }}

        .export-notes-btn.visible {{
            display: flex;
        }}

        .export-notes-btn:hover {{
            background: #e0a800;
        }}

        /* ===== 統一筆記面板 ===== */
        .note-panel {{
            position: fixed;
            top: 0;
            right: -420px;
            width: 400px;
            height: 100vh;
            background: var(--bg-color);
            border-left: 1px solid var(--code-border);
            box-shadow: -5px 0 20px rgba(0,0,0,0.15);
            z-index: 2000;
            transition: right 0.3s ease;
            display: flex;
            flex-direction: column;
        }}

        .note-panel.active {{
            right: 0;
        }}

        .note-panel-header {{
            display: flex;
            justify-content: space-between;
            align-items: center;
            padding: 16px 20px;
            border-bottom: 1px solid var(--code-border);
            background: var(--code-bg);
        }}

        .note-panel-header h3 {{
            margin: 0;
            font-size: 1.1em;
            display: flex;
            align-items: center;
            gap: 8px;
        }}

        .note-panel-close {{
            background: none;
            border: none;
            font-size: 20px;
            cursor: pointer;
            color: var(--text-color);
            opacity: 0.6;
            padding: 4px 8px;
            border-radius: 4px;
        }}

        .note-panel-close:hover {{
            opacity: 1;
            background: var(--code-border);
        }}

        /* 筆記分頁標籤 */
        .note-tabs {{
            display: flex;
            border-bottom: 1px solid var(--code-border);
            background: var(--code-bg);
        }}

        .note-tab {{
            flex: 1;
            padding: 12px 8px;
            border: none;
            background: none;
            cursor: pointer;
            font-size: 13px;
            color: var(--text-color);
            opacity: 0.6;
            transition: all 0.2s;
            display: flex;
            flex-direction: column;
            align-items: center;
            gap: 4px;
            border-bottom: 2px solid transparent;
        }}

        .note-tab:hover {{
            opacity: 0.9;
            background: rgba(0,0,0,0.05);
        }}

        .note-tab.active {{
            opacity: 1;
            border-bottom-color: var(--link-color);
            background: var(--bg-color);
        }}

        .note-tab-icon {{
            font-size: 18px;
        }}

        .note-tab-label {{
            font-size: 11px;
        }}

        .note-tab-count {{
            font-size: 10px;
            background: var(--code-border);
            padding: 1px 6px;
            border-radius: 10px;
        }}

        .note-tab.active .note-tab-count {{
            background: var(--link-color);
            color: white;
        }}

        /* 筆記內容區 */
        .note-panel-content {{
            flex: 1;
            overflow-y: auto;
            padding: 16px;
        }}

        .note-context {{
            background: var(--code-bg);
            border: 1px solid var(--code-border);
            border-radius: 6px;
            padding: 10px 12px;
            margin-bottom: 16px;
            font-size: 12px;
            color: var(--text-color);
            opacity: 0.8;
        }}

        .note-context-label {{
            font-weight: bold;
            margin-right: 6px;
        }}

        .note-editor {{
            margin-bottom: 16px;
        }}

        .note-editor textarea {{
            width: 100%;
            height: 120px;
            padding: 12px;
            border: 1px solid var(--code-border);
            border-radius: 6px;
            background: var(--bg-color);
            color: var(--text-color);
            font-family: inherit;
            font-size: 14px;
            resize: vertical;
            transition: border-color 0.2s;
        }}

        .note-editor textarea:focus {{
            outline: none;
            border-color: var(--link-color);
        }}

        .note-editor-actions {{
            display: flex;
            gap: 8px;
            margin-top: 10px;
        }}

        .note-editor-actions button {{
            padding: 8px 16px;
            border: 1px solid var(--code-border);
            border-radius: 5px;
            cursor: pointer;
            font-size: 13px;
            background: var(--bg-color);
            color: var(--text-color);
            display: flex;
            align-items: center;
            gap: 6px;
            transition: all 0.2s;
        }}

        .note-editor-actions button:hover {{
            background: var(--code-bg);
        }}

        .note-editor-actions button.primary {{
            background: var(--link-color);
            color: white;
            border-color: var(--link-color);
        }}

        .note-editor-actions button.primary:hover {{
            filter: brightness(1.1);
        }}

        .note-editor-actions button.danger {{
            color: #dc3545;
            border-color: #dc3545;
        }}

        .note-editor-actions button.danger:hover {{
            background: #dc3545;
            color: white;
        }}

        /* 筆記列表 */
        .note-list {{
            margin-top: 20px;
        }}

        .note-list-title {{
            font-size: 13px;
            font-weight: bold;
            color: var(--text-color);
            opacity: 0.7;
            margin-bottom: 12px;
            display: flex;
            align-items: center;
            gap: 6px;
        }}

        .note-list-item {{
            background: var(--code-bg);
            border: 1px solid var(--code-border);
            border-radius: 6px;
            padding: 12px;
            margin-bottom: 10px;
            cursor: pointer;
            transition: all 0.2s;
        }}

        .note-list-item:hover {{
            border-color: var(--link-color);
            box-shadow: 0 2px 8px rgba(0,0,0,0.1);
        }}

        .note-list-item.active {{
            border-color: var(--link-color);
            background: rgba(0,102,204,0.05);
        }}

        .note-list-item-header {{
            display: flex;
            justify-content: space-between;
            align-items: flex-start;
            margin-bottom: 6px;
        }}

        .note-list-item-context {{
            font-size: 11px;
            color: var(--text-color);
            opacity: 0.6;
            flex: 1;
            overflow: hidden;
            text-overflow: ellipsis;
            white-space: nowrap;
        }}

        .note-list-item-actions {{
            display: flex;
            gap: 4px;
        }}

        .note-list-item-actions button {{
            background: none;
            border: none;
            cursor: pointer;
            font-size: 12px;
            padding: 2px 6px;
            border-radius: 3px;
            opacity: 0.6;
        }}

        .note-list-item-actions button:hover {{
            opacity: 1;
            background: var(--code-border);
        }}

        .note-list-item-content {{
            font-size: 13px;
            color: var(--text-color);
            line-height: 1.5;
            overflow: hidden;
            display: -webkit-box;
            -webkit-line-clamp: 2;
            -webkit-box-orient: vertical;
        }}

        .note-list-item-time {{
            font-size: 10px;
            color: var(--text-color);
            opacity: 0.5;
            margin-top: 6px;
        }}

        .note-empty {{
            text-align: center;
            padding: 30px;
            color: var(--text-color);
            opacity: 0.5;
        }}

        .note-empty-icon {{
            font-size: 40px;
            margin-bottom: 10px;
        }}

        /* 工具列筆記按鈕 */
        .toolbar-note-btn {{
            background: none;
            border: 1px solid var(--code-border);
            border-radius: 5px;
            padding: 6px 12px;
            cursor: pointer;
            font-size: 13px;
            color: var(--text-color);
            display: flex;
            align-items: center;
            gap: 6px;
            transition: all 0.2s;
        }}

        .toolbar-note-btn:hover {{
            background: var(--code-bg);
            border-color: var(--link-color);
        }}

        .toolbar-note-btn.has-note {{
            background: #fff3cd;
            border-color: #ffc107;
            color: #856404;
        }}

        [data-theme="dark"] .toolbar-note-btn.has-note {{
            background: #4a4000;
            border-color: #ffc107;
            color: #ffc107;
        }}

        /* ===== 使用說明 Modal ===== */
        .help-modal {{
            position: fixed;
            top: 0;
            left: 0;
            right: 0;
            bottom: 0;
            background: rgba(0,0,0,0.6);
            z-index: 3000;
            display: none;
            justify-content: center;
            align-items: center;
            padding: 20px;
        }}

        .help-modal.active {{
            display: flex;
        }}

        .help-modal-content {{
            background: var(--bg-color);
            border-radius: 12px;
            max-width: 550px;
            width: 100%;
            max-height: 80vh;
            overflow-y: auto;
            box-shadow: 0 10px 40px rgba(0,0,0,0.3);
        }}

        .help-modal-header {{
            display: flex;
            justify-content: space-between;
            align-items: center;
            padding: 20px 24px;
            border-bottom: 1px solid var(--code-border);
        }}

        .help-modal-header h3 {{
            margin: 0;
            display: flex;
            align-items: center;
            gap: 10px;
        }}

        .help-modal-close {{
            background: none;
            border: none;
            font-size: 24px;
            cursor: pointer;
            color: var(--text-color);
            opacity: 0.6;
            padding: 4px;
        }}

        .help-modal-close:hover {{
            opacity: 1;
        }}

        .help-modal-body {{
            padding: 24px;
        }}

        .help-section {{
            margin-bottom: 24px;
        }}

        .help-section:last-child {{
            margin-bottom: 0;
        }}

        .help-section h4 {{
            margin: 0 0 12px 0;
            font-size: 1em;
            color: var(--link-color);
            display: flex;
            align-items: center;
            gap: 8px;
        }}

        .help-section ul {{
            margin: 0;
            padding-left: 24px;
        }}

        .help-section li {{
            margin-bottom: 6px;
            font-size: 14px;
            line-height: 1.6;
        }}

        .help-modal-footer {{
            padding: 16px 24px;
            border-top: 1px solid var(--code-border);
            display: flex;
            justify-content: space-between;
            align-items: center;
        }}

        .help-modal-footer label {{
            display: flex;
            align-items: center;
            gap: 8px;
            font-size: 13px;
            cursor: pointer;
        }}

        .help-modal-footer button {{
            padding: 8px 20px;
            background: var(--link-color);
            color: white;
            border: none;
            border-radius: 5px;
            cursor: pointer;
            font-size: 14px;
        }}

        /* ===== 匯出筆記 Modal ===== */
        .export-modal {{
            position: fixed;
            top: 0;
            left: 0;
            right: 0;
            bottom: 0;
            background: rgba(0,0,0,0.6);
            z-index: 3000;
            display: none;
            justify-content: center;
            align-items: center;
            padding: 20px;
        }}

        .export-modal.active {{
            display: flex;
        }}

        .export-modal-content {{
            background: var(--bg-color);
            border-radius: 12px;
            max-width: 450px;
            width: 100%;
            box-shadow: 0 10px 40px rgba(0,0,0,0.3);
        }}

        .export-modal-header {{
            display: flex;
            justify-content: space-between;
            align-items: center;
            padding: 20px 24px;
            border-bottom: 1px solid var(--code-border);
        }}

        .export-modal-header h3 {{
            margin: 0;
            display: flex;
            align-items: center;
            gap: 10px;
        }}

        .export-modal-close {{
            background: none;
            border: none;
            font-size: 24px;
            cursor: pointer;
            color: var(--text-color);
            opacity: 0.6;
        }}

        .export-modal-body {{
            padding: 24px;
        }}

        .export-option-group {{
            margin-bottom: 20px;
        }}

        .export-option-group h4 {{
            margin: 0 0 12px 0;
            font-size: 14px;
            color: var(--text-color);
        }}

        .export-option {{
            display: flex;
            align-items: center;
            gap: 10px;
            padding: 10px 12px;
            background: var(--code-bg);
            border: 1px solid var(--code-border);
            border-radius: 6px;
            margin-bottom: 8px;
            cursor: pointer;
            transition: all 0.2s;
        }}

        .export-option:hover {{
            border-color: var(--link-color);
        }}

        .export-option input {{
            margin: 0;
        }}

        .export-option label {{
            flex: 1;
            cursor: pointer;
            font-size: 14px;
        }}

        .export-option .count {{
            font-size: 12px;
            color: var(--text-color);
            opacity: 0.6;
        }}

        .export-modal-footer {{
            padding: 16px 24px;
            border-top: 1px solid var(--code-border);
            display: flex;
            justify-content: flex-end;
            gap: 10px;
        }}

        .export-modal-footer button {{
            padding: 10px 24px;
            border-radius: 5px;
            cursor: pointer;
            font-size: 14px;
            display: flex;
            align-items: center;
            gap: 8px;
        }}

        .export-modal-footer button.cancel {{
            background: var(--bg-color);
            border: 1px solid var(--code-border);
            color: var(--text-color);
        }}

        .export-modal-footer button.primary {{
            background: var(--link-color);
            border: none;
            color: white;
        }}

        /* ===== 筆記中心 Modal ===== */
        .note-center-modal {{
            display: none;
            position: fixed;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            background: rgba(0, 0, 0, 0.5);
            z-index: 3000;
            justify-content: center;
            align-items: center;
        }}

        .note-center-modal.active {{
            display: flex;
        }}

        .note-center-container {{
            background: var(--bg-color);
            border-radius: 12px;
            width: 90%;
            max-width: 800px;
            max-height: 85vh;
            display: flex;
            flex-direction: column;
            box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);
        }}

        .note-center-header {{
            padding: 20px 24px;
            border-bottom: 1px solid var(--code-border);
            display: flex;
            justify-content: space-between;
            align-items: center;
        }}

        .note-center-header h2 {{
            margin: 0;
            font-size: 20px;
            display: flex;
            align-items: center;
            gap: 10px;
        }}

        .note-center-header .close-btn {{
            background: none;
            border: none;
            font-size: 24px;
            cursor: pointer;
            color: var(--text-color);
            opacity: 0.6;
            padding: 5px;
            line-height: 1;
        }}

        .note-center-header .close-btn:hover {{
            opacity: 1;
        }}

        .note-center-tabs {{
            display: flex;
            padding: 0 24px;
            border-bottom: 1px solid var(--code-border);
            background: var(--code-bg);
        }}

        .note-center-tab {{
            padding: 14px 20px;
            border: none;
            background: none;
            cursor: pointer;
            font-size: 14px;
            color: var(--text-color);
            opacity: 0.6;
            border-bottom: 3px solid transparent;
            margin-bottom: -1px;
            transition: all 0.2s;
        }}

        .note-center-tab:hover {{
            opacity: 0.8;
        }}

        .note-center-tab.active {{
            opacity: 1;
            border-bottom-color: var(--link-color);
            font-weight: 600;
        }}

        .note-center-tab .badge {{
            display: inline-block;
            background: var(--link-color);
            color: white;
            font-size: 11px;
            padding: 2px 6px;
            border-radius: 10px;
            margin-left: 6px;
        }}

        .note-center-content {{
            flex: 1;
            overflow-y: auto;
            padding: 20px 24px;
        }}

        .note-center-empty {{
            text-align: center;
            padding: 60px 20px;
            color: var(--text-color);
            opacity: 0.5;
        }}

        .note-center-empty .icon {{
            font-size: 48px;
            margin-bottom: 16px;
        }}

        /* 文件分組 */
        .note-group {{
            margin-bottom: 24px;
            border: 1px solid var(--code-border);
            border-radius: 8px;
            overflow: hidden;
        }}

        .note-group-header {{
            background: var(--code-bg);
            padding: 12px 16px;
            display: flex;
            justify-content: space-between;
            align-items: center;
            cursor: pointer;
            transition: background 0.2s;
        }}

        .note-group-header:hover {{
            background: var(--blockquote-bg);
        }}

        .note-group-title {{
            font-weight: 600;
            font-size: 14px;
            display: flex;
            align-items: center;
            gap: 8px;
        }}

        .note-group-count {{
            font-size: 12px;
            color: var(--text-color);
            opacity: 0.6;
        }}

        .note-group-actions {{
            display: flex;
            gap: 8px;
        }}

        .note-group-actions button {{
            padding: 6px 12px;
            font-size: 12px;
            border: 1px solid var(--code-border);
            background: var(--bg-color);
            border-radius: 4px;
            cursor: pointer;
            color: var(--text-color);
            transition: all 0.2s;
        }}

        .note-group-actions button:hover {{
            border-color: var(--link-color);
            color: var(--link-color);
        }}

        .note-group-items {{
            padding: 12px 16px;
        }}

        /* 筆記項目 */
        .note-center-item {{
            padding: 12px;
            border: 1px solid var(--code-border);
            border-radius: 6px;
            margin-bottom: 10px;
            background: var(--bg-color);
        }}

        .note-center-item:last-child {{
            margin-bottom: 0;
        }}

        .note-center-item-context {{
            font-size: 12px;
            color: var(--text-color);
            opacity: 0.6;
            margin-bottom: 8px;
            padding: 8px;
            background: var(--code-bg);
            border-radius: 4px;
            border-left: 3px solid var(--link-color);
        }}

        .note-center-item-content {{
            font-size: 14px;
            line-height: 1.6;
            margin-bottom: 10px;
        }}

        .note-center-item-footer {{
            display: flex;
            justify-content: space-between;
            align-items: center;
        }}

        .note-center-item-time {{
            font-size: 11px;
            color: var(--text-color);
            opacity: 0.5;
        }}

        .note-center-item-actions {{
            display: flex;
            gap: 6px;
        }}

        .note-center-item-actions button {{
            padding: 4px 10px;
            font-size: 12px;
            border: 1px solid var(--code-border);
            background: var(--bg-color);
            border-radius: 4px;
            cursor: pointer;
            color: var(--text-color);
            transition: all 0.2s;
        }}

        .note-center-item-actions button:hover {{
            border-color: var(--link-color);
            color: var(--link-color);
        }}

        .note-center-item-actions button.jump-btn {{
            background: var(--link-color);
            border-color: var(--link-color);
            color: white;
        }}

        .note-center-item-actions button.jump-btn:hover {{
            opacity: 0.8;
        }}

        /* 統計列 */
        .note-center-footer {{
            padding: 16px 24px;
            border-top: 1px solid var(--code-border);
            background: var(--code-bg);
            font-size: 13px;
            color: var(--text-color);
            display: flex;
            justify-content: space-between;
            align-items: center;
        }}

        .note-center-stats {{
            display: flex;
            gap: 16px;
        }}

        .note-center-stats span {{
            opacity: 0.7;
        }}

        /* 段落高亮動畫 */
        @keyframes noteHighlight {{
            0% {{ background-color: rgba(255, 235, 59, 0.6); }}
            100% {{ background-color: transparent; }}
        }}

        .note-highlight {{
            animation: noteHighlight 2s ease-out;
        }}

        .para-note-indicator {{
            position: absolute;
            right: -30px;
            top: 0;
            width: 24px;
            height: 24px;
            background: #ffc107;
            border-radius: 50%;
            display: flex;
            align-items: center;
            justify-content: center;
            font-size: 12px;
            cursor: pointer;
            box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2);
            transition: transform 0.2s;
        }}

        .para-note-indicator:hover {{
            transform: scale(1.1);
        }}

        /* 頁尾版本號 */
        .site-footer {{
            text-align: center;
            padding: 20px;
            font-size: 12px;
            color: var(--text-color);
            opacity: 0.5;
            border-top: 1px solid var(--code-border);
            margin-top: 40px;
        }}

        /* 章節測驗 */
        .quiz-section {{
            background: linear-gradient(135deg, #e8f5e9 0%, #c8e6c9 100%);
            border: 1px solid #a5d6a7;
            border-radius: 8px;
            padding: 20px;
            margin: 30px 0;
        }}

        [data-theme="dark"] .quiz-section {{
            background: linear-gradient(135deg, #1b5e20 0%, #2e7d32 100%);
            border-color: #388e3c;
        }}

        .quiz-section h4 {{
            margin: 0 0 15px 0;
            color: #2e7d32;
            font-size: 1em;
        }}

        [data-theme="dark"] .quiz-section h4 {{
            color: #a5d6a7;
        }}

        .quiz-question {{
            margin-bottom: 20px;
        }}

        .quiz-question p {{
            margin: 0 0 10px 0;
            font-weight: 500;
        }}

        .quiz-options {{
            display: flex;
            flex-direction: column;
            gap: 8px;
        }}

        .quiz-option {{
            display: flex;
            align-items: center;
            gap: 10px;
            padding: 10px 15px;
            background: rgba(255,255,255,0.7);
            border: 1px solid transparent;
            border-radius: 6px;
            cursor: pointer;
            transition: all 0.2s;
        }}

        [data-theme="dark"] .quiz-option {{
            background: rgba(0,0,0,0.2);
        }}

        .quiz-option:hover {{
            background: rgba(255,255,255,0.9);
        }}

        [data-theme="dark"] .quiz-option:hover {{
            background: rgba(0,0,0,0.3);
        }}

        .quiz-option.selected {{
            border-color: var(--link-color);
            background: rgba(255,255,255,0.95);
        }}

        .quiz-option.correct {{
            border-color: #4caf50;
            background: #e8f5e9;
        }}

        .quiz-option.incorrect {{
            border-color: #f44336;
            background: #ffebee;
        }}

        .quiz-result {{
            margin-top: 15px;
            padding: 12px;
            border-radius: 6px;
            text-align: center;
            font-weight: 500;
            display: none;
        }}

        .quiz-result.show {{
            display: block;
        }}

        .quiz-result.correct {{
            background: #e8f5e9;
            color: #2e7d32;
        }}

        .quiz-result.incorrect {{
            background: #ffebee;
            color: #c62828;
        }}

        <!-- FEATURE:watermark -->
        /* 浮水印 */
        .watermark {{
            position: fixed;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            pointer-events: none;
            z-index: 9998;
            overflow: hidden;
        }}

        .watermark-text {{
            position: absolute;
            white-space: nowrap;
            font-size: 16px;
            color: rgba(128, 128, 128, 0.15);
            transform: rotate(-30deg);
            user-select: none;
            font-family: "微軟正黑體", sans-serif;
        }}

        [data-theme="dark"] .watermark-text {{
            color: rgba(200, 200, 200, 0.08);
        }}

        @media print {{
            .watermark {{
                position: fixed;
                z-index: 9999;
            }}
            .watermark-text {{
                color: rgba(128, 128, 128, 0.2) !important;
            }}
        }}
        <!-- /FEATURE:watermark -->

        /* 列印 */
        @media print {{
            .nav, .toc, .back-to-top, .progress-bar, .copy-btn, .video-section, .note-btn, .export-notes-btn, .quiz-section {{ display: none !important; }}
            .content {{ max-width: 100%; padding: 20px; }}
            pre {{ white-space: pre-wrap; }}
            body {{ background: #fff; color: #000; }}
        }}

        @media (max-width: 800px) {{
            .toc {{ display: none; }}
            .content {{ padding: 20px; }}
        }}
    </style>
</head>
<body>
    <div class="progress-bar" id="progress-bar"></div>

    <!-- FEATURE:watermark -->
    <div class="watermark" id="watermark"></div>
    <!-- /FEATURE:watermark -->

    <nav class="nav">
        <div class="nav-left">
            <a href="{index_path}">← 返回目錄</a>
            <span class="sep">/</span>
            <span class="nav-category">{category}</span>
            <span class="sep">/</span>
            <span class="nav-title">{title}</span>
        </div>
        <div class="tools">
            <div class="font-size-controls">
                <button onclick="changeFontSize(-1)" title="縮小字體">A-</button>
                <button onclick="changeFontSize(1)" title="放大字體">A+</button>
            </div>
            <button onclick="toggleTheme()" id="theme-btn">🌙</button>
            <button onclick="window.print()">🖨️</button>
            <button class="toolbar-note-btn" onclick="openNotePanel('doc')" id="doc-note-btn" title="文件筆記">📝 筆記</button>
            <button onclick="openHelpModal()" title="使用說明">❓</button>
        </div>
    </nav>

    <div class="wrapper">
        <aside class="toc">
            <h2>本頁目錄</h2>
            {toc}
        </aside>

        <main class="content">
            {content}

            <div class="doc-nav">
                {prev_link}
                {next_link}
            </div>

            <footer style="margin-top: 50px; padding-top: 20px; border-top: 1px solid var(--toc-border); text-align: center; font-size: 0.8em; opacity: 0.5;">
                漢娜不動產估價師聯合事務所 製作
            </footer>
        </main>
    </div>

    <button class="back-to-top" id="back-to-top" onclick="scrollToTop()">↑</button>

    <!-- 懸浮影片播放器 -->
    <div class="pip-player" id="pip-player">
        <div class="pip-resize-handle top-left" onmousedown="startPipResize(event, 'top-left')"></div>
        <button class="pip-close" onclick="closePip()" title="關閉">✕</button>
        <div class="pip-size-controls">
            <button class="pip-size-btn" onclick="setPipSize('small', this)" title="小">S</button>
            <button class="pip-size-btn" onclick="setPipSize('medium', this)" title="中">M</button>
            <button class="pip-size-btn active" onclick="setPipSize('large', this)" title="大">L</button>
        </div>
        <button class="pip-back-to-video" onclick="scrollToVideo()" title="回到影片位置">↑ 回到影片</button>
        <video id="pip-video"></video>
        <div class="pip-progress" onclick="seekPip(event)">
            <div class="pip-progress-bar" id="pip-progress-bar"></div>
        </div>
        <div class="pip-controls">
            <div class="pip-left-controls">
                <button onclick="pipSeek(-10)" title="倒退 10 秒">⏪</button>
                <button onclick="togglePipPlay()" id="pip-play-btn" title="播放/暫停">▶</button>
                <button onclick="pipSeek(10)" title="快進 10 秒">⏩</button>
                <span class="pip-time" id="pip-time">0:00 / 0:00</span>
            </div>
            <div class="pip-right-controls">
                <button onclick="togglePipFullscreen()" title="全螢幕">⛶</button>
            </div>
        </div>
        <div class="pip-resize-handle bottom-right" onmousedown="startPipResize(event, 'bottom-right')"></div>
    </div>

    <!-- 筆記功能 -->
    <button class="export-notes-btn" id="export-notes-btn" onclick="openExportModal()">📝 匯出筆記</button>
    <div class="note-overlay" id="note-overlay" onclick="closeNotePanel()"></div>

    <!-- 統一筆記面板 -->
    <div class="note-panel" id="note-panel">
        <div class="note-panel-header">
            <h3>📝 筆記</h3>
            <button class="note-panel-close" onclick="closeNotePanel()">✕</button>
        </div>
        <div class="note-tabs">
            <button class="note-tab" data-tab="site" onclick="switchNoteTab('site')">
                <span class="note-tab-icon">🌐</span>
                <span class="note-tab-label">網站</span>
                <span class="note-tab-count" id="site-note-count">0</span>
            </button>
            <button class="note-tab" data-tab="doc" onclick="switchNoteTab('doc')">
                <span class="note-tab-icon">📄</span>
                <span class="note-tab-label">文件</span>
                <span class="note-tab-count" id="doc-note-count">0</span>
            </button>
            <button class="note-tab active" data-tab="para" onclick="switchNoteTab('para')">
                <span class="note-tab-icon">📝</span>
                <span class="note-tab-label">段落</span>
                <span class="note-tab-count" id="para-note-count">0</span>
            </button>
        </div>
        <div class="note-panel-content" id="note-panel-content">
            <!-- 動態載入內容 -->
        </div>
    </div>

    <!-- 使用說明 Modal -->
    <div class="help-modal" id="help-modal">
        <div class="help-modal-content">
            <div class="help-modal-header">
                <h3>❓ 使用說明</h3>
                <button class="help-modal-close" onclick="closeHelpModal()">✕</button>
            </div>
            <div class="help-modal-body">
                <div class="help-section">
                    <h4>🔍 搜尋功能</h4>
                    <ul>
                        <li>點擊搜尋框或按 <code>Ctrl+K</code> 快速搜尋</li>
                        <li>搜尋結果會高亮顯示關鍵字</li>
                    </ul>
                </div>
                <div class="help-section">
                    <h4>📝 筆記功能</h4>
                    <ul>
                        <li><strong>🌐 網站筆記</strong>：記錄整體心得（全站共用）</li>
                        <li><strong>📄 文件筆記</strong>：記錄單篇文件重點</li>
                        <li><strong>📝 段落筆記</strong>：在段落旁點擊 📝 記錄</li>
                    </ul>
                </div>
                <div class="help-section">
                    <h4>💾 筆記儲存</h4>
                    <ul>
                        <li>自動儲存於瀏覽器（換電腦會遺失）</li>
                        <li>建議定期點擊「匯出筆記」備份</li>
                    </ul>
                </div>
                <div class="help-section">
                    <h4>🎨 其他功能</h4>
                    <ul>
                        <li>🌙 深色模式：右上角切換</li>
                        <li>🔤 字體大小：A- / A+ 調整</li>
                        <li>📺 影片子母畫面：滾動時自動懸浮</li>
                    </ul>
                </div>
            </div>
            <div class="help-modal-footer">
                <label>
                    <input type="checkbox" id="hide-help-checkbox"> 不再顯示此說明
                </label>
                <button onclick="closeHelpModal()">我知道了</button>
            </div>
        </div>
    </div>

    <!-- 匯出筆記 Modal -->
    <div class="export-modal" id="export-modal">
        <div class="export-modal-content">
            <div class="export-modal-header">
                <h3>📤 匯出筆記</h3>
                <button class="export-modal-close" onclick="closeExportModal()">✕</button>
            </div>
            <div class="export-modal-body">
                <div class="export-option-group">
                    <h4>選擇要匯出的筆記範圍：</h4>
                    <div class="export-option">
                        <input type="checkbox" id="export-site" checked>
                        <label for="export-site">🌐 網站筆記</label>
                        <span class="count" id="export-site-count">(0 則)</span>
                    </div>
                    <div class="export-option">
                        <input type="checkbox" id="export-doc" checked>
                        <label for="export-doc">📄 文件筆記</label>
                        <span class="count" id="export-doc-count">(0 則)</span>
                    </div>
                    <div class="export-option">
                        <input type="checkbox" id="export-para" checked>
                        <label for="export-para">📝 段落筆記</label>
                        <span class="count" id="export-para-count">(0 則)</span>
                    </div>
                </div>
                <div class="export-option-group">
                    <h4>匯出格式：</h4>
                    <div class="export-option">
                        <input type="radio" name="export-format" id="format-md" value="md" checked>
                        <label for="format-md">Markdown (.md)</label>
                    </div>
                    <div class="export-option">
                        <input type="radio" name="export-format" id="format-txt" value="txt">
                        <label for="format-txt">純文字 (.txt)</label>
                    </div>
                </div>
            </div>
            <div class="export-modal-footer">
                <button class="cancel" onclick="closeExportModal()">取消</button>
                <button class="primary" onclick="doExportNotes()">📥 下載筆記</button>
            </div>
        </div>
    </div>

    <!-- 筆記中心 Modal -->
    <div class="note-center-modal" id="note-center-modal">
        <div class="note-center-container">
            <div class="note-center-header">
                <h2>📚 筆記中心</h2>
                <button class="close-btn" onclick="closeNoteCenter()">✕</button>
            </div>
            <div class="note-center-tabs">
                <button class="note-center-tab active" data-tab="site" onclick="switchNoteCenterTab('site')">
                    🌐 網站筆記 <span class="badge" id="nc-site-count">0</span>
                </button>
                <button class="note-center-tab" data-tab="doc" onclick="switchNoteCenterTab('doc')">
                    📄 文件筆記 <span class="badge" id="nc-doc-count">0</span>
                </button>
                <button class="note-center-tab" data-tab="para" onclick="switchNoteCenterTab('para')">
                    📝 段落筆記 <span class="badge" id="nc-para-count">0</span>
                </button>
            </div>
            <div class="note-center-content" id="note-center-content">
                <!-- 動態載入內容 -->
            </div>
            <div class="note-center-footer">
                <div class="note-center-stats" id="note-center-stats">
                    載入中...
                </div>
                <button onclick="openExportModal()" style="padding: 8px 16px; border-radius: 5px; border: 1px solid var(--code-border); background: var(--bg-color); cursor: pointer; color: var(--text-color);">
                    📤 匯出全部
                </button>
            </div>
        </div>
    </div>

    <script>
        // ===== 浮水印 =====
        (function initWatermark() {{
            const watermarkEl = document.getElementById('watermark');
            if (!watermarkEl) return;

            const text = '{watermark_text}';
            if (!text) return;

            const rows = 15;
            const cols = 8;

            for (let i = 0; i < rows; i++) {{
                for (let j = 0; j < cols; j++) {{
                    const span = document.createElement('span');
                    span.className = 'watermark-text';
                    span.textContent = text;
                    span.style.left = `${{j * 250 + (i % 2) * 125}}px`;
                    span.style.top = `${{i * 150}}px`;
                    watermarkEl.appendChild(span);
                }}
            }}
        }})();

        // ===== 懸浮影片播放器 (PIP) =====
        let mainVideo = null;
        let pipVideo = null;
        let pipPlayer = null;
        let pipEnabled = true;
        let pipManualClosed = false;

        function initPip() {{
            mainVideo = document.querySelector('.video-section video');
            pipVideo = document.getElementById('pip-video');
            pipPlayer = document.getElementById('pip-player');

            if (!mainVideo || !pipVideo) return;

            // 複製影片來源
            pipVideo.src = mainVideo.src || mainVideo.querySelector('source')?.src;

            // 同步播放狀態
            mainVideo.addEventListener('play', () => {{
                if (!pipPlayer.classList.contains('active')) {{
                    pipVideo.currentTime = mainVideo.currentTime;
                }}
            }});

            mainVideo.addEventListener('pause', () => {{
                if (!pipPlayer.classList.contains('active')) {{
                    pipVideo.pause();
                    updatePipPlayBtn();
                }}
            }});

            // PIP 影片時間更新
            pipVideo.addEventListener('timeupdate', () => {{
                updatePipProgress();
                updatePipTime();
            }});

            pipVideo.addEventListener('play', updatePipPlayBtn);
            pipVideo.addEventListener('pause', updatePipPlayBtn);
        }}

        function checkPipVisibility() {{
            if (!mainVideo || !pipPlayer || pipManualClosed) return;

            const rect = mainVideo.getBoundingClientRect();
            const isPlaying = !mainVideo.paused;
            const isOutOfView = rect.bottom < 0 || rect.top > window.innerHeight;

            if (isPlaying && isOutOfView && pipEnabled) {{
                // 影片在播放但離開視窗，顯示 PIP
                if (!pipPlayer.classList.contains('active')) {{
                    pipVideo.currentTime = mainVideo.currentTime;
                    pipVideo.play();
                    pipPlayer.classList.add('active');
                    mainVideo.pause();
                }}
            }} else if (!isOutOfView && pipPlayer.classList.contains('active')) {{
                // 影片回到視窗，關閉 PIP
                mainVideo.currentTime = pipVideo.currentTime;
                if (!pipVideo.paused) {{
                    mainVideo.play();
                }}
                pipVideo.pause();
                pipPlayer.classList.remove('active');
            }}
        }}

        function closePip() {{
            if (!pipPlayer || !mainVideo) return;
            pipManualClosed = true;
            mainVideo.currentTime = pipVideo.currentTime;
            mainVideo.pause();
            pipVideo.pause();
            pipPlayer.classList.remove('active');
        }}

        function scrollToVideo() {{
            if (!mainVideo) return;
            mainVideo.currentTime = pipVideo.currentTime;
            if (!pipVideo.paused) {{
                mainVideo.play();
            }}
            pipVideo.pause();
            pipPlayer.classList.remove('active');
            pipManualClosed = false;
            mainVideo.scrollIntoView({{ behavior: 'smooth', block: 'center' }});
        }}

        function togglePipPlay() {{
            if (!pipVideo) return;
            if (pipVideo.paused) {{
                pipVideo.play();
            }} else {{
                pipVideo.pause();
            }}
        }}

        function updatePipPlayBtn() {{
            const btn = document.getElementById('pip-play-btn');
            if (btn && pipVideo) {{
                btn.textContent = pipVideo.paused ? '▶' : '⏸';
            }}
        }}

        function pipSeek(seconds) {{
            if (!pipVideo) return;
            pipVideo.currentTime = Math.max(0, Math.min(pipVideo.duration, pipVideo.currentTime + seconds));
        }}

        function updatePipProgress() {{
            const bar = document.getElementById('pip-progress-bar');
            if (bar && pipVideo && pipVideo.duration) {{
                const percent = (pipVideo.currentTime / pipVideo.duration) * 100;
                bar.style.width = percent + '%';
            }}
        }}

        function updatePipTime() {{
            const timeEl = document.getElementById('pip-time');
            if (timeEl && pipVideo) {{
                const format = (t) => {{
                    const m = Math.floor(t / 60);
                    const s = Math.floor(t % 60);
                    return m + ':' + (s < 10 ? '0' : '') + s;
                }};
                timeEl.textContent = format(pipVideo.currentTime) + ' / ' + format(pipVideo.duration || 0);
            }}
        }}

        function seekPip(event) {{
            if (!pipVideo) return;
            const bar = event.currentTarget;
            const rect = bar.getBoundingClientRect();
            const percent = (event.clientX - rect.left) / rect.width;
            pipVideo.currentTime = percent * pipVideo.duration;
        }}

        function togglePipFullscreen() {{
            if (!pipVideo) return;
            if (pipVideo.requestFullscreen) {{
                pipVideo.requestFullscreen();
            }} else if (pipVideo.webkitRequestFullscreen) {{
                pipVideo.webkitRequestFullscreen();
            }}
        }}

        // PIP 大小預設值
        const pipSizes = {{
            small: 280,
            medium: 380,
            large: 480
        }};
        let currentPipSize = 'large';

        function setPipSize(size, btn) {{
            if (!pipPlayer) return;
            currentPipSize = size;
            pipPlayer.style.width = pipSizes[size] + 'px';

            // 更新按鈕狀態
            document.querySelectorAll('.pip-size-btn').forEach(b => {{
                b.classList.remove('active');
            }});
            if (btn) {{
                btn.classList.add('active');
            }} else {{
                // 沒有傳入按鈕時，根據 size 找到對應按鈕
                document.querySelectorAll('.pip-size-btn').forEach(b => {{
                    if (b.textContent === size[0].toUpperCase()) {{
                        b.classList.add('active');
                    }}
                }});
            }}

            // 儲存偏好
            localStorage.setItem('pipSize', size);
        }}

        // PIP 拖拽調整大小
        let isResizing = false;
        let resizeCorner = null;
        let startX, startY, startWidth, startRight, startBottom;

        function startPipResize(e, corner) {{
            if (!pipPlayer) return;
            e.preventDefault();
            isResizing = true;
            resizeCorner = corner;
            startX = e.clientX;
            startY = e.clientY;
            startWidth = pipPlayer.offsetWidth;
            startRight = parseInt(pipPlayer.style.right) || 20;
            startBottom = parseInt(pipPlayer.style.bottom) || 90;

            document.addEventListener('mousemove', doPipResize);
            document.addEventListener('mouseup', stopPipResize);
        }}

        function doPipResize(e) {{
            if (!isResizing || !pipPlayer) return;

            const dx = e.clientX - startX;
            const dy = e.clientY - startY;

            if (resizeCorner === 'bottom-right') {{
                // 從右下角拖拽
                const newWidth = Math.max(200, Math.min(600, startWidth + dx));
                pipPlayer.style.width = newWidth + 'px';
            }} else if (resizeCorner === 'top-left') {{
                // 從左上角拖拽
                const newWidth = Math.max(200, Math.min(600, startWidth - dx));
                const newRight = startRight - dx;
                pipPlayer.style.width = newWidth + 'px';
                pipPlayer.style.right = newRight + 'px';
            }}

            // 清除預設大小按鈕的 active 狀態
            document.querySelectorAll('.pip-size-btn').forEach(btn => {{
                btn.classList.remove('active');
            }});
        }}

        function stopPipResize() {{
            isResizing = false;
            resizeCorner = null;
            document.removeEventListener('mousemove', doPipResize);
            document.removeEventListener('mouseup', stopPipResize);
        }}

        // 初始化 PIP
        document.addEventListener('DOMContentLoaded', () => {{
            initPip();
            // 載入儲存的大小偏好
            const savedSize = localStorage.getItem('pipSize');
            if (savedSize && pipSizes[savedSize] && pipPlayer) {{
                pipPlayer.style.width = pipSizes[savedSize] + 'px';
                currentPipSize = savedSize;
                document.querySelectorAll('.pip-size-btn').forEach(btn => {{
                    btn.classList.toggle('active', btn.textContent === savedSize[0].toUpperCase());
                }});
            }}
        }});

        // 閱讀進度條
        window.addEventListener('scroll', function() {{
            const winScroll = document.documentElement.scrollTop;
            const height = document.documentElement.scrollHeight - document.documentElement.clientHeight;
            const scrolled = (winScroll / height) * 100;
            document.getElementById('progress-bar').style.width = scrolled + '%';

            // 回到頂部按鈕顯示/隱藏
            const backToTop = document.getElementById('back-to-top');
            if (winScroll > 300) {{
                backToTop.classList.add('visible');
            }} else {{
                backToTop.classList.remove('visible');
            }}

            // 檢查是否需要顯示/隱藏 PIP
            checkPipVisibility();
        }});

        // 回到頂部
        function scrollToTop() {{
            window.scrollTo({{ top: 0, behavior: 'smooth' }});
        }}

        // 字體大小調整
        let currentFontSize = parseInt(localStorage.getItem('fontSize')) || 16;
        document.documentElement.style.setProperty('--font-size', currentFontSize + 'px');

        function changeFontSize(delta) {{
            currentFontSize = Math.max(12, Math.min(24, currentFontSize + delta * 2));
            document.documentElement.style.setProperty('--font-size', currentFontSize + 'px');
            localStorage.setItem('fontSize', currentFontSize);
        }}

        // 程式碼複製按鈕
        document.querySelectorAll('pre').forEach(pre => {{
            const btn = document.createElement('button');
            btn.className = 'copy-btn';
            btn.textContent = '複製';
            btn.onclick = function() {{
                const code = pre.querySelector('code');
                navigator.clipboard.writeText(code ? code.textContent : pre.textContent).then(() => {{
                    btn.textContent = '✓ 已複製';
                    setTimeout(() => btn.textContent = '複製', 2000);
                }});
            }};
            pre.appendChild(btn);
        }});

        // 夜間模式切換
        function toggleTheme() {{
            const html = document.documentElement;
            const btn = document.getElementById('theme-btn');
            if (html.getAttribute('data-theme') === 'dark') {{
                html.removeAttribute('data-theme');
                btn.textContent = '🌙';
                localStorage.setItem('theme', 'light');
            }} else {{
                html.setAttribute('data-theme', 'dark');
                btn.textContent = '☀️';
                localStorage.setItem('theme', 'dark');
            }}
        }}

        // 讀取儲存的設定
        if (localStorage.getItem('theme') === 'dark') {{
            document.documentElement.setAttribute('data-theme', 'dark');
            document.getElementById('theme-btn').textContent = '☀️';
        }}

        // 目錄平滑滾動
        document.querySelectorAll('.toc a').forEach(link => {{
            link.addEventListener('click', e => {{
                e.preventDefault();
                const target = document.querySelector(link.getAttribute('href'));
                if (target) target.scrollIntoView({{ behavior: 'smooth', block: 'start' }});
            }});
        }});

        // 鍵盤快捷鍵
        document.addEventListener('keydown', function(e) {{
            if (e.key === 'ArrowLeft' && e.altKey) {{
                const prevLink = document.querySelector('.doc-nav a[href*="prev"], .doc-nav a:first-child');
                if (prevLink && prevLink.href) window.location = prevLink.href;
            }}
            if (e.key === 'ArrowRight' && e.altKey) {{
                const nextLink = document.querySelector('.doc-nav a:last-child');
                if (nextLink && nextLink.href) window.location = nextLink.href;
            }}
        }});

        // 搜尋高亮功能
        (function() {{
            const params = new URLSearchParams(window.location.search);
            const highlight = params.get('highlight');
            if (!highlight) return;

            const content = document.querySelector('.content');
            if (!content) return;

            // 遞迴處理文字節點
            function highlightText(node, keyword) {{
                if (node.nodeType === 3) {{ // 文字節點
                    const text = node.textContent;
                    const lower = text.toLowerCase();
                    const idx = lower.indexOf(keyword.toLowerCase());
                    if (idx >= 0) {{
                        const span = document.createElement('span');
                        span.innerHTML = text.slice(0, idx) +
                            '<mark class="search-highlight">' + text.slice(idx, idx + keyword.length) + '</mark>' +
                            text.slice(idx + keyword.length);
                        node.parentNode.replaceChild(span, node);
                        return true;
                    }}
                }} else if (node.nodeType === 1 && !['SCRIPT', 'STYLE', 'MARK'].includes(node.tagName)) {{
                    for (let child of Array.from(node.childNodes)) {{
                        if (highlightText(child, keyword)) return true;
                    }}
                }}
                return false;
            }}

            // 加入高亮樣式
            const style = document.createElement('style');
            style.textContent = '.search-highlight {{ background: #fff3cd; padding: 2px 4px; border-radius: 3px; }}';
            document.head.appendChild(style);

            // 執行高亮
            highlightText(content, highlight);

            // 滾動到第一個高亮處
            setTimeout(() => {{
                const first = document.querySelector('.search-highlight');
                if (first) {{
                    first.scrollIntoView({{ behavior: 'smooth', block: 'center' }});
                }}
            }}, 100);
        }})();

        // ===== 三層筆記系統 =====
        const pageId = window.location.pathname;
        const pageTitle = document.querySelector('h1')?.textContent || document.title || '未知頁面';
        const siteId = window.location.origin + window.location.pathname.split('/').slice(0, -1).join('/');

        // 筆記儲存結構
        let siteNotes = JSON.parse(localStorage.getItem('site-notes') || '[]');
        let docNotes = JSON.parse(localStorage.getItem(`doc-notes:${{pageId}}`) || '[]');
        let paraNotes = JSON.parse(localStorage.getItem(`para-notes:${{pageId}}`) || '[]');

        let currentTab = 'para';
        let currentParaId = null;
        let currentParaContext = '';
        let editingNoteId = null;

        // 處理 URL 參數跳轉
        function handleScrollTo() {{
            const urlParams = new URLSearchParams(window.location.search);
            const scrollTo = urlParams.get('scrollTo');
            if (scrollTo) {{
                setTimeout(() => {{
                    const el = document.querySelector(`[data-para-id="${{scrollTo}}"]`);
                    if (el) {{
                        el.scrollIntoView({{ behavior: 'smooth', block: 'center' }});
                        el.classList.add('note-highlight');
                        setTimeout(() => el.classList.remove('note-highlight'), 2500);
                    }}
                }}, 300);
            }}
        }}

        // 為段落添加筆記按鈕
        function initNotes() {{
            const content = document.querySelector('.content');
            if (!content) return;

            let noteIndex = 0;
            content.querySelectorAll('p, h2, h3, li, blockquote').forEach(el => {{
                if (el.closest('.doc-nav') || el.closest('.reading-meta') || el.closest('.video-section') || el.closest('.quiz-section')) return;

                const paraId = `para-${{noteIndex++}}`;
                el.classList.add('note-target');
                el.dataset.paraId = paraId;

                const btn = document.createElement('button');
                btn.className = 'note-btn';
                btn.innerHTML = '📝';
                btn.title = '添加筆記';
                btn.onclick = (e) => {{
                    e.stopPropagation();
                    openNotePanel('para', paraId, el.textContent.slice(0, 50));
                }};

                // 檢查是否已有筆記
                if (paraNotes.some(n => n.paraId === paraId)) {{
                    btn.classList.add('has-note');
                }}

                el.appendChild(btn);
            }});

            updateNoteCounts();
            updateExportButton();

            // 處理 URL 跳轉
            handleScrollTo();

            // 首次使用顯示說明
            if (!localStorage.getItem('hide-help') && !localStorage.getItem('help-shown')) {{
                localStorage.setItem('help-shown', 'true');
                setTimeout(() => openHelpModal(), 500);
            }}
        }}

        // 開啟筆記面板
        function openNotePanel(tab, paraId = null, context = '') {{
            currentParaId = paraId;
            currentParaContext = context;
            editingNoteId = null;

            document.getElementById('note-panel').classList.add('active');
            document.getElementById('note-overlay').classList.add('active');

            switchNoteTab(tab);
        }}

        // 關閉筆記面板
        function closeNotePanel() {{
            document.getElementById('note-panel').classList.remove('active');
            document.getElementById('note-overlay').classList.remove('active');
        }}

        // 切換分頁
        function switchNoteTab(tab) {{
            currentTab = tab;
            editingNoteId = null;

            // 更新分頁按鈕狀態
            document.querySelectorAll('.note-tab').forEach(t => {{
                t.classList.toggle('active', t.dataset.tab === tab);
            }});

            // 渲染內容
            renderNoteContent();
        }}

        // 渲染筆記內容
        function renderNoteContent() {{
            const container = document.getElementById('note-panel-content');
            let html = '';

            if (currentTab === 'site') {{
                html = renderSiteNotes();
            }} else if (currentTab === 'doc') {{
                html = renderDocNotes();
            }} else {{
                html = renderParaNotes();
            }}

            container.innerHTML = html;
        }}

        // 渲染網站筆記
        function renderSiteNotes() {{
            let html = `
                <div class="note-context">
                    <span class="note-context-label">🌐 網站筆記</span>
                    記錄整個網站的學習心得
                </div>
                <div class="note-editor">
                    <textarea id="note-textarea" placeholder="寫下你對整個網站的心得...">${{editingNoteId ? (siteNotes.find(n => n.id === editingNoteId)?.content || '') : ''}}</textarea>
                    <div class="note-editor-actions">
                        <button class="primary" onclick="saveSiteNote()">💾 儲存</button>
                        ${{editingNoteId ? '<button class="danger" onclick="deleteSiteNote()">🗑️ 刪除</button>' : ''}}
                    </div>
                </div>
            `;

            if (siteNotes.length > 0) {{
                html += `<div class="note-list"><div class="note-list-title">📋 已保存的網站筆記</div>`;
                siteNotes.forEach(note => {{
                    html += `
                        <div class="note-list-item ${{editingNoteId === note.id ? 'active' : ''}}" onclick="editSiteNote('${{note.id}}')">
                            <div class="note-list-item-content">${{escapeHtml(note.content)}}</div>
                            <div class="note-list-item-time">${{formatTime(note.updated)}}</div>
                        </div>
                    `;
                }});
                html += `</div>`;
            }}

            return html;
        }}

        // 渲染文件筆記
        function renderDocNotes() {{
            const docTitle = document.querySelector('h1')?.textContent || '本文件';
            let html = `
                <div class="note-context">
                    <span class="note-context-label">📄 文件筆記</span>
                    ${{docTitle}}
                </div>
                <div class="note-editor">
                    <textarea id="note-textarea" placeholder="寫下你對這篇文件的筆記...">${{editingNoteId ? (docNotes.find(n => n.id === editingNoteId)?.content || '') : ''}}</textarea>
                    <div class="note-editor-actions">
                        <button class="primary" onclick="saveDocNote()">💾 儲存</button>
                        ${{editingNoteId ? '<button class="danger" onclick="deleteDocNote()">🗑️ 刪除</button>' : ''}}
                    </div>
                </div>
            `;

            if (docNotes.length > 0) {{
                html += `<div class="note-list"><div class="note-list-title">📋 已保存的文件筆記</div>`;
                docNotes.forEach(note => {{
                    html += `
                        <div class="note-list-item ${{editingNoteId === note.id ? 'active' : ''}}" onclick="editDocNote('${{note.id}}')">
                            <div class="note-list-item-content">${{escapeHtml(note.content)}}</div>
                            <div class="note-list-item-time">${{formatTime(note.updated)}}</div>
                        </div>
                    `;
                }});
                html += `</div>`;
            }}

            return html;
        }}

        // 渲染段落筆記
        function renderParaNotes() {{
            let html = '';

            if (currentParaId) {{
                html += `
                    <div class="note-context">
                        <span class="note-context-label">📍 目前位置</span>
                        ${{escapeHtml(currentParaContext)}}...
                    </div>
                    <div class="note-editor">
                        <textarea id="note-textarea" placeholder="寫下你對這段落的筆記...">${{editingNoteId ? (paraNotes.find(n => n.id === editingNoteId)?.content || '') : ''}}</textarea>
                        <div class="note-editor-actions">
                            <button class="primary" onclick="saveParaNote()">💾 儲存</button>
                            ${{editingNoteId ? '<button class="danger" onclick="deleteParaNote()">🗑️ 刪除</button>' : ''}}
                        </div>
                    </div>
                `;
            }}

            if (paraNotes.length > 0) {{
                html += `<div class="note-list"><div class="note-list-title">📋 本頁段落筆記 (${{paraNotes.length}})</div>`;
                paraNotes.forEach(note => {{
                    const el = document.querySelector(`[data-para-id="${{note.paraId}}"]`);
                    const context = el ? el.textContent.slice(0, 40).replace(/📝/g, '').trim() : '(已刪除段落)';
                    html += `
                        <div class="note-list-item ${{editingNoteId === note.id ? 'active' : ''}}" onclick="editParaNote('${{note.id}}')">
                            <div class="note-list-item-header">
                                <div class="note-list-item-context">「${{escapeHtml(context)}}...」</div>
                                <div class="note-list-item-actions">
                                    <button onclick="event.stopPropagation(); scrollToParaNote('${{note.paraId}}')" title="跳轉">↗</button>
                                </div>
                            </div>
                            <div class="note-list-item-content">${{escapeHtml(note.content)}}</div>
                            <div class="note-list-item-time">${{formatTime(note.updated)}}</div>
                        </div>
                    `;
                }});
                html += `</div>`;
            }} else if (!currentParaId) {{
                html += `
                    <div class="note-empty">
                        <div class="note-empty-icon">📝</div>
                        <div>尚無段落筆記</div>
                        <div style="font-size: 12px; margin-top: 8px;">在段落旁點擊 📝 開始記錄</div>
                    </div>
                `;
            }}

            return html;
        }}

        // 網站筆記 CRUD
        function saveSiteNote() {{
            const content = document.getElementById('note-textarea').value.trim();
            if (!content) return;

            if (editingNoteId) {{
                const note = siteNotes.find(n => n.id === editingNoteId);
                if (note) {{
                    note.content = content;
                    note.updated = Date.now();
                }}
            }} else {{
                siteNotes.push({{
                    id: 'site-' + Date.now(),
                    content,
                    created: Date.now(),
                    updated: Date.now()
                }});
            }}

            localStorage.setItem('site-notes', JSON.stringify(siteNotes));
            editingNoteId = null;
            renderNoteContent();
            updateNoteCounts();
            updateExportButton();
        }}

        function editSiteNote(id) {{
            editingNoteId = id;
            renderNoteContent();
            document.getElementById('note-textarea').focus();
        }}

        function deleteSiteNote() {{
            if (!editingNoteId) return;
            siteNotes = siteNotes.filter(n => n.id !== editingNoteId);
            localStorage.setItem('site-notes', JSON.stringify(siteNotes));
            editingNoteId = null;
            renderNoteContent();
            updateNoteCounts();
            updateExportButton();
        }}

        // 文件筆記 CRUD
        function saveDocNote() {{
            const content = document.getElementById('note-textarea').value.trim();
            if (!content) return;

            if (editingNoteId) {{
                const note = docNotes.find(n => n.id === editingNoteId);
                if (note) {{
                    note.content = content;
                    note.updated = Date.now();
                }}
            }} else {{
                docNotes.push({{
                    id: 'doc-' + Date.now(),
                    content,
                    pageTitle: pageTitle,
                    created: Date.now(),
                    updated: Date.now()
                }});
            }}

            localStorage.setItem(`doc-notes:${{pageId}}`, JSON.stringify(docNotes));
            editingNoteId = null;
            renderNoteContent();
            updateNoteCounts();
            updateExportButton();
        }}

        function editDocNote(id) {{
            editingNoteId = id;
            renderNoteContent();
            document.getElementById('note-textarea').focus();
        }}

        function deleteDocNote() {{
            if (!editingNoteId) return;
            docNotes = docNotes.filter(n => n.id !== editingNoteId);
            localStorage.setItem(`doc-notes:${{pageId}}`, JSON.stringify(docNotes));
            editingNoteId = null;
            renderNoteContent();
            updateNoteCounts();
            updateExportButton();
        }}

        // 段落筆記 CRUD
        function saveParaNote() {{
            const content = document.getElementById('note-textarea').value.trim();
            if (!content || !currentParaId) return;

            if (editingNoteId) {{
                const note = paraNotes.find(n => n.id === editingNoteId);
                if (note) {{
                    note.content = content;
                    note.updated = Date.now();
                }}
            }} else {{
                paraNotes.push({{
                    id: 'para-' + Date.now(),
                    paraId: currentParaId,
                    content,
                    context: currentParaContext,
                    pageTitle: pageTitle,
                    created: Date.now(),
                    updated: Date.now()
                }});
            }}

            localStorage.setItem(`para-notes:${{pageId}}`, JSON.stringify(paraNotes));

            // 更新段落按鈕狀態
            const el = document.querySelector(`[data-para-id="${{currentParaId}}"]`);
            if (el) {{
                el.querySelector('.note-btn').classList.add('has-note');
            }}

            editingNoteId = null;
            renderNoteContent();
            updateNoteCounts();
            updateExportButton();
        }}

        function editParaNote(id) {{
            const note = paraNotes.find(n => n.id === id);
            if (note) {{
                currentParaId = note.paraId;
                const el = document.querySelector(`[data-para-id="${{note.paraId}}"]`);
                currentParaContext = el ? el.textContent.slice(0, 50).replace(/📝/g, '').trim() : '';
            }}
            editingNoteId = id;
            renderNoteContent();
            document.getElementById('note-textarea').focus();
        }}

        function deleteParaNote() {{
            if (!editingNoteId) return;
            const note = paraNotes.find(n => n.id === editingNoteId);
            paraNotes = paraNotes.filter(n => n.id !== editingNoteId);
            localStorage.setItem(`para-notes:${{pageId}}`, JSON.stringify(paraNotes));

            // 更新段落按鈕狀態
            if (note && !paraNotes.some(n => n.paraId === note.paraId)) {{
                const el = document.querySelector(`[data-para-id="${{note.paraId}}"]`);
                if (el) {{
                    el.querySelector('.note-btn').classList.remove('has-note');
                }}
            }}

            editingNoteId = null;
            currentParaId = null;
            renderNoteContent();
            updateNoteCounts();
            updateExportButton();
        }}

        function scrollToParaNote(paraId) {{
            const el = document.querySelector(`[data-para-id="${{paraId}}"]`);
            if (el) {{
                el.scrollIntoView({{ behavior: 'smooth', block: 'center' }});
                el.style.background = 'rgba(255, 193, 7, 0.3)';
                setTimeout(() => el.style.background = '', 2000);
            }}
        }}

        // 更新筆記計數
        function updateNoteCounts() {{
            document.getElementById('site-note-count').textContent = siteNotes.length;
            document.getElementById('doc-note-count').textContent = docNotes.length;
            document.getElementById('para-note-count').textContent = paraNotes.length;
        }}

        function updateExportButton() {{
            const totalNotes = siteNotes.length + docNotes.length + paraNotes.length;
            document.getElementById('export-notes-btn').classList.toggle('visible', totalNotes > 0);
        }}

        // 使用說明 Modal
        function openHelpModal() {{
            document.getElementById('help-modal').classList.add('active');
        }}

        function closeHelpModal() {{
            document.getElementById('help-modal').classList.remove('active');
            if (document.getElementById('hide-help-checkbox').checked) {{
                localStorage.setItem('hide-help', 'true');
            }}
        }}

        // 匯出筆記 Modal
        function openExportModal() {{
            // 更新計數
            document.getElementById('export-site-count').textContent = `(${{siteNotes.length}} 則)`;
            document.getElementById('export-doc-count').textContent = `(${{docNotes.length}} 則)`;
            document.getElementById('export-para-count').textContent = `(${{paraNotes.length}} 則)`;

            document.getElementById('export-modal').classList.add('active');
        }}

        function closeExportModal() {{
            document.getElementById('export-modal').classList.remove('active');
        }}

        function doExportNotes() {{
            const includeSite = document.getElementById('export-site').checked;
            const includeDoc = document.getElementById('export-doc').checked;
            const includePara = document.getElementById('export-para').checked;
            const format = document.querySelector('input[name="export-format"]:checked').value;

            const siteTitle = document.title || '學習筆記';
            const docTitle = document.querySelector('h1')?.textContent || '文件';

            let content = '';
            let totalCount = 0;

            if (format === 'md') {{
                content = `# ${{siteTitle}} - 學習筆記\\n\\n`;
                content += `> 匯出時間：${{new Date().toLocaleString('zh-TW')}}\\n\\n`;

                if (includeSite && siteNotes.length > 0) {{
                    content += `## 🌐 網站筆記\\n\\n`;
                    siteNotes.forEach((note, i) => {{
                        content += `${{note.content}}\\n\\n`;
                        if (i < siteNotes.length - 1) content += `---\\n\\n`;
                    }});
                    content += `\\n`;
                    totalCount += siteNotes.length;
                }}

                if (includeDoc && docNotes.length > 0) {{
                    content += `## 📄 文件筆記：${{docTitle}}\\n\\n`;
                    docNotes.forEach((note, i) => {{
                        content += `${{note.content}}\\n\\n`;
                        if (i < docNotes.length - 1) content += `---\\n\\n`;
                    }});
                    content += `\\n`;
                    totalCount += docNotes.length;
                }}

                if (includePara && paraNotes.length > 0) {{
                    content += `## 📝 段落筆記\\n\\n`;
                    paraNotes.forEach((note, i) => {{
                        const el = document.querySelector(`[data-para-id="${{note.paraId}}"]`);
                        const context = el ? el.textContent.slice(0, 80).replace(/📝/g, '').trim() : '';
                        content += `### 筆記 ${{i + 1}}\\n\\n`;
                        if (context) content += `**原文**：${{context}}...\\n\\n`;
                        content += `**筆記**：${{note.content}}\\n\\n---\\n\\n`;
                    }});
                    totalCount += paraNotes.length;
                }}

                content += `\\n---\\n共 ${{totalCount}} 則筆記`;
            }} else {{
                content = `${{siteTitle}} - 學習筆記\\n`;
                content += `匯出時間：${{new Date().toLocaleString('zh-TW')}}\\n\\n`;
                content += `=`.repeat(50) + `\\n\\n`;

                if (includeSite && siteNotes.length > 0) {{
                    content += `【網站筆記】\\n\\n`;
                    siteNotes.forEach(note => {{
                        content += `${{note.content}}\\n\\n`;
                    }});
                    totalCount += siteNotes.length;
                }}

                if (includeDoc && docNotes.length > 0) {{
                    content += `【文件筆記：${{docTitle}}】\\n\\n`;
                    docNotes.forEach(note => {{
                        content += `${{note.content}}\\n\\n`;
                    }});
                    totalCount += docNotes.length;
                }}

                if (includePara && paraNotes.length > 0) {{
                    content += `【段落筆記】\\n\\n`;
                    paraNotes.forEach((note, i) => {{
                        content += `${{i + 1}}. ${{note.content}}\\n\\n`;
                    }});
                    totalCount += paraNotes.length;
                }}

                content += `共 ${{totalCount}} 則筆記`;
            }}

            // 下載檔案
            const blob = new Blob([content], {{ type: format === 'md' ? 'text/markdown;charset=utf-8' : 'text/plain;charset=utf-8' }});
            const url = URL.createObjectURL(blob);
            const a = document.createElement('a');
            a.href = url;
            a.download = `${{siteTitle.replace(/[^\\w\\u4e00-\\u9fff]/g, '_')}}_筆記.${{format}}`;
            a.click();
            URL.revokeObjectURL(url);

            closeExportModal();
        }}

        // 輔助函數
        function escapeHtml(text) {{
            const div = document.createElement('div');
            div.textContent = text;
            return div.innerHTML;
        }}

        function formatTime(timestamp) {{
            const date = new Date(timestamp);
            return date.toLocaleString('zh-TW', {{ month: 'short', day: 'numeric', hour: '2-digit', minute: '2-digit' }});
        }}

        // ESC 關閉面板
        document.addEventListener('keydown', function(e) {{
            if (e.key === 'Escape') {{
                closeNotePanel();
                closeHelpModal();
                closeExportModal();
            }}
        }});

        // 初始化筆記功能
        initNotes();

        // ===== 閱讀時間估計 =====
        (function() {{
            const content = document.querySelector('.content');
            if (!content) return;

            // 計算字數（中文按字算，英文按詞算）
            const text = content.textContent || '';
            const chineseChars = (text.match(/[\u4e00-\u9fff]/g) || []).length;
            const englishWords = (text.match(/[a-zA-Z]+/g) || []).length;
            const totalChars = chineseChars + englishWords;

            // 假設每分鐘閱讀 300 字
            const minutes = Math.max(1, Math.ceil(totalChars / 300));

            // 插入閱讀資訊
            const h1 = content.querySelector('h1');
            if (h1) {{
                const meta = document.createElement('div');
                meta.className = 'reading-meta';
                meta.innerHTML = `
                    <span>⏱️ 預計閱讀 ${{minutes}} 分鐘</span>
                    <span>📖 約 ${{totalChars.toLocaleString()}} 字</span>
                `;
                h1.insertAdjacentElement('afterend', meta);
            }}
        }})();
    </script>
    <footer class="site-footer">
        v1.2.0 | Markdown to HTML Site Generator
    </footer>
</body>
</html>
'''


def extract_title_from_md(md_path: Path) -> str:
    content = md_path.read_text(encoding='utf-8')

    # 1. 先嘗試從 YAML frontmatter 提取 title
    yaml_match = re.search(r'^---\s*\n(.*?)\n---', content, re.DOTALL)
    if yaml_match:
        yaml_content = yaml_match.group(1)
        title_match = re.search(r'^title:\s*["\']?(.+?)["\']?\s*$', yaml_content, re.MULTILINE)
        if title_match:
            return title_match.group(1).strip()

    # 2. 移除 YAML frontmatter 後，找第一個 # 標題
    content_without_yaml = re.sub(r'^---\s*\n.*?\n---\s*\n', '', content, flags=re.DOTALL)
    match = re.search(r'^#\s+(.+)$', content_without_yaml, re.MULTILINE)
    if match:
        return match.group(1).strip()

    # 3. 都找不到就用檔名
    return md_path.stem


def extract_description_from_md(md_path: Path) -> str:
    content = md_path.read_text(encoding='utf-8')

    # 移除 YAML frontmatter
    content = re.sub(r'^---\s*\n.*?\n---\s*\n', '', content, flags=re.DOTALL)

    lines = content.split('\n')
    for line in lines:
        line = line.strip()
        # 跳過空行、標題、註解
        if line and not line.startswith('#') and not line.startswith('---') and not line.startswith('>'):
            desc = re.sub(r'\*\*|__|\*|_|`', '', line)
            if desc:  # 確保有內容
                return desc[:60] + '...' if len(desc) > 60 else desc
    return ''


def extract_text_content(md_path: Path) -> str:
    """提取純文字內容供搜尋用"""
    content = md_path.read_text(encoding='utf-8')
    # 移除 Markdown 語法
    content = re.sub(r'```[\s\S]*?```', '', content)  # 移除代碼區塊
    content = re.sub(r'`[^`]+`', '', content)  # 移除行內代碼
    content = re.sub(r'\[([^\]]+)\]\([^)]+\)', r'\1', content)  # 連結轉文字
    content = re.sub(r'[#*_~>`|]', '', content)  # 移除 Markdown 符號
    content = re.sub(r'\n+', ' ', content)  # 換行轉空格
    content = re.sub(r'\s+', ' ', content)  # 多空格轉單空格
    return content.strip()[:500]  # 限制長度


def generate_toc(html_content: str) -> tuple:
    toc_items = []
    counter = [0]

    def add_id(match):
        level = match.group(1)
        attrs = match.group(2) or ''
        text = match.group(3)

        if 'id="' not in attrs:
            clean_text = re.sub(r'<[^>]+>', '', text)
            slug = re.sub(r'[^\w\u4e00-\u9fff]+', '-', clean_text.lower()).strip('-')
            if not slug:
                counter[0] += 1
                slug = f'section-{counter[0]}'
            return f'<h{level} id="{slug}"{attrs}>{text}</h{level}>'
        return match.group(0)

    html_content = re.sub(r'<h([23])([^>]*)>(.*?)</h\1>', add_id, html_content, flags=re.DOTALL)

    for match in re.finditer(r'<h([23])[^>]*id="([^"]*)"[^>]*>(.*?)</h\1>', html_content, re.DOTALL):
        level, id_, text = match.groups()
        clean_text = re.sub(r'<[^>]+>', '', text)
        toc_items.append((level, id_, clean_text))

    toc_html = '<ul>\n'
    for level, id_, text in toc_items:
        css_class = f'toc-h{level}'
        toc_html += f'  <li class="{css_class}"><a href="#{id_}">{text}</a></li>\n'
    toc_html += '</ul>'

    return toc_html, html_content


def convert_folder_to_site(
    source_folder: Path,
    output_folder: Path = None,
    site_title: str = "文件目錄",
    site_description: str = "",
    max_depth: int = 1,
    features: list = None,
    watermark_text: str = ""
):
    # 預設啟用所有功能
    if features is None:
        features = DEFAULT_FEATURES
    source_folder = Path(source_folder)

    if output_folder is None:
        output_folder = source_folder / 'html_output'
    else:
        output_folder = Path(output_folder)

    output_folder.mkdir(parents=True, exist_ok=True)

    # 收集 Markdown 檔案
    md_files = []
    for md_file in source_folder.rglob('*.md'):
        rel_path = md_file.relative_to(source_folder)
        depth = len(rel_path.parents) - 1
        if depth <= max_depth:
            md_files.append(md_file)

    print(f"找到 {len(md_files)} 個 Markdown 檔案")
    print("=" * 50)

    # 分類與搜尋索引
    categories = defaultdict(list)
    all_docs = []
    search_index = []

    for md_file in md_files:
        rel_path = md_file.relative_to(source_folder)
        parent = rel_path.parent.as_posix()
        parts = parent.split('/')
        category = parts[0] if parts[0] != '.' else '總覽'

        title = extract_title_from_md(md_file)
        desc = extract_description_from_md(md_file)
        text_content = extract_text_content(md_file)
        html_rel_path = rel_path.with_suffix('.html')

        doc_info = {
            'md_path': md_file,
            'html_rel_path': html_rel_path,
            'title': title,
            'description': desc,
            'category': category
        }

        categories[category].append(doc_info)
        all_docs.append(doc_info)

        # 搜尋索引
        search_index.append({
            'title': title,
            'url': html_rel_path.as_posix(),
            'content': text_content
        })

    # 轉換每個 Markdown 檔案
    for i, doc in enumerate(all_docs):
        md_path = doc['md_path']
        html_path = output_folder / doc['html_rel_path']
        html_path.parent.mkdir(parents=True, exist_ok=True)

        print(f"[{i+1}/{len(all_docs)}] {doc['title']}")

        # 尋找同資料夾的影片檔案（供影片版使用）
        video_file = None
        video_files = list(md_path.parent.glob('*.mp4'))
        if video_files:
            video_file = video_files[0]

        result = subprocess.run([
            'pandoc', str(md_path),
            '--from', 'markdown',
            '--to', 'html5',
            '--no-highlight'
        ], capture_output=True, text=True, encoding='utf-8')

        if result.returncode != 0:
            print(f"   ✗ 錯誤")
            continue

        content = result.stdout
        toc, content = generate_toc(content)

        depth = len(doc['html_rel_path'].parents) - 1
        index_path = '../' * depth + 'index.html' if depth > 0 else 'index.html'

        prev_link = ''
        next_link = ''
        if i > 0:
            prev_doc = all_docs[i-1]
            prev_href = '../' * depth + prev_doc['html_rel_path'].as_posix()
            prev_link = f'<a href="{prev_href}">← {prev_doc["title"][:25]}</a>'
        if i < len(all_docs) - 1:
            next_doc = all_docs[i+1]
            next_href = '../' * depth + next_doc['html_rel_path'].as_posix()
            next_link = f'<a href="{next_href}">{next_doc["title"][:25]} →</a>'

        # 輕量版（無影片）- 根據功能處理模板
        processed_doc_template = process_template(DOC_TEMPLATE, features)
        html = processed_doc_template.format(
            title=escape(doc['title']),
            category=escape(doc['category']),
            index_path=index_path,
            toc=toc,
            content=content,
            prev_link=prev_link,
            next_link=next_link,
            watermark_text=escape(watermark_text)
        )
        html_path.write_text(html, encoding='utf-8')

        # 記錄影片資訊供後續影片版使用
        doc['video_file'] = video_file
        doc['toc'] = toc
        doc['content'] = content
        doc['index_path'] = index_path
        doc['prev_link'] = prev_link
        doc['next_link'] = next_link

        print(f"   ✓ 完成")

    # 收集範例作品（程式碼資料夾中的 HTML 檔案）
    print()
    print("收集範例作品...")
    demos = []
    maps_folder = output_folder / 'maps'

    for html_file in source_folder.rglob('*.html'):
        # 排除已生成的 html_output
        if 'html_output' in str(html_file):
            continue
        # 只收集「程式碼」資料夾中的 HTML
        if '程式碼' in str(html_file.parent):
            maps_folder.mkdir(parents=True, exist_ok=True)
            dest_path = maps_folder / html_file.name
            shutil.copy2(html_file, dest_path)

            # 從檔名提取標題
            title = html_file.stem.replace('_', ' ')
            demos.append({
                'title': title,
                'url': f'maps/{html_file.name}',
                'type': '互動地圖'
            })
            print(f"   ✓ {title}")

    if not demos:
        print("   (無範例作品)")

    # 生成搜尋索引
    print()
    print("生成搜尋索引...")
    search_index_path = output_folder / 'search-index.json'
    search_index_path.write_text(json.dumps(search_index, ensure_ascii=False, indent=2), encoding='utf-8')

    # 生成首頁
    print("生成首頁...")

    categories_html = ''
    for category, docs in sorted(categories.items()):
        cards_html = ''
        for doc in docs:
            href = doc['html_rel_path'].as_posix()
            cards_html += f'''
            <a href="{href}" class="doc-card">
                <h3>{escape(doc['title'])}</h3>
                <p class="desc">{escape(doc['description'])}</p>
            </a>
            '''

        categories_html += f'''
        <div class="category">
            <h2>{escape(category)}</h2>
            <div class="doc-grid">
                {cards_html}
            </div>
        </div>
        '''

    # 生成範例作品區塊
    if demos:
        demo_cards = ''
        for demo in demos:
            demo_cards += f'''
            <a href="{demo['url']}" class="demo-card" target="_blank">
                <h3>🗺️ {escape(demo['title'])}</h3>
                <span class="demo-type">{escape(demo['type'])}</span>
            </a>
            '''
        demos_html = f'''
        <div class="demos">
            <h2>🎯 範例作品</h2>
            <div class="demo-grid">
                {demo_cards}
            </div>
        </div>
        '''
    else:
        demos_html = ''

    # 搜尋索引 JSON 嵌入 HTML（避免 file:// CORS 問題）
    search_index_json = json.dumps(search_index, ensure_ascii=False) if 'search' in features else '[]'

    # 根據功能處理模板
    processed_index_template = process_template(INDEX_TEMPLATE, features)

    index_html = processed_index_template.format(
        site_title=escape(site_title),
        site_description=escape(site_description),
        total_docs=len(all_docs),
        total_categories=len(categories),
        generated_date=datetime.now().strftime('%Y-%m-%d'),
        categories_html=categories_html,
        demos_html=demos_html,
        search_index_json=search_index_json
    )

    index_path = output_folder / 'index.html'
    index_path.write_text(index_html, encoding='utf-8')

    # ===== 生成影片版 =====
    video_output_folder = output_folder.parent / (output_folder.name + '_video')
    video_output_folder.mkdir(parents=True, exist_ok=True)

    print()
    print("生成影片版...")

    video_count = 0
    for doc in all_docs:
        video_html_path = video_output_folder / doc['html_rel_path']
        video_html_path.parent.mkdir(parents=True, exist_ok=True)

        # 生成影片嵌入區塊（插入到 h1 標題後面）
        content_with_video = doc['content']
        if doc.get('video_file'):
            video_file = doc['video_file']
            video_dest = video_html_path.parent / video_file.name
            shutil.copy2(video_file, video_dest)
            video_block = f'''
<div class="video-section">
    <h3>📺 教學影片</h3>
    <video controls preload="metadata">
        <source src="{video_file.name}" type="video/mp4">
        您的瀏覽器不支援影片播放
    </video>
</div>
'''
            # 插入到第一個 </h1> 後面
            content_with_video = doc['content'].replace('</h1>', '</h1>\n' + video_block, 1)
            video_count += 1
            print(f"   📺 {doc['title']}")

        # 影片版也使用模組化模板
        processed_doc_template = process_template(DOC_TEMPLATE, features)
        html = processed_doc_template.format(
            title=escape(doc['title']),
            category=escape(doc['category']),
            index_path=doc['index_path'],
            toc=doc['toc'],
            content=content_with_video,
            prev_link=doc['prev_link'],
            next_link=doc['next_link'],
            watermark_text=escape(watermark_text)
        )
        video_html_path.write_text(html, encoding='utf-8')

    # 複製 maps 資料夾到影片版
    if (output_folder / 'maps').exists():
        shutil.copytree(output_folder / 'maps', video_output_folder / 'maps', dirs_exist_ok=True)

    # 生成影片版首頁（標題加上「影片版」）- 使用處理過的模板
    video_index_html = processed_index_template.format(
        site_title=escape(site_title + '（影片版）'),
        site_description=escape(site_description),
        total_docs=len(all_docs),
        total_categories=len(categories),
        generated_date=datetime.now().strftime('%Y-%m-%d'),
        categories_html=categories_html,
        demos_html=demos_html,
        search_index_json=search_index_json
    )
    (video_output_folder / 'index.html').write_text(video_index_html, encoding='utf-8')

    print(f"   ✓ 影片版完成（{video_count} 部影片）")

    print()
    print("=" * 50)
    print(f"✅ 完成！共 {len(all_docs)} 份文件")
    print(f"   📁 輕量版: {output_folder}")
    print(f"   📺 影片版: {video_output_folder}")

    return index_path


if __name__ == '__main__':
    # 建立功能清單說明
    feature_list = '\n'.join([f"  {f}: {cfg['name']} - {cfg['desc']}"
                              for f, cfg in FEATURE_MODULES.items()])

    parser = argparse.ArgumentParser(
        description='Markdown 轉 HTML 網站 v3（支援模組化功能）',
        formatter_class=argparse.RawDescriptionHelpFormatter,
        epilog=f'''
可用功能模組：
{feature_list}

範例：
  # 啟用所有功能（預設）
  python md_to_html_site.py ./docs

  # 只啟用搜尋和深色模式
  python md_to_html_site.py ./docs --features search,dark_mode

  # 停用筆記相關功能
  python md_to_html_site.py ./docs --no-features notes,note_center,export

  # 最小化版本（無任何額外功能）
  python md_to_html_site.py ./docs --features none
'''
    )
    parser.add_argument('input', nargs='?', help='來源資料夾')
    parser.add_argument('-o', '--output', help='輸出資料夾')
    parser.add_argument('--title', default='文件目錄', help='標題')
    parser.add_argument('--description', default='', help='描述')
    parser.add_argument('--depth', type=int, default=1, help='掃描深度')
    parser.add_argument('--features', metavar='LIST',
                        help='啟用的功能（逗號分隔），可用 "all" 或 "none"')
    parser.add_argument('--no-features', metavar='LIST', dest='no_features',
                        help='停用的功能（逗號分隔）')
    parser.add_argument('--list-features', action='store_true',
                        help='列出所有可用功能模組')
    parser.add_argument('--watermark', metavar='TEXT',
                        help='浮水印文字（會自動啟用 watermark 功能）')

    args = parser.parse_args()

    # 如果沒有提供 input 且沒有 --list-features，顯示錯誤
    if not args.input and not args.list_features:
        parser.error("請提供來源資料夾，或使用 --list-features 查看可用功能")

    # 列出功能模組
    if args.list_features:
        print("\n📦 可用功能模組：")
        print("=" * 50)
        for f, cfg in FEATURE_MODULES.items():
            deps = f" (依賴: {', '.join(cfg['depends'])})" if cfg['depends'] else ""
            default = " ✓" if cfg['default'] else ""
            print(f"  {f:15} {cfg['name']}{default}")
            print(f"                  {cfg['desc']}{deps}")
        print("\n✓ = 預設啟用")
        sys.exit(0)

    # 解析啟用的功能
    enabled_features = parse_features(args)

    # 如果指定了浮水印，自動啟用 watermark 功能
    watermark_text = ''
    if args.watermark:
        enabled_features = list(set(enabled_features) | {'watermark'})
        # 浮水印文字加上日期
        from datetime import datetime
        watermark_text = f"{args.watermark} | {datetime.now().strftime('%Y-%m-%d')}"

    print(f"\n🔧 啟用功能: {', '.join(sorted(enabled_features))}")
    if watermark_text:
        print(f"🔖 浮水印: {watermark_text}")

    index_path = convert_folder_to_site(
        Path(args.input),
        Path(args.output) if args.output else None,
        args.title,
        args.description,
        args.depth,
        enabled_features,
        watermark_text
    )

    import webbrowser
    webbrowser.open(str(index_path))
