{"id":"19eb0d2c-78e2-48db-8caf-350e3400c1e8","entityType":"agent","slug":"clawhub-edsml-yl10823-html-slides","name":"html-based slides","canonicalUrl":"https://www.xpersona.co/agent/clawhub-edsml-yl10823-html-slides","canonicalPath":"/agent/clawhub-edsml-yl10823-html-slides","generatedAt":"2026-10-12T21:27:47.265Z","source":"CLAWHUB","claimStatus":"UNCLAIMED","verificationTier":"NONE","summary":{"evidence":{"source":"editorial-content","verified":true,"confidence":"high","updatedAt":"2026-10-11T23:43:37.321Z","emptyReason":null},"description":"Create interactive, self-contained HTML slide decks with sidebar navigation, comment panel, zoom controls, inline editing, and present mode. Default brand is... Skill: html-based slides Owner: edsml-yl10823 Summary: Create interactive, self-contained HTML slide decks with sidebar navigation, comment panel, zoom controls, inline editing, and present mode. Default brand is... Tags: latest:1.0.0 Version history: v1.0.0 | 2026-04-15T07:54:46.314Z | user - Initial release of corporate-slides version 1.0.0. - Create interactive, self-contained HTML slide decks with built-in sideba","descriptionLabel":"Technical summary","evidenceSummary":"Capability contract not published. No trust telemetry is available yet. 974 downloads reported by the source. Last updated 10/11/2026.","installCommand":"clawhub skill install s1703chsgssn8asdzkcwz1rh7d845c0e:html-slides","sourceUrl":"https://clawhub.ai/edsml-yl10823/html-slides","homepage":"https://clawhub.ai/edsml-yl10823/skills/html-slides","primaryLinks":[{"label":"View on ClawHub","url":"https://clawhub.ai/edsml-yl10823/html-slides","kind":"source"},{"label":"Homepage","url":"https://clawhub.ai/edsml-yl10823/skills/html-slides","kind":"homepage"}],"safetyScore":84,"overallRank":62,"popularityScore":60,"trustScore":null,"claimedByName":null,"isOwner":false,"seoDescription":"Create interactive, self-contained HTML slide decks with sidebar navigation, comment panel, zoom controls, inline editing, and present mode. Default brand is..."},"coverage":{"evidence":{"source":"public-profile","verified":false,"confidence":"medium","updatedAt":"2026-10-11T23:43:37.321Z","emptyReason":null},"protocols":[{"protocol":"OPENCLEW","label":"OpenClaw","status":"self-declared","notes":"Declared in the public agent profile."}],"capabilities":[],"verifiedCount":0,"selfDeclaredCount":1,"capabilityMatrix":{"rows":[{"key":"OPENCLEW","type":"protocol","support":"unknown","confidenceSource":"profile","notes":"Listed on profile"}],"flattenedTokens":"protocol:OPENCLEW|unknown|profile"}},"adoption":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"medium","updatedAt":"2026-10-11T23:43:37.321Z","emptyReason":null},"stars":null,"forks":null,"downloads":974,"likes":null,"task":null,"library":null,"packageName":null,"latestVersion":"1.0.0","tractionLabel":"974 downloads"},"release":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"medium","updatedAt":"2026-10-11T23:43:37.308Z","emptyReason":null},"lastUpdatedAt":"2026-10-11T23:43:37.321Z","lastCrawledAt":"2026-10-11T23:43:37.308Z","lastIndexedAt":null,"nextCrawlAt":"2026-10-12T23:43:37.308Z","lastVerifiedAt":null,"highlights":[{"version":"1.0.0","createdAt":"2026-04-15T07:54:46.314Z","changelog":"- Initial release of corporate-slides version 1.0.0. - Create interactive, self-contained HTML slide decks with built-in sidebar navigation, comment panel, zoom controls, inline editing, and present mode. - Default brand is Shopee/Sea (with logos and presets), with support for Neutral or fully custom brand tokens, colors, and fonts. - Bilingual (EN/CN) slides are generated by default, with automatic language toggle; supports monolingual slides if requested. - Preserves strict layout: each slide fits exactly in the viewport (100vh), with clear content limits and no scrolling. - Supports various content-driven slide types and reusable components optimized for product, roadmap, or business reports.","fileCount":8,"zipByteSize":23819}]},"execution":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"low","updatedAt":null,"emptyReason":"No published capability contract is available yet."},"installCommand":"clawhub skill install s1703chsgssn8asdzkcwz1rh7d845c0e:html-slides","setupComplexity":"low","setupSteps":["Setup complexity is LOW. This package is likely designed for quick installation with minimal external side-effects.","Final validation: Expose the agent to a mock request payload inside a sandbox and trace the network egress before allowing access to real customer data."],"contract":{"contractStatus":"missing","authModes":[],"requires":[],"forbidden":[],"supportsMcp":false,"supportsA2a":false,"supportsStreaming":false,"inputSchemaRef":null,"outputSchemaRef":null,"dataRegion":null,"contractUpdatedAt":null,"sourceUpdatedAt":null,"freshnessSeconds":null},"invocationGuide":{"preferredApi":{"snapshotUrl":"https://www.xpersona.co/api/v1/agents/clawhub-edsml-yl10823-html-slides/snapshot","contractUrl":"https://www.xpersona.co/api/v1/agents/clawhub-edsml-yl10823-html-slides/contract","trustUrl":"https://www.xpersona.co/api/v1/agents/clawhub-edsml-yl10823-html-slides/trust"},"curlExamples":["curl -s \"https://www.xpersona.co/api/v1/agents/clawhub-edsml-yl10823-html-slides/snapshot\"","curl -s \"https://www.xpersona.co/api/v1/agents/clawhub-edsml-yl10823-html-slides/contract\"","curl -s \"https://www.xpersona.co/api/v1/agents/clawhub-edsml-yl10823-html-slides/trust\""],"jsonRequestTemplate":{"query":"summarize this repo","constraints":{"maxLatencyMs":2000,"protocolPreference":["OPENCLEW"]}},"jsonResponseTemplate":{"ok":true,"result":{"summary":"...","confidence":0.9},"meta":{"source":"CLAWHUB","generatedAt":"2026-10-12T21:27:47.265Z"}},"retryPolicy":{"maxAttempts":3,"backoffMs":[500,1500,3500],"retryableConditions":["HTTP_429","HTTP_503","NETWORK_TIMEOUT"]}},"endpoints":{"dossierUrl":"https://www.xpersona.co/api/v1/agents/clawhub-edsml-yl10823-html-slides/dossier","snapshotUrl":"https://www.xpersona.co/api/v1/agents/clawhub-edsml-yl10823-html-slides/snapshot","contractUrl":"https://www.xpersona.co/api/v1/agents/clawhub-edsml-yl10823-html-slides/contract","trustUrl":"https://www.xpersona.co/api/v1/agents/clawhub-edsml-yl10823-html-slides/trust"}},"reliability":{"evidence":{"source":"runtime-metrics","verified":false,"confidence":"low","updatedAt":null,"emptyReason":"No trust, reliability, or runtime telemetry is available."},"trust":{"status":"unavailable","handshakeStatus":"UNKNOWN","verificationFreshnessHours":null,"reputationScore":null,"p95LatencyMs":null,"successRate30d":null,"fallbackRate":null,"attempts30d":null,"trustUpdatedAt":null,"trustConfidence":"unknown","sourceUpdatedAt":null,"freshnessSeconds":null},"decisionGuardrails":{"doNotUseIf":["Contract metadata is missing or unavailable for deterministic execution."],"safeUseWhen":[],"riskFlags":["missing_or_unavailable_contract","trust_data_unavailable","schema_references_missing"],"operationalConfidence":"low"},"executionMetrics":{"observedLatencyMsP50":null,"observedLatencyMsP95":null,"estimatedCostUsd":null,"uptime30d":null,"rateLimitRpm":null,"rateLimitBurst":null,"lastVerifiedAt":null,"verificationSource":null},"runtimeMetrics":{"successRate":null,"avgLatencyMs":null,"avgCostUsd":null,"hallucinationRate":null,"retryRate":null,"disputeRate":null,"p50Latency":null,"p95Latency":null,"lastUpdated":null}},"benchmarks":{"evidence":{"source":"no-benchmark-data","verified":false,"confidence":"low","updatedAt":null,"emptyReason":"No benchmark suites or observed failure patterns are available."},"suites":[],"failurePatterns":[]},"artifacts":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"high","updatedAt":"2026-10-11T23:43:37.321Z","emptyReason":null},"readme":"Skill: html-based slides\n\nOwner: edsml-yl10823\n\nSummary: Create interactive, self-contained HTML slide decks with sidebar navigation, comment panel, zoom controls, inline editing, and present mode. Default brand is...\n\nTags: latest:1.0.0\n\nVersion history:\n\nv1.0.0 | 2026-04-15T07:54:46.314Z | user\n\n- Initial release of corporate-slides version 1.0.0.\n- Create interactive, self-contained HTML slide decks with built-in sidebar navigation, comment panel, zoom controls, inline editing, and present mode.\n- Default brand is Shopee/Sea (with logos and presets), with support for Neutral or fully custom brand tokens, colors, and fonts.\n- Bilingual (EN/CN) slides are generated by default, with automatic language toggle; supports monolingual slides if requested.\n- Preserves strict layout: each slide fits exactly in the viewport (100vh), with clear content limits and no scrolling.\n- Supports various content-driven slide types and reusable components optimized for product, roadmap, or business reports.\n\nArchive index:\n\nArchive v1.0.0: 8 files, 23819 bytes\n\nFiles: references/components.md (12300b), references/design-tokens.md (6959b), references/js-controller.md (9663b), references/slide-types.md (9713b), references/viewport-chrome.md (14637b), skill-card.md (2508b), SKILL.md (11941b), _meta.json (130b)\n\nFile v1.0.0:SKILL.md\n\n---\nname: corporate-slides\ndescription: Create interactive, self-contained HTML slide decks with sidebar navigation, comment panel, zoom controls, inline editing, and present mode. Default brand is Shopee/Sea but supports custom brand presets. Use when the user says \"做slides\"、\"create slides\"、\"创建幻灯片\"、\"做PPT\"、\"做汇报\"、\"bi-weekly\"、\"biweekly\"、\"双周汇报\"、\"quarterly review\"、\"product review\"、\"roadmap presentation\"、\"strategy deck\"、\"post-mortem slides\", or any request to create a presentation deck.\n---\n\n# Corporate Slides\n\nCreate zero-dependency, interactive HTML presentations that run in any browser. Every output is a single self-contained HTML file with built-in navigation, commenting, editing, and presentation capabilities.\n\n## Core Principles\n\n1. **Zero Dependencies** — Single HTML file with inline CSS/JS. No npm, no build tools.\n2. **Interactive Chrome** — Left sidebar navigation (bilingual-aware), right comment panel, zoom controls, inline text editing, present mode, EN/CN language switch — all built in by default.\n3. **Viewport Fitting (NON-NEGOTIABLE)** — Every slide MUST fit exactly within 100vh. No scrolling within slides.\n4. **Brand-Configurable** — Default brand is Shopee/Sea. User can select a different brand preset or define custom colors/fonts. The design token system makes this a single-point swap.\n5. **Content-Driven** — Slides are built around data, comparisons, timelines, and action items — not filler graphics.\n6. **Bilingual by Default** — Unless user specifies a single language, generate **both EN and CN** content for every text element with an EN/CN toggle in the toolbar. If user explicitly requests a single language, skip the toggle and generate monolingual content.\n\n---\n\n## Phase 0: Detect Mode\n\n- **Mode A: New Presentation** — Create from scratch. Go to Phase 1.\n- **Mode B: Enhancement** — Modify an existing HTML slide deck. Read it first, understand its brand/style, then modify. When adding content, check density limits; split slides if overflow would occur.\n\n---\n\n## Phase 1: Content Discovery\n\n**Ask ALL questions in a single call:**\n\n**Question 1 — Purpose** (header: \"Purpose\"):\nWhat is this presentation for? Options:\n- Bi-weekly / periodic update\n- Product review / feature walkthrough\n- Roadmap / strategy deck\n- Post-mortem / retrospective\n- Quarterly business review\n- Training / onboarding\n- Other (describe)\n\n**Question 2 — Brand** (header: \"Brand\"):\nWhich brand preset? Options:\n- Shopee / Sea (default — orange + navy)\n- Custom (I'll provide colors/fonts)\n- Neutral / Minimal (dark charcoal + blue accent, no logos)\n\n**Question 3 — Content** (header: \"Content\"):\nDo you have content ready? Options:\n- All content ready (paste text, metrics, etc.)\n- Rough notes / bullet points\n- Topic only — help me structure it\n\n**Question 4 — Length** (header: \"Length\"):\nApproximately how many slides? Options: Short 5-8 / Medium 8-14 / Long 14+\n\n**Question 5 — Interactive Features** (header: \"Features\"):\nWhich interactive features to include? Options:\n- Full (sidebar + comments + zoom + edit + present + language toggle) — recommended\n- Light (sidebar + present only)\n- Minimal (no chrome, static slides)\n\n**Language handling (NO question needed — apply automatically):**\n- If user has NOT specified a single language → generate bilingual (EN + CN) with language toggle. This is the default.\n- If user explicitly says \"English only\", \"只要中文\", or similar → generate monolingual, no toggle.\n- The language toggle is part of the toolbar chrome, not a separate question.\n\nIf user selected **Custom brand**, follow up with:\n- Primary accent color (hex)\n- Secondary / heading color (hex)\n- Display font preference (or \"your choice\")\n- Logo image file (or \"no logo\")\n\nIf user has content, ask them to share it. Then proceed to Phase 2.\n\n---\n\n## Phase 2: Plan Slide Structure\n\nBased on user content, plan the slide deck using available slide types and components.\n\n### Available Slide Types\n\n| Type | When to Use |\n|------|-------------|\n| **Cover** | First slide — title, date, team, optional logos |\n| **Section Divider** | Transition between major topics — colored background, section number |\n| **Content** | Main information slides — header bar + body components |\n| **Closing** | Last slide — thank you, contact, next steps |\n\n### Available Components (for Content Slides)\n\nRead [components.md](references/components.md) for full HTML templates.\n\n| Component | Best For |\n|-----------|----------|\n| **Metrics Grid** | KPI cards (3-column) with values and change indicators |\n| **Bi-weekly Table** | Period-over-period comparison with insight cards |\n| **Feature Table** | Feature comparisons, scope definitions, matrices |\n| **Two-Column Grid** | Findings vs Actions, Pros vs Cons, Before vs After |\n| **Action List** | Action items, scope items, decisions with owners |\n| **Timeline** | Roadmap milestones, project phases |\n| **Status Badge** | Inline status indicators (on-track, at-risk, done) |\n| **Screenshot Slot** | Replaceable image placeholder for operational screenshots (dashed border when empty, auto-shows image when `src` set) |\n\n### Content Density Limits Per Slide\n\n| Slide Type | Maximum Content |\n|------------|-----------------|\n| Cover | Title + subtitle + meta |\n| Section Divider | Title + subtitle + section number |\n| Content (text) | 1 heading + 1 paragraph + 1 component |\n| Content (table) | 1 heading + 1 table (up to 12 rows) |\n| Content (mixed) | 1 heading + 2 smaller components |\n| Closing | Title + subtitle + meta |\n\n**Content exceeds limits? Split into multiple slides. Never cram, never scroll.**\n\nPresent the slide plan to the user for confirmation before generating.\n\n---\n\n## Phase 3: Generate Presentation\n\n### Brand Resolution\n\n1. If **Shopee/Sea** (default): use the Shopee/Sea preset from [design-tokens.md](references/design-tokens.md). MUST include BOTH base64-embedded Shopee and SeaMoney logos on cover, section dividers, content headers, and closing slides.\n2. If **Custom**: swap `--accent-primary`, `--accent-secondary`, `--color-navy`, fonts, and logo. Keep all other structural tokens unchanged.\n3. If **Neutral**: use the Neutral preset from design-tokens.md. No logos — use a text-only header.\n\n### HTML Architecture\n\n```\n<!DOCTYPE html>\n<html lang=\"zh\">\n<head>\n    <!-- Google Fonts (based on brand preset) -->\n    <style>\n        /* 1. CSS Custom Properties (from design-tokens.md — brand-resolved) */\n        /* 2. Reset & Base Typography */\n        /* 3. Viewport Fitting (MANDATORY — from viewport-chrome.md) */\n        /* 4. Language Toggle (bilingual only — from viewport-chrome.md) */\n        /* 5. Sidebar Navigation */\n        /* 6. Progress Bar */\n        /* 7. Comment Panel */\n        /* 8. Zoom Controls */\n        /* 9. Slide Type Styles (cover, section, content, closing) */\n        /* 10. Component Styles */\n        /* 11. Edit Mode */\n        /* 12. Present Mode */\n        /* 13. Responsive Breakpoints */\n        /* 14. Embedded Logos (if applicable) */\n    </style>\n</head>\n<body class=\"lang-cn\">\n    <!-- Chrome: sidebar + toggle (left), progress bar (top, slide area only), horizontal toolbar (top-right: lang→present→zoom→edit→comment), comment panel (right) -->\n    <!-- SLIDES (each is a <section class=\"slide\">) with lang-en/lang-cn spans -->\n    <!-- JS: SlidePresentation class -->\n</body>\n</html>\n```\n\n**Before generating, read ALL reference files:**\n\n- [design-tokens.md](references/design-tokens.md) — CSS custom properties, brand presets, typography\n- [slide-types.md](references/slide-types.md) — HTML templates for each slide type\n- [components.md](references/components.md) — Reusable component HTML/CSS\n- [viewport-chrome.md](references/viewport-chrome.md) — Interactive chrome + viewport rules\n- [js-controller.md](references/js-controller.md) — SlidePresentation JS class\n\n### Bilingual Content Rules (when generating EN + CN)\n\nEvery user-visible text element must contain **both language spans**:\n\n```html\n<h2>\n    <span class=\"lang-en\">Architecture Overview</span>\n    <span class=\"lang-cn\">架构概览</span>\n</h2>\n<p>\n    <span class=\"lang-en\">Smart acts as a Package Registry.</span>\n    <span class=\"lang-cn\">Smart 作为 Package Registry。</span>\n</p>\n```\n\n**Rules:**\n1. Wrap each translatable text node in `<span class=\"lang-en\">` and `<span class=\"lang-cn\">`\n2. Technical terms, product names, and code snippets stay unchanged across both languages (e.g. \"SKILL.md\", \"SuperAgent\", \"CLI\", variable names)\n3. `data-title` (CN) and `data-title-en` (EN) attributes on slides; `data-group` (CN) and `data-group-en` (EN) on group headers. Sidebar switches language along with body class.\n4. The `<html lang>` attribute should be set to `\"zh\"` (CN is the default display language)\n5. Body starts with class `lang-cn` — CN is shown first, user toggles to EN\n6. For list items, wrap the text content inside each `<li>`, not the `<li>` itself\n7. For table cells, wrap content inside each `<td>`/`<th>`, not the cell itself\n\n**CSS (included in viewport-chrome.md):**\n```css\nbody.lang-en .lang-cn { display: none; }\nbody.lang-cn .lang-en { display: none; }\n```\n\n**When monolingual:** Skip all `lang-en`/`lang-cn` spans, write plain text, omit the language toggle button from the toolbar, and omit the language CSS/JS.\n\n### Key Requirements\n\n1. **Single self-contained HTML file** — all CSS/JS inline\n2. **Every slide** must have `data-title` (CN), `data-title-en` (EN), `data-group` (CN), and `data-group-en` (EN) attributes for bilingual sidebar. Monolingual slides only need `data-title` and `data-group`.\n3. **Every slide** must include a footer with page numbers (populated by JS)\n4. **All sizes** must use `clamp(min, preferred, max)` — never fixed px/rem\n5. **Logos**: Shopee/Sea — BOTH `.shopee` and `.seamoney` logos MUST appear, embedded via CSS `content: url(data:...)`. Custom brand — embed user-provided logo(s). Neutral — no logos, text-only headers.\n6. Include `prefers-reduced-motion` support\n7. Clear `/* === SECTION NAME === */` comment blocks throughout CSS\n8. **Bilingual presentations** must include the EN/CN language switch in the toolbar and all lang-en/lang-cn CSS (see viewport-chrome.md). Sidebar nav must also be bilingual-aware.\n\n---\n\n## Phase 4: Delivery\n\n1. **Save** to `work/slides/` with a descriptive filename\n2. **Open** using `open [filename].html` to launch in browser\n3. **Summarize** — Tell the user:\n   - File location, slide count, brand preset used\n   - Navigation: Arrow keys, Space, scroll/swipe, sidebar click\n   - Top-right toolbar (horizontal, left to right): Language switch → Present → Zoom → Edit → Comment\n   - Language: Click \"EN\" or \"CN\" segment in the switch to change language; sidebar nav follows. Press `L` to toggle.\n   - Present: Press `F5` or click ▶ — fullscreen, hides all chrome\n   - Zoom: +/- buttons (70%–150%)\n   - Edit: Press `E` — click any text to edit, undo/redo in toolbar\n   - Comment panel: Press `C` — per-slide notes saved to localStorage, Copy All exports as Markdown\n   - Sidebar: Click ☰ at sidebar right edge to collapse/expand\n\n---\n\n## Supporting Files\n\n| File | Purpose | When to Read |\n|------|---------|-------------|\n| [design-tokens.md](references/design-tokens.md) | Brand presets, CSS variables, colors, typography, spacing | Phase 3 (always) |\n| [slide-types.md](references/slide-types.md) | HTML templates for cover, section, content, closing | Phase 3 (always) |\n| [components.md](references/components.md) | Reusable component HTML: metrics, tables, timelines, etc. | Phase 3 (always) |\n| [viewport-chrome.md](references/viewport-chrome.md) | Viewport fitting CSS + interactive chrome HTML/CSS | Phase 3 (always) |\n| [js-controller.md](references/js-controller.md) | SlidePresentation JS class with all interactive features | Phase 3 (always) |\n\nFile v1.0.0:_meta.json\n\n{\n  \"ownerId\": \"kn7embg2epew9fdvnh29tq4sws844k82\",\n  \"slug\": \"html-slides\",\n  \"version\": \"1.0.0\",\n  \"publishedAt\": 1776239686314\n}\n\nFile v1.0.0:references/components.md\n\n# Reusable Components\n\nThese components are placed inside `.slide-content` of Content Slides. Always add `class=\"reveal\"` to the component wrapper for entrance animation.\n\nAll components use CSS custom properties for colors, so they automatically adapt to any brand preset.\n\n---\n\n## 1. Metrics Grid\n\n3-column KPI cards with label, large value, and change indicator. Great for dashboards, status updates, quarterly metrics.\n\n```html\n<div class=\"metrics-grid reveal\">\n    <div class=\"metric-card\">\n        <span class=\"metric-label\">Label</span>\n        <span class=\"metric-value\">7,800+</span>\n        <span class=\"metric-change positive\">+12.5% vs last period</span>\n    </div>\n    <div class=\"metric-card\">\n        <span class=\"metric-label\">Label</span>\n        <span class=\"metric-value\">3,200+</span>\n        <span class=\"metric-change negative\">-8.3% vs target</span>\n    </div>\n    <div class=\"metric-card\">\n        <span class=\"metric-label\">Label</span>\n        <span class=\"metric-value\">34%</span>\n        <span class=\"metric-change neutral\">Stable</span>\n    </div>\n</div>\n```\n\n### CSS\n\n```css\n.metrics-grid {\n    display: grid; grid-template-columns: repeat(3, 1fr);\n    gap: clamp(8px, 1.2vw, 16px); width: 100%;\n}\n.metric-card {\n    background: var(--bg-secondary);\n    border-radius: clamp(6px, 0.8vw, 12px);\n    padding: clamp(10px, 1.5vh, 20px) clamp(10px, 1.2vw, 18px);\n    display: flex; flex-direction: column; gap: clamp(3px, 0.5vh, 8px);\n    border-left: 3px solid var(--accent);\n    transition: transform 0.2s ease, box-shadow 0.2s ease;\n}\n.metric-card:hover { transform: translateY(-2px); box-shadow: 0 4px 16px rgba(0,0,0,0.06); }\n.metric-label { font-family: var(--font-body); font-size: var(--small-size); color: var(--text-muted); text-transform: uppercase; letter-spacing: 0.05em; font-weight: 600; }\n.metric-value { font-family: var(--font-display); font-size: var(--cta-size); font-weight: 900; color: var(--color-heading); line-height: 1; }\n.metric-change { font-family: var(--font-body); font-size: var(--small-size); font-weight: 600; }\n.metric-change.positive { color: #16803c; }\n.metric-change.negative { color: #dc2626; }\n.metric-change.neutral { color: var(--text-muted); }\n```\n\n---\n\n## 2. Comparison Table with Insights\n\n2-column layout: left is a comparison table, right is insight cards. Best for period-over-period metrics, bi-weekly/quarterly comparisons.\n\n```html\n<div class=\"comparison-grid reveal\">\n    <div class=\"comparison-table-wrap\">\n        <div class=\"comparison-table-caption\">Comparison Table</div>\n        <table class=\"comparison-table\">\n            <thead>\n                <tr>\n                    <th>Section</th><th>Metric</th>\n                    <th class=\"num\">Period 1</th><th class=\"num\">Period 2</th>\n                    <th class=\"num\">&Delta;</th>\n                </tr>\n            </thead>\n            <tbody>\n                <tr>\n                    <td class=\"section-cell\" rowspan=\"2\">Group A</td>\n                    <td>Metric 1</td>\n                    <td class=\"num\">2,121</td><td class=\"num\">2,349</td>\n                    <td class=\"num delta-pos\">+10.7%</td>\n                </tr>\n                <tr>\n                    <td>Metric 2</td>\n                    <td class=\"num\">65,219</td><td class=\"num\">74,826</td>\n                    <td class=\"num delta-pos\">+14.7%</td>\n                </tr>\n                <tr class=\"section-divider\">\n                    <td class=\"section-cell\" rowspan=\"2\">Group B</td>\n                    <td>Metric 3</td>\n                    <td class=\"num\">1,253,158</td><td class=\"num\">993,785</td>\n                    <td class=\"num delta-neg\">&minus;20.7%</td>\n                </tr>\n                <tr>\n                    <td class=\"indent\">Sub-metric</td>\n                    <td class=\"num\">222,879</td><td class=\"num\">261,876</td>\n                    <td class=\"num delta-pos\">+17.5%</td>\n                </tr>\n            </tbody>\n        </table>\n        <div class=\"comparison-source\">Source: ...</div>\n    </div>\n    <div class=\"comparison-insights\">\n        <div class=\"insight-card\">\n            <span class=\"insight-num\">01 &middot; Theme</span>\n            <span class=\"insight-title\">Key Insight Headline</span>\n            <p class=\"insight-body\">Narrative with <span class=\"pos\">+10.7%</span> inline.</p>\n        </div>\n        <!-- Up to 3 insight cards -->\n    </div>\n</div>\n```\n\nKey CSS classes: `.comparison-grid` (2-column grid), `.comparison-table`, `.insight-card`, `.delta-pos`, `.delta-neg`, `.pos`, `.neg`.\n\n---\n\n## 3. Feature / Scope Table\n\nGeneral-purpose table for feature comparisons, scope definitions, capability matrices.\n\n```html\n<table class=\"data-table reveal\">\n    <thead>\n        <tr><th>Column 1</th><th>Column 2</th><th>Column 3</th></tr>\n    </thead>\n    <tbody>\n        <tr>\n            <td class=\"row-label\">Row Label</td>\n            <td>Value</td>\n            <td>Value</td>\n        </tr>\n    </tbody>\n</table>\n```\n\n### CSS\n\n```css\n.data-table { width: 100%; border-collapse: separate; border-spacing: 0; font-family: var(--font-body); }\n.data-table thead th {\n    font-family: var(--font-display); font-weight: 700; font-size: var(--small-size);\n    color: var(--text-muted); text-transform: uppercase; letter-spacing: 0.05em;\n    padding: clamp(6px, 1vh, 12px) clamp(8px, 1vw, 14px);\n    border-bottom: 2px solid var(--color-heading);\n}\n.data-table tbody td {\n    padding: clamp(6px, 1vh, 12px) clamp(8px, 1vw, 14px);\n    border-bottom: 1px solid var(--border-card);\n}\n.data-table tbody tr:hover { background: var(--bg-secondary); }\n.row-label { font-weight: 600; color: var(--color-heading); }\n```\n\n---\n\n## 4. Two-Column Grid (Findings vs Actions / Pros vs Cons)\n\n2-column layout for problem/solution, pros/cons, before/after, findings/actions.\n\n```html\n<div class=\"two-col-grid reveal\">\n    <div class=\"col-block col-left\">\n        <h3>Left Column Title</h3>\n        <ul class=\"col-list\">\n            <li>Point 1</li>\n            <li>Point 2</li>\n        </ul>\n    </div>\n    <div class=\"col-block col-right\">\n        <h3>Right Column Title</h3>\n        <ul class=\"col-list\">\n            <li>Point 1</li>\n            <li>Point 2</li>\n        </ul>\n    </div>\n</div>\n```\n\n### CSS\n\n```css\n.two-col-grid { display: grid; grid-template-columns: 1fr 1fr; gap: clamp(10px, 1.5vw, 20px); width: 100%; }\n.col-block h3 { margin-bottom: clamp(6px, 1vh, 12px); padding-bottom: clamp(4px, 0.6vh, 8px); border-bottom: 2px solid var(--color-heading); }\n.col-left h3 { color: #dc2626; border-color: #dc2626; }\n.col-right h3 { color: #16803c; border-color: #16803c; }\n.col-list { list-style: none; display: flex; flex-direction: column; gap: clamp(4px, 0.8vh, 10px); }\n.col-list li {\n    font-family: var(--font-body); font-size: var(--body-size);\n    color: var(--text-secondary); line-height: 1.45;\n    padding-left: clamp(12px, 1.5vw, 18px); position: relative;\n}\n.col-list li::before {\n    content: ''; position: absolute; left: 0; top: clamp(5px, 0.7vh, 7px);\n    width: clamp(5px, 0.5vw, 7px); height: clamp(5px, 0.5vw, 7px); border-radius: 50%;\n}\n.col-left .col-list li::before { background: #fca5a5; }\n.col-right .col-list li::before { background: #86efac; }\n```\n\n**Tip:** The left/right color scheme (red/green) is the default for Findings vs Actions. For neutral comparisons (e.g., Option A vs Option B), use `color: var(--color-heading); border-color: var(--color-heading);` on both columns.\n\n---\n\n## 5. Action List\n\nVertical list of items with owner labels and descriptions. Works for action items, decisions, scope items, roadmap entries.\n\n```html\n<div class=\"action-list reveal\">\n    <div class=\"action-item\">\n        <span class=\"action-owner\">Owner / Label</span>\n        <span class=\"action-desc\">Description of the item.</span>\n    </div>\n</div>\n```\n\n### CSS\n\n```css\n.action-list { list-style: none; display: flex; flex-direction: column; gap: clamp(6px, 1vh, 14px); width: 100%; }\n.action-item {\n    display: flex; align-items: flex-start; gap: clamp(8px, 1.2vw, 16px);\n    padding: clamp(8px, 1.2vh, 16px) clamp(10px, 1.5vw, 20px);\n    background: var(--bg-secondary); border-radius: clamp(6px, 0.8vw, 10px);\n    border-left: 3px solid var(--accent);\n}\n.action-owner { font-family: var(--font-display); font-size: var(--small-size); font-weight: 700; color: var(--accent); white-space: nowrap; min-width: clamp(80px, 10vw, 130px); }\n.action-desc { font-family: var(--font-body); line-height: 1.5; }\n```\n\n---\n\n## 6. Timeline\n\nVertical timeline with dots, dates, and descriptions. Use for roadmaps, project phases, milestones.\n\n```html\n<div class=\"timeline reveal\">\n    <div class=\"timeline-step\">\n        <div class=\"timeline-dot\"></div>\n        <div class=\"timeline-step-header\">\n            <h4>Milestone Title</h4>\n            <span class=\"timeline-date\">Q2 2026</span>\n        </div>\n        <p class=\"timeline-desc\">Description.</p>\n    </div>\n</div>\n```\n\n### CSS\n\n```css\n.timeline { display: flex; flex-direction: column; position: relative; padding-left: clamp(16px, 2.5vw, 32px); }\n.timeline::before {\n    content: ''; position: absolute;\n    left: clamp(5px, 0.7vw, 10px); top: clamp(6px, 1vh, 10px); bottom: clamp(6px, 1vh, 10px);\n    width: 2px; background: linear-gradient(to bottom, var(--accent), var(--color-heading));\n}\n.timeline-dot {\n    width: clamp(10px, 1.2vw, 14px); height: clamp(10px, 1.2vw, 14px);\n    border-radius: 50%; background: var(--accent); flex-shrink: 0;\n    position: absolute; z-index: 2;\n}\n.timeline-date { font-family: var(--font-body); font-size: var(--small-size); color: var(--accent); font-weight: 600; }\n```\n\n---\n\n## 7. Status Badge\n\nInline status indicators for tables or lists.\n\n```html\n<span class=\"status-badge on-track\">On Track</span>\n<span class=\"status-badge at-risk\">At Risk</span>\n<span class=\"status-badge done\">Done</span>\n<span class=\"status-badge pending\">Pending</span>\n```\n\n```css\n.status-badge {\n    display: inline-block;\n    padding: clamp(2px, 0.3vh, 4px) clamp(6px, 0.8vw, 12px);\n    border-radius: 100px; font-size: var(--small-size); font-weight: 600;\n}\n.status-badge.on-track { background: #dcfce7; color: #16803c; }\n.status-badge.at-risk { background: #fef2f2; color: #dc2626; }\n.status-badge.done { background: #dbeafe; color: #1d4ed8; }\n.status-badge.pending { background: #f3f4f6; color: #6b7280; }\n```\n\n---\n\n## 8. Screenshot Slot\n\nReplaceable, croppable image placeholder for embedding operational screenshots into slides. Shows a dashed placeholder with label when `src` is empty; displays the image when `src` is set.\n\n```html\n<div class=\"screenshot-slot reveal\">\n    <img src=\"\" alt=\"Description\">\n    <div class=\"screenshot-label\">Screenshot: Description (replace src to update)</div>\n</div>\n```\n\nTo update: set `src` to a local file path, URL, or base64 data URI. Use `object-position` on the `img` for cropping.\n\n```html\n<!-- With image -->\n<div class=\"screenshot-slot reveal\">\n    <img src=\"path/to/screenshot.png\" alt=\"Create dialog\" style=\"object-position: top left;\">\n    <div class=\"screenshot-label\">Screenshot: Create Skill</div>\n</div>\n```\n\n### CSS\n\n```css\n.screenshot-slot {\n    width: 100%; max-height: 42vh;\n    border: 2px dashed var(--border-card); border-radius: clamp(6px, 0.8vw, 12px);\n    overflow: hidden; position: relative;\n    display: flex; align-items: center; justify-content: center;\n    background: var(--bg-secondary); margin-top: var(--element-gap);\n}\n.screenshot-slot img {\n    width: 100%; height: 100%; object-fit: contain; display: block;\n}\n.screenshot-slot img[src=\"\"], .screenshot-slot img:not([src]) { display: none; }\n.screenshot-slot .screenshot-label {\n    position: absolute; font-family: var(--font-body); font-size: var(--small-size);\n    color: var(--text-muted); text-align: center;\n    padding: clamp(20px, 4vh, 40px);\n}\n.screenshot-slot img[src]:not([src=\"\"]) ~ .screenshot-label { display: none; }\n```\n\n### Usage Notes\n\n- The label auto-hides when an image `src` is provided\n- Adjust `max-height` to fit slide layout (default 42vh)\n- Use `object-position` CSS on `img` for cropping (e.g., `object-position: top center`)\n- Use `object-fit: cover` instead of `contain` for full-bleed cropping\n- For bilingual labels, use `<span class=\"lang-en\">...</span><span class=\"lang-cn\">...</span>` inside `.screenshot-label`\n\nFile v1.0.0:references/design-tokens.md\n\n# Design Tokens\n\nThis file defines the CSS custom property system. Select a brand preset and copy the corresponding `:root` block into the presentation.\n\n---\n\n## Brand Presets\n\n### Preset: Shopee / Sea (DEFAULT)\n\n```html\n<link rel=\"preconnect\" href=\"https://fonts.googleapis.com\">\n<link rel=\"preconnect\" href=\"https://fonts.gstatic.com\" crossorigin>\n<link href=\"https://fonts.googleapis.com/css2?family=Lato:wght@300;400;700;900&family=Open+Sans:wght@300;400;500;600;700&family=Roboto+Mono:wght@400;500;600&display=swap\" rel=\"stylesheet\">\n```\n\n```css\n:root {\n    /* Colors — Shopee Corporate */\n    --accent-primary: #ee4d2d;\n    --accent-secondary: #05007E;\n    --color-heading: #05007E;\n    --accent: #ee4d2d;\n    --accent-glow: rgba(238, 77, 45, 0.3);\n    --bg-primary: #ffffff;\n    --bg-secondary: #f7f8fa;\n    --bg-card: #f7f8fa;\n    --bg-card-hover: #f0f1f5;\n    --text-primary: #1a1a1a;\n    --text-secondary: #5a5f6b;\n    --text-muted: #999999;\n    --text-on-accent: #ffffff;\n    --border-subtle: rgba(0,0,0,0.06);\n    --border-card: #eee;\n\n    /* Typography */\n    --font-display: 'Lato', sans-serif;\n    --font-body: 'Open Sans', sans-serif;\n    --font-mono: 'Roboto Mono', monospace;\n\n    /* Brand Config */\n    --brand-has-logo: 1; /* 1 = show logo elements, 0 = hide */\n    --section-bg: #05007E; /* section divider background */\n}\n```\n\n**Logos (MANDATORY — both Shopee AND SeaMoney):** Embed via CSS `content: url(data:image/png;base64,...)` targeting `img.brand-logo.shopee` and `img.brand-logo.seamoney`. Both logos MUST appear on cover slides, section dividers, content headers, and closing slides. Copy the actual base64 data from the most recent presentation file.\n\n```css\nimg.brand-logo.shopee { content: url(data:image/png;base64,...SHOPEE_LOGO_DATA...); }\nimg.brand-logo.seamoney { content: url(data:image/png;base64,...SEAMONEY_LOGO_DATA...); }\n```\n\nHTML pattern: `<img src=\"data:,\" class=\"brand-logo shopee\" alt=\"Shopee\">` and `<img src=\"data:,\" class=\"brand-logo seamoney\" alt=\"SeaMoney\">`.\n\n---\n\n### Preset: Neutral / Minimal\n\n```html\n<link href=\"https://fonts.googleapis.com/css2?family=DM+Sans:wght@400;500;700;800&family=Inter:wght@300;400;500;600;700&family=JetBrains+Mono:wght@400;500;600&display=swap\" rel=\"stylesheet\">\n```\n\n```css\n:root {\n    /* Colors — Neutral Corporate */\n    --accent-primary: #2563eb;\n    --accent-secondary: #1e293b;\n    --color-heading: #1e293b;\n    --accent: #2563eb;\n    --accent-glow: rgba(37, 99, 235, 0.2);\n    --bg-primary: #ffffff;\n    --bg-secondary: #f8fafc;\n    --bg-card: #f8fafc;\n    --bg-card-hover: #f1f5f9;\n    --text-primary: #0f172a;\n    --text-secondary: #475569;\n    --text-muted: #94a3b8;\n    --text-on-accent: #ffffff;\n    --border-subtle: rgba(0,0,0,0.06);\n    --border-card: #e2e8f0;\n\n    /* Typography */\n    --font-display: 'DM Sans', sans-serif;\n    --font-body: 'Inter', sans-serif;\n    --font-mono: 'JetBrains Mono', monospace;\n\n    /* Brand Config */\n    --brand-has-logo: 0;\n    --section-bg: #1e293b;\n}\n```\n\n**Logos:** None. Hide all `.brand-logo` containers or replace with text-only headers.\n\n---\n\n### Preset: Custom\n\nStart from the Shopee/Sea preset and swap these values:\n\n```css\n:root {\n    --accent-primary: <USER_PRIMARY_COLOR>;\n    --accent-secondary: <USER_SECONDARY_COLOR>;\n    --color-heading: <USER_SECONDARY_COLOR>;\n    --accent: <USER_PRIMARY_COLOR>;\n    --accent-glow: <USER_PRIMARY_COLOR with 0.2 alpha>;\n    --section-bg: <USER_SECONDARY_COLOR>;\n\n    /* Typography — swap if user provides font preferences */\n    --font-display: <USER_DISPLAY_FONT>;\n    --font-body: <USER_BODY_FONT>;\n    --font-mono: <USER_MONO_FONT>;\n\n    --brand-has-logo: <1 if user provides logo, else 0>;\n}\n```\n\n---\n\n## Shared Token Scale (ALL presets use these)\n\nThese structural tokens do NOT change between presets:\n\n```css\n:root {\n    /* Typography — sizes */\n    --title-size: clamp(1.5rem, 5vw, 4rem);\n    --h2-size: clamp(1.25rem, 3.5vw, 2.5rem);\n    --h3-size: clamp(1rem, 2.5vw, 1.75rem);\n    --h4-size: clamp(0.85rem, 1.6vw, 1.3rem);\n    --body-size: clamp(0.75rem, 1.5vw, 1.125rem);\n    --small-size: clamp(0.65rem, 1vw, 0.875rem);\n    --eyebrow-size: clamp(0.6rem, 0.95vw, 0.85rem);\n    --card-num-size: clamp(0.55rem, 0.8vw, 0.75rem);\n    --cta-size: clamp(1.2rem, 2.8vw, 2.2rem);\n\n    /* Spacing */\n    --slide-padding: clamp(1rem, 4vw, 4rem);\n    --content-gap: clamp(0.5rem, 2vw, 2rem);\n    --element-gap: clamp(0.25rem, 1vw, 1rem);\n\n    /* Sidebar */\n    --sidebar-width: clamp(180px, 16vw, 240px);\n\n    /* Comment Panel */\n    --comment-panel-width: clamp(220px, 20vw, 320px);\n    --panel-transition: 0.35s cubic-bezier(0.16, 1, 0.3, 1);\n\n    /* Edit mode */\n    --edit-extra: 0px;\n\n    /* Zoom */\n    --zoom-level: 1;\n\n    /* Animation */\n    --ease: cubic-bezier(0.16, 1, 0.3, 1);\n    --duration: 0.7s;\n}\n```\n\n---\n\n## Base Typography Rules\n\n```css\n.slide-content h1 { font-size: var(--title-size); font-weight: 900; line-height: 1.1; font-family: var(--font-display); }\n.slide-content h2 { font-size: var(--h2-size); font-weight: 700; line-height: 1.2; font-family: var(--font-display); color: var(--color-heading); }\n.slide-content h3 { font-size: var(--h3-size); font-weight: 700; font-family: var(--font-display); color: var(--color-heading); }\n.slide-content h4 { font-size: var(--h4-size); font-weight: 700; font-family: var(--font-display); color: var(--color-heading); }\n.slide-content p  { font-size: var(--body-size); line-height: 1.6; font-family: var(--font-body); color: var(--text-secondary); }\n```\n\n## Status Colors (shared across all presets)\n\n| Color | CSS | Usage |\n|-------|-----|-------|\n| Green (positive) | `#16803c` | Positive metrics, on-track |\n| Red (negative) | `#dc2626` | Negative metrics, at-risk |\n| Green bg | `#dcfce7` | On-track badge background |\n| Red bg | `#fef2f2` | At-risk badge background |\n| Green dots | `#86efac` | Mitigation list markers |\n| Red dots | `#fca5a5` | Risk list markers |\n\n## Reveal Animations\n\n```css\n.reveal {\n    opacity: 0; transform: translateY(25px);\n    transition: opacity var(--duration) var(--ease), transform var(--duration) var(--ease);\n}\n.reveal-left {\n    opacity: 0; transform: translateX(-30px);\n    transition: opacity var(--duration) var(--ease), transform var(--duration) var(--ease);\n}\n.reveal-scale {\n    opacity: 0; transform: scale(0.92);\n    transition: opacity var(--duration) var(--ease), transform var(--duration) var(--ease);\n}\n.slide.visible .reveal,\n.slide.visible .reveal-left,\n.slide.visible .reveal-scale {\n    opacity: 1; transform: translateY(0) translateX(0) scale(1);\n}\n.slide.visible .reveal:nth-child(1) { transition-delay: 0.1s; }\n.slide.visible .reveal:nth-child(2) { transition-delay: 0.2s; }\n.slide.visible .reveal:nth-child(3) { transition-delay: 0.3s; }\n.slide.visible .reveal:nth-child(4) { transition-delay: 0.4s; }\n.slide.visible .reveal:nth-child(5) { transition-delay: 0.5s; }\n.slide.visible .reveal:nth-child(6) { transition-delay: 0.6s; }\n```\n\nFile v1.0.0:references/js-controller.md\n\n# JS Controller — SlidePresentation Class\n\nCopy this complete `<script>` block at the end of `<body>`. The class is fully brand-agnostic — it reads from DOM elements and CSS properties only.\n\n## Features\n\n| Feature | Trigger | Description |\n|---------|---------|-------------|\n| Language switch | Click EN or CN segment, or press `L` | Switches `body.lang-cn` ↔ `body.lang-en`, updates sidebar text, persisted to localStorage |\n| Sidebar auto-build | On load | Reads `data-title` (CN) and `data-title-en` from slides; `data-group` (CN) and `data-group-en` for group headers |\n| Slide visibility | Intersection observer | Adds `.visible` class at 50% threshold (triggers reveal animations) |\n| Keyboard nav | Arrow keys, Space, PageUp/Down, Home/End | Smooth scroll between slides |\n| Touch/swipe | Vertical swipe >50px | Mobile-friendly navigation |\n| Mouse wheel | With 800ms debounce | Scroll one slide at a time |\n| Sidebar click | Click any sidebar item | Jump to slide |\n| Progress bar | Auto-update | Top bar width = % of slides viewed |\n| Page numbers | On load | `N / Total` rendered in each `.page-number` |\n| Sidebar toggle | Click hamburger | Toggles `body.sidebar-hidden` |\n| Comment panel | Press `C` or click icon | Per-slide notes, localStorage persistence, Copy All, Clear All |\n| Zoom | +/- buttons | 70%–150%, step 10%, applies CSS `zoom` to `.slide-content` |\n| Inline edit | Press `E` or click pencil | contentEditable on text elements, undo/redo history |\n| Present mode | Press `F5` or click play | fullscreen, hides all chrome |\n\n## Complete Script\n\n**IMPORTANT:** Always copy the full ~600-line JS implementation from the most recent source presentation. The stub below shows the class structure.\n\n```javascript\nclass SlidePresentation {\n    constructor() {\n        this.slides = document.querySelectorAll('.slide');\n        this.currentSlide = 0;\n        this.isScrolling = false;\n        this.scrollTimeout = null;\n\n        // Language switch (bilingual only — skipped if #langSwitch absent)\n        this.setupLanguageToggle();\n\n        this.setupPageNumbers();\n        this.buildSidebar();\n        this.setupIntersectionObserver();\n        this.setupKeyboardNav();\n        this.setupTouchNav();\n        this.setupProgressBar();\n        this.setupWheelNav();\n        this.setupSidebarNav();\n\n        this.sidebarVisible = true;\n        this.setupSidebarToggle();\n\n        // Comment panel\n        this.commentPanel = document.getElementById('commentPanel');\n        this.commentTextarea = document.getElementById('commentTextarea');\n        this.commentSlideLabel = document.getElementById('commentSlideLabel');\n        this.commentSlideName = document.getElementById('commentSlideName');\n        this.commentCopyAllBtn = document.getElementById('commentCopyAll');\n        this.commentStatus = document.getElementById('commentStatus');\n        this.commentsOpen = false;\n        this.comments = this.loadComments();\n        this.slideNames = Array.from(this.slides).map(\n            slide => slide.dataset.title || 'Slide ' + (Array.from(this.slides).indexOf(slide) + 1)\n        );\n        this.setupCommentPanel();\n\n        // Zoom\n        this.zoomLevel = 1.0;\n        this.zoomMin = 0.7;\n        this.zoomMax = 1.5;\n        this.zoomStep = 0.1;\n        this.setupZoomControls();\n\n        // Inline edit\n        this.editActive = false;\n        this.editHistory = [];\n        this.editHistoryIndex = -1;\n        this.activeEditEl = null;\n        this.setupInlineEdit();\n\n        // Present mode\n        this.presentMode = false;\n        this.setupPresentMode();\n\n        this.slides[0].classList.add('visible');\n        this.updateAll();\n    }\n\n    /* --- Language switch: body.lang-cn ↔ body.lang-en --- */\n    setupLanguageToggle() {\n        /* Only active when #langSwitch exists (bilingual presentations).\n           - Reads saved preference from localStorage (key: title-slug + '-lang')\n           - Default: 'cn' (body starts with class lang-cn)\n           - #langEn click → setLanguage('en'); #langCn click → setLanguage('cn')\n           - Press L: toggle between 'en' and 'cn'\n           - Update .lang-option.active class to highlight active segment\n           - Persist choice to localStorage\n           - If #langSwitch not found, skip entirely (monolingual mode) */\n    }\n    setLanguage(lang) {\n        /* lang = 'en' | 'cn'\n           - Remove both lang-en and lang-cn from body\n           - Add body.lang-{lang}\n           - Update .lang-option active state (#langEn / #langCn)\n           - Update sidebar text: for each sidebar item, read its stored data-title-en / data-title (CN)\n             and set textContent based on active language.\n             For group headers, read data-group-en / data-group (CN).\n           - Save to localStorage */\n    }\n\n    /* --- Sidebar auto-build from data-title / data-title-en / data-group / data-group-en --- */\n    buildSidebar() {\n        /* Reads each slide's data-title (CN) and data-title-en (EN).\n           Group headers use data-group (CN) and data-group-en (EN).\n           Sidebar items store both titles as data attributes for language switching.\n           Renders text based on current body language class. */\n    }\n\n    /* --- Intersection observer for .visible class --- */\n    setupIntersectionObserver() { /* threshold: 0.5 */ }\n\n    /* --- Keyboard: arrows, space, page up/down, home/end, L for language switch --- */\n    setupKeyboardNav() { /* skips TEXTAREA/INPUT/contentEditable targets; L toggles between en/cn */ }\n\n    /* --- Touch: vertical swipe >50px --- */\n    setupTouchNav() { /* skips .comment-panel targets */ }\n\n    /* --- Mouse wheel with 800ms debounce --- */\n    setupWheelNav() { /* deltaY >30 threshold */ }\n\n    /* --- Sidebar click navigation --- */\n    setupSidebarNav() { /* reads data-slide attribute */ }\n\n    /* --- Navigate to slide index --- */\n    goToSlide(index) { /* scrollIntoView + updateAll */ }\n\n    /* --- Update progress, sidebar, page number, comments --- */\n    updateAll() { /* calls all update methods */ }\n\n    /* --- Progress bar: width = (current+1)/total * 100% --- */\n    setupProgressBar() { /* ... */ }\n    updateProgressBar() { /* ... */ }\n\n    /* --- Sidebar active state tracking --- */\n    updateSidebar() { /* toggles .active class, scrollIntoView */ }\n\n    /* --- Static page numbers in each footer --- */\n    setupPageNumbers() { /* renders N / Total into .page-number elements */ }\n\n    /* --- Sidebar toggle: body.sidebar-hidden --- */\n    setupSidebarToggle() { /* click handler on #sidebarToggle */ }\n\n    /* --- Comment panel --- */\n    toggleComments() { /* body.comments-open */ }\n    setupCommentPanel() {\n        /* Toggle: click #commentToggle or press C\n           Auto-save: debounced 500ms to localStorage\n           Copy All: exports as Markdown with slide headers\n           Clear All: with confirmation dialog */\n    }\n    updateCommentPanel() { /* sync textarea to current slide */ }\n    loadComments() { /* localStorage key derived from document.title */ }\n    saveComments() { /* clean empty entries, persist */ }\n    async copyAllComments() { /* clipboard API with fallback */ }\n    showStatus(msg) { /* flash message for 2s */ }\n\n    /* --- Zoom: 70%-150%, step 10% --- */\n    setupZoomControls() { /* #zoomIn, #zoomOut click handlers */ }\n    setZoom(level) { /* CSS zoom on .slide-content, --zoom-level variable */ }\n    updateZoomButtons() { /* disable at min/max */ }\n\n    /* --- Inline text editing --- */\n    setupInlineEdit() {\n        /* Toggle: click #editToggle or press E\n           Selectors for editable elements:\n           h1, h2, h3, p, li, td (not thead), .eyebrow, .slide-title,\n           .kpi-label, .kpi-number, .kpi-change, .body-text\n           Each gets .editable class + edit icon overlay\n           Double-click or icon click activates contentEditable\n           Escape cancels edit */\n    }\n    toggleEditMode() { /* body.edit-active, optional discard dialog */ }\n    startInlineEdit(el) { /* contentEditable=true, .editing class, select all */ }\n    stopInlineEdit() { /* save to history if changed */ }\n    editUndo() { /* restore oldHTML from history */ }\n    editRedo() { /* apply newHTML from history */ }\n\n    /* --- Present mode --- */\n    setupPresentMode() { /* F5 or #presentToggle click */ }\n    enterPresentMode() { /* body.present-mode, requestFullscreen */ }\n    exitPresentMode() { /* triggered by fullscreenchange event */ }\n}\n\ndocument.addEventListener('DOMContentLoaded', () => {\n    new SlidePresentation();\n});\n```\n\n## Implementation Notes\n\n1. **Language switch** localStorage key is `{title-slug}-lang`, stores `'en'` or `'cn'`. Default is `'cn'`. Only initialized when `#langSwitch` element exists (bilingual mode). Two segment buttons: EN and CN. The active segment has `.active` class (highlighted with accent color). When language changes, `setLanguage()` also updates all sidebar item text (reads stored `data-title-en`/`data-title-cn` attributes from sidebar links and `data-group-en`/`data-group-cn` from group headers).\n2. **Sidebar logo** is extracted from `document.title` — split on `—`, `–`, or `|` delimiters\n3. **Comment localStorage key** is a slug of `document.title` — unique per presentation\n4. **Zoom** uses CSS `zoom` property on `.slide-content` elements and updates `--zoom-level` CSS variable (for padding compensation)\n5. **Edit history** is per-session only (not persisted)\n6. **Present mode** uses Fullscreen API — exit via Escape key or browser controls\n\n**Always copy the full implementation from the most recent source presentation file.** The stub above is for reference only.\n\nFile v1.0.0:references/slide-types.md\n\n# Slide Types\n\nEvery presentation uses four slide types. Each slide is a `<section class=\"slide [type-class]\">` with `data-title` and `data-group` attributes used by the JS sidebar builder.\n\n**Brand-aware elements:** Logos, accent colors, and section backgrounds all come from CSS custom properties. The same HTML works across all brand presets — only the `:root` variables change.\n\n**Logo rule for Shopee/Sea preset:** Both Shopee logo AND SeaMoney logo MUST appear on cover slides, section dividers, and content slide headers. Use class names `.shopee` and `.seamoney` — the CSS `content` property embeds the actual logo images via base64 data URIs. For Neutral preset, omit logo elements entirely.\n\n---\n\n## 1. Cover Slide\n\nFirst slide. Centered layout with optional logos, title, accent bar, subtitle, meta.\n\n### With Logos — Shopee/Sea (BOTH logos MANDATORY)\n\n```html\n<section class=\"slide cover-slide\" data-title=\"Title\" data-group=\"Overview\">\n    <div class=\"slide-content\">\n        <div class=\"cover-logos reveal\">\n            <img src=\"data:,\" class=\"brand-logo shopee\" alt=\"Shopee\">\n            <img src=\"data:,\" class=\"brand-logo seamoney\" alt=\"SeaMoney\">\n        </div>\n        <span class=\"cover-title reveal\">Presentation Title</span>\n        <div class=\"cover-accent-bar reveal\"></div>\n        <span class=\"cover-subtitle reveal\">Subtitle or Description</span>\n        <div class=\"cover-meta reveal\">\n            <span>Team Name</span>\n            <span>2026-04-10</span>\n        </div>\n    </div>\n    <div class=\"slide-footer\">\n        <div class=\"footer-left\"></div>\n        <div class=\"footer-center\">Private &amp; Confidential</div>\n        <div class=\"footer-right page-number\"></div>\n    </div>\n</section>\n```\n\n### With Logos — Custom Brand\n\n```html\n<!-- Use brand-specific class names; CSS content: url(data:...) will embed them -->\n<div class=\"cover-logos reveal\">\n    <img src=\"data:,\" class=\"brand-logo custom-primary\" alt=\"Brand\">\n    <img src=\"data:,\" class=\"brand-logo custom-secondary\" alt=\"Brand 2\">  <!-- optional if only one logo -->\n</div>\n```\n\n### Without Logos (Neutral preset)\n\n```html\n<section class=\"slide cover-slide\" data-title=\"Title\" data-group=\"Overview\">\n    <div class=\"slide-content\">\n        <span class=\"cover-title reveal\">Presentation Title</span>\n        <div class=\"cover-accent-bar reveal\"></div>\n        <span class=\"cover-subtitle reveal\">Subtitle or Description</span>\n        <div class=\"cover-meta reveal\">\n            <span>Team Name</span>\n            <span>2026-04-10</span>\n        </div>\n    </div>\n    <div class=\"slide-footer\">\n        <div class=\"footer-left\"></div>\n        <div class=\"footer-center\">Private &amp; Confidential</div>\n        <div class=\"footer-right page-number\"></div>\n    </div>\n</section>\n```\n\n### Cover CSS\n\n```css\n.cover-slide { background: var(--bg-primary); }\n.cover-slide .slide-content {\n    align-items: center; text-align: center;\n    gap: clamp(0.8rem, 2vh, 1.8rem);\n}\n.cover-logos { display: flex; align-items: center; gap: clamp(8px, 1.2vw, 16px); }\n.cover-logos img { height: clamp(35px, 5.5vh, 62px); }\n.cover-title {\n    font-family: var(--font-display); font-size: var(--title-size);\n    font-weight: 900; color: var(--accent); line-height: 1.1;\n}\n.cover-accent-bar {\n    width: 100%; max-width: clamp(200px, 40vw, 500px);\n    height: 3px; background: var(--accent);\n}\n.cover-subtitle {\n    font-family: var(--font-body); font-size: var(--h3-size);\n    color: var(--text-secondary); font-weight: 400;\n}\n.cover-meta {\n    font-family: var(--font-body); font-size: var(--small-size);\n    color: var(--text-muted); display: flex; gap: clamp(12px, 2vw, 24px);\n}\n```\n\n---\n\n## 2. Section Divider Slide\n\nColored background (uses `--section-bg`), used to transition between major topics. Large ghost section number.\n\n```html\n<section class=\"slide section-slide\" data-title=\"Section Name\" data-group=\"Section Group\">\n    <div class=\"slide-content\">\n        <!-- Shopee/Sea: BOTH logos MANDATORY; Neutral: omit this div -->\n        <div class=\"section-logos reveal\">\n            <img src=\"data:,\" class=\"brand-logo shopee\" alt=\"Shopee\">\n            <img src=\"data:,\" class=\"brand-logo seamoney\" alt=\"SeaMoney\">\n        </div>\n        <div class=\"section-accent-bar reveal\"></div>\n        <span class=\"section-title reveal\">Section Title</span>\n        <p class=\"subtitle reveal\">One-line description of what this section covers.</p>\n        <span class=\"section-number\">01</span>\n    </div>\n    <div class=\"slide-footer\">\n        <div class=\"footer-left\"></div>\n        <div class=\"footer-center\">Private &amp; Confidential</div>\n        <div class=\"footer-right page-number\"></div>\n    </div>\n</section>\n```\n\n### Section Divider CSS\n\n```css\n.section-slide { background: var(--section-bg); }\n.section-slide .slide-content { align-items: flex-start; gap: clamp(0.5rem, 1.5vh, 1.2rem); }\n.section-logos img { height: clamp(28px, 4vh, 45px); filter: brightness(0) invert(1); opacity: 0.9; }\n.section-accent-bar { width: clamp(60px, 10vw, 120px); height: 3px; background: var(--accent); }\n.section-title {\n    font-family: var(--font-display); font-size: var(--h2-size);\n    font-weight: 900; color: var(--text-on-accent); line-height: 1.15;\n}\n.section-slide .subtitle {\n    font-family: var(--font-body); font-size: var(--body-size);\n    color: rgba(255, 255, 255, 0.7); max-width: 60%;\n}\n.section-number {\n    font-family: var(--font-display); font-size: clamp(3rem, 8vw, 7rem);\n    font-weight: 900; color: rgba(255, 255, 255, 0.08);\n    position: absolute; right: var(--slide-padding); top: 50%; transform: translateY(-50%);\n}\n.section-slide .slide-footer .footer-center,\n.section-slide .slide-footer .page-current { color: rgba(255, 255, 255, 0.4); }\n.section-slide .slide-footer .page-separator,\n.section-slide .slide-footer .page-total { color: rgba(255, 255, 255, 0.25); }\n```\n\n---\n\n## 3. Content Slide\n\nThe main information carrier. Header bar (optional logos + section title + accent line) + body area for components.\n\n```html\n<section class=\"slide content-slide\" data-title=\"Slide Title\" data-group=\"Group Name\">\n    <div class=\"slide-header\">\n        <!-- Shopee/Sea: BOTH logos MANDATORY; Neutral: drop .header-logos div -->\n        <div class=\"header-logos\">\n            <img src=\"data:,\" class=\"brand-logo shopee\" alt=\"Shopee\">\n            <img src=\"data:,\" class=\"brand-logo seamoney\" alt=\"SeaMoney\">\n        </div>\n        <div class=\"header-title-block\">\n            <span class=\"header-title\">Section Title</span>\n            <div class=\"header-line\"></div>\n        </div>\n    </div>\n    <div class=\"slide-content\">\n        <h2 class=\"reveal\">Main insight or headline for this slide.</h2>\n        <p class=\"reveal\">Supporting context — keep to 2-3 sentences max.</p>\n        <!-- INSERT COMPONENT(S) HERE with class=\"reveal\" -->\n    </div>\n    <div class=\"slide-footer\">\n        <div class=\"footer-left\"></div>\n        <div class=\"footer-center\">Private &amp; Confidential</div>\n        <div class=\"footer-right page-number\"></div>\n    </div>\n</section>\n```\n\nFor **Neutral preset** without logos, drop the `.header-logos` div:\n\n```html\n<div class=\"slide-header\">\n    <div class=\"header-title-block\">\n        <span class=\"header-title\">Section Title</span>\n        <div class=\"header-line\"></div>\n    </div>\n</div>\n```\n\n### Content Slide CSS\n\n```css\n.slide-header {\n    display: flex; align-items: center;\n    padding: var(--slide-padding); padding-bottom: 0;\n    padding-left: calc((var(--sidebar-width) + clamp(1.5rem, 4vw, 4rem)) / var(--zoom-level, 1));\n    gap: clamp(10px, 1.5vw, 20px);\n}\n.header-logos img { height: clamp(31px, 4.4vh, 48px); }\n.header-title {\n    font-family: var(--font-display); font-size: var(--h2-size);\n    font-weight: 700; color: var(--accent);\n}\n.header-line { height: 3px; background: var(--accent); width: 100%; }\n.content-slide .slide-content {\n    justify-content: flex-start;\n    padding-top: clamp(0.5rem, 1.5vh, 1.5rem);\n    gap: var(--content-gap);\n}\n.content-slide p { max-width: 85%; }\n```\n\n---\n\n## 4. Closing Slide\n\nLast slide. Variant of cover — can use \"Thank You\", \"Next Steps\", \"Q&A\", etc.\n\n```html\n<section class=\"slide cover-slide closing-slide\" data-title=\"Thank You\" data-group=\"Closing\">\n    <div class=\"slide-content\">\n        <!-- Shopee/Sea: include both logos; Neutral: omit -->\n        <div class=\"cover-logos reveal\">\n            <img src=\"data:,\" class=\"brand-logo shopee\" alt=\"Shopee\">\n            <img src=\"data:,\" class=\"brand-logo seamoney\" alt=\"SeaMoney\">\n        </div>\n        <span class=\"cover-title reveal\">Thank You</span>\n        <div class=\"cover-accent-bar reveal\"></div>\n        <span class=\"cover-subtitle reveal\">Presentation Title · Date</span>\n        <div class=\"cover-meta reveal\">\n            <span>Questions &amp; Discussion</span>\n            <span>Team Name</span>\n        </div>\n    </div>\n    <div class=\"slide-footer\">\n        <div class=\"footer-left\"></div>\n        <div class=\"footer-center\">Private &amp; Confidential</div>\n        <div class=\"footer-right page-number\"></div>\n    </div>\n</section>\n```\n\n---\n\n## Footer (Every Slide)\n\nEvery slide MUST include this footer. Page numbers are populated by JS.\n\n```css\n.slide-footer {\n    display: flex; justify-content: space-between; align-items: center;\n    padding: clamp(8px, 1.5vh, 16px) var(--slide-padding);\n    padding-left: calc((var(--sidebar-width) + clamp(1.5rem, 4vw, 4rem)) / var(--zoom-level, 1));\n    flex-shrink: 0;\n}\n.page-current { font-size: 1.4vw; font-weight: 700; color: var(--text-primary); }\n.page-separator { font-size: 1vw; color: var(--text-muted); margin: 0 0.35em; }\n.page-total { font-size: 1vw; color: var(--text-muted); }\n```\n\nFile v1.0.0:references/viewport-chrome.md\n\n# Viewport Fitting & Interactive Chrome\n\nAll CSS in this file is brand-agnostic — it references only CSS custom properties, so it works with any brand preset.\n\n## Viewport Fitting (MANDATORY)\n\nCopy this entire block into every presentation.\n\n```css\n* { margin: 0; padding: 0; box-sizing: border-box; }\n\nhtml, body { height: 100%; overflow-x: hidden; }\nhtml { scroll-snap-type: y mandatory; scroll-behavior: smooth; }\n\nbody {\n    background: var(--bg-primary);\n    font-family: var(--font-display);\n    color: var(--text-primary);\n    -webkit-font-smoothing: antialiased;\n}\n\n.slide {\n    width: 100vw; height: 100vh; height: 100dvh;\n    overflow: hidden; scroll-snap-align: start;\n    display: flex; flex-direction: column; position: relative;\n}\n\n.slide-content {\n    flex: 1; display: flex; flex-direction: column;\n    justify-content: center; max-height: 100%; overflow: hidden;\n    padding: calc(var(--slide-padding) / var(--zoom-level, 1));\n    padding-left: calc((var(--sidebar-width) + clamp(1.5rem, 4vw, 4rem)) / var(--zoom-level, 1));\n    transition: padding-left var(--panel-transition), padding-right var(--panel-transition);\n}\n\n.card, .container, .content-box { max-width: min(90vw, 1000px); max-height: min(80vh, 700px); }\nimg, .image-container { max-width: 100%; max-height: min(50vh, 400px); object-fit: contain; }\n```\n\n## Responsive Breakpoints\n\n```css\n@media (max-height: 700px) {\n    :root {\n        --slide-padding: clamp(0.75rem, 3vw, 2rem);\n        --content-gap: clamp(0.4rem, 1.5vw, 1rem);\n        --title-size: clamp(1.5rem, 5.4vw, 3rem);\n        --h2-size: clamp(1.2rem, 3.6vw, 2.1rem);\n    }\n}\n@media (max-height: 600px) {\n    :root {\n        --slide-padding: clamp(0.5rem, 2.5vw, 1.5rem);\n        --title-size: clamp(1.32rem, 4.8vw, 2.4rem);\n        --body-size: clamp(0.84rem, 1.44vw, 1.14rem);\n    }\n    .nav-dots, .keyboard-hint, .decorative { display: none; }\n}\n@media (max-height: 500px) {\n    :root {\n        --slide-padding: clamp(0.4rem, 2vw, 1rem);\n        --title-size: clamp(1.2rem, 4.2vw, 1.8rem);\n    }\n}\n@media (max-width: 600px) {\n    :root { --title-size: clamp(1.5rem, 8.4vw, 3rem); }\n    .grid { grid-template-columns: 1fr; }\n    .metrics-grid { grid-template-columns: 1fr 1fr; }\n    .two-col-grid { grid-template-columns: 1fr; }\n}\n@media (max-width: 768px) {\n    :root { --sidebar-width: 0px; --comment-panel-width: 85vw; }\n    .sidebar, .sidebar-toggle { display: none; }\n    .slide-content { padding-left: calc(var(--slide-padding) / var(--zoom-level, 1)); }\n    .chrome-toolbar { right: 0.5rem !important; }\n}\n@media (max-width: 480px) {\n    .metrics-grid { grid-template-columns: 1fr; }\n}\n@media (prefers-reduced-motion: reduce) {\n    *, *::before, *::after {\n        animation-duration: 0.01ms !important;\n        transition-duration: 0.2s !important;\n    }\n    html { scroll-behavior: auto; }\n}\n```\n\n---\n\n## Chrome HTML Templates\n\n### Sidebar Navigation + Toggle + Progress Bar\n\nThe sidebar is auto-built by JS from `data-title` and `data-group` attributes on slides.\n\n**Toggle button is flush against the sidebar's right edge** — it moves with the sidebar when expanding/collapsing.\n\n**Progress bar only spans the slide area** (starts at `left: var(--sidebar-width)`, not from the viewport edge).\n\n```html\n<nav class=\"sidebar\" id=\"sidebar\" aria-label=\"Slide navigation\">\n    <div class=\"sidebar-header\">\n        <div class=\"sidebar-logo\" id=\"sidebarLogo\"></div>\n    </div>\n    <div class=\"sidebar-divider\"></div>\n    <div id=\"sidebarNav\"></div>\n</nav>\n\n<!-- Toggle sits OUTSIDE the sidebar, flush against its right edge -->\n<button class=\"sidebar-toggle\" id=\"sidebarToggle\" aria-label=\"Toggle sidebar\" title=\"Toggle sidebar\">\n    <svg width=\"18\" height=\"18\" viewBox=\"0 0 18 18\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\">\n        <path d=\"M3 4h12M3 9h12M3 14h12\"/>\n    </svg>\n</button>\n\n<!-- Progress bar covers ONLY the slide area, NOT the sidebar -->\n<div class=\"progress-bar\" id=\"progressBar\"></div>\n```\n\n#### Sidebar + Toggle + Progress CSS\n\n```css\n/* === SIDEBAR === */\n.sidebar {\n    position: fixed; left: 0; top: 0; bottom: 0;\n    width: var(--sidebar-width);\n    background: #fff; z-index: 1000;\n    border-right: 1px solid var(--border-subtle);\n    display: flex; flex-direction: column;\n    transition: transform var(--panel-transition);\n    overflow-y: auto;\n}\nbody.sidebar-hidden .sidebar {\n    transform: translateX(-100%);\n}\n\n/* === SIDEBAR TOGGLE — flush OUTSIDE sidebar right edge === */\n.sidebar-toggle {\n    position: fixed;\n    top: clamp(0.6rem, 1.5vh, 1rem);\n    left: calc(var(--sidebar-width) + 4px);\n    z-index: 1001;\n    width: 32px; height: 32px;\n    border: none; border-radius: 6px; cursor: pointer;\n    background: rgba(255,255,255,0.85);\n    backdrop-filter: blur(8px);\n    color: var(--text-secondary);\n    display: flex; align-items: center; justify-content: center;\n    transition: left var(--panel-transition);\n}\n.sidebar-toggle:hover {\n    background: var(--bg-card-hover);\n    color: var(--text-primary);\n}\n/* When sidebar hidden: toggle snaps to left edge of viewport */\nbody.sidebar-hidden .sidebar-toggle {\n    left: 6px;\n}\n/* In present mode hide the toggle */\nbody.present-mode .sidebar-toggle { display: none; }\n\n/* === PROGRESS BAR — spans slide area only === */\n.progress-bar {\n    position: fixed;\n    top: 0;\n    left: var(--sidebar-width);   /* starts where slides start */\n    right: 0;\n    height: 3px;\n    background: var(--accent);\n    transform-origin: left;\n    transform: scaleX(0);\n    z-index: 1002;\n    transition: left var(--panel-transition), transform 0.3s ease;\n}\n/* When sidebar hidden, progress bar extends full width */\nbody.sidebar-hidden .progress-bar {\n    left: 0;\n}\nbody.present-mode .progress-bar { display: none; }\n```\n\n---\n\n### Chrome Toolbar (Horizontal — Top Right)\n\nAll chrome controls are grouped in a **single horizontal toolbar**. Order left to right: **Language switch → Present → Zoom → Edit → Comment**.\n\nThe language switch is only included in **bilingual presentations**. For monolingual output, omit the `#langSwitch` div and its adjacent divider.\n\n```html\n<div class=\"chrome-toolbar\" id=\"chromeToolbar\">\n    <!-- 0. Language switch (bilingual only) -->\n    <div class=\"lang-switch\" id=\"langSwitch\">\n        <button class=\"lang-option\" data-lang=\"en\" id=\"langEn\">EN</button>\n        <button class=\"lang-option active\" data-lang=\"cn\" id=\"langCn\">CN</button>\n    </div>\n\n    <div class=\"toolbar-divider\"></div>\n\n    <!-- 1. Present -->\n    <button class=\"chrome-btn present-toggle\" id=\"presentToggle\" aria-label=\"Present (F5)\" title=\"Present (F5)\">\n        <svg width=\"14\" height=\"14\" viewBox=\"0 0 16 16\" fill=\"currentColor\">\n            <path d=\"M4 2l10 6-10 6V2z\"/>\n        </svg>\n    </button>\n\n    <div class=\"toolbar-divider\"></div>\n\n    <!-- 2. Zoom -->\n    <div class=\"zoom-controls\" id=\"zoomControls\">\n        <button class=\"zoom-btn\" id=\"zoomOut\" aria-label=\"Zoom out\">&minus;</button>\n        <span class=\"zoom-level\" id=\"zoomLevel\">100%</span>\n        <button class=\"zoom-btn\" id=\"zoomIn\" aria-label=\"Zoom in\">+</button>\n    </div>\n\n    <div class=\"toolbar-divider\"></div>\n\n    <!-- 3. Edit + undo/redo -->\n    <button class=\"chrome-btn edit-toggle\" id=\"editToggle\" aria-label=\"Toggle text editing (E)\" title=\"Edit text (E)\">\n        <svg width=\"14\" height=\"14\" viewBox=\"0 0 16 16\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\">\n            <path d=\"M11.5 1.5l3 3L5 14H2v-3L11.5 1.5z\"/>\n        </svg>\n    </button>\n    <div class=\"edit-history\" id=\"editHistory\">\n        <button class=\"edit-history-btn\" id=\"editUndo\" aria-label=\"Undo\" disabled>&#8630;</button>\n        <button class=\"edit-history-btn\" id=\"editRedo\" aria-label=\"Redo\" disabled>&#8631;</button>\n    </div>\n\n    <div class=\"toolbar-divider\"></div>\n\n    <!-- 4. Comment -->\n    <button class=\"chrome-btn comment-toggle\" id=\"commentToggle\" aria-label=\"Toggle comments\" title=\"Toggle comments (C)\">\n        <svg width=\"18\" height=\"18\" viewBox=\"0 0 18 18\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n            <path d=\"M2 3h14v10H6l-4 3V3z\"/>\n        </svg>\n    </button>\n</div>\n```\n\n#### Chrome Toolbar CSS\n\n```css\n/* === HORIZONTAL TOOLBAR — top right === */\n.chrome-toolbar {\n    position: fixed;\n    top: clamp(0.6rem, 1.5vh, 1rem);\n    right: clamp(0.5rem, 1.5vw, 1rem);\n    z-index: 1001;\n    display: flex;\n    align-items: center;\n    gap: 4px;\n    background: rgba(255, 255, 255, 0.85);\n    backdrop-filter: blur(8px);\n    border-radius: 8px;\n    padding: 4px 6px;\n    box-shadow: 0 1px 4px rgba(0,0,0,0.08);\n    transition: right var(--panel-transition);\n}\n\n/* When comment panel is open, shift toolbar left */\nbody.comments-open .chrome-toolbar {\n    right: calc(var(--comment-panel-width) + clamp(0.5rem, 1.5vw, 1rem));\n}\n\nbody.present-mode .chrome-toolbar { display: none; }\n\n.toolbar-divider {\n    width: 1px; height: 18px;\n    background: var(--border-subtle);\n    flex-shrink: 0;\n}\n\n/* Chrome buttons (present, edit, comment) */\n.chrome-btn {\n    width: 32px; height: 32px;\n    border: none; border-radius: 6px; cursor: pointer;\n    background: transparent;\n    color: var(--text-secondary);\n    display: flex; align-items: center; justify-content: center;\n    transition: background 0.2s, color 0.2s;\n}\n.chrome-btn:hover {\n    background: var(--bg-card-hover);\n    color: var(--text-primary);\n}\n.chrome-btn.active {\n    background: var(--accent);\n    color: #fff;\n}\n\n/* Zoom controls (inline in toolbar) */\n.zoom-controls {\n    display: flex; align-items: center; gap: 2px;\n}\n.zoom-btn {\n    width: 28px; height: 28px;\n    border: none; border-radius: 4px; cursor: pointer;\n    background: transparent;\n    font-size: 16px; font-weight: 600;\n    color: var(--text-secondary);\n    display: flex; align-items: center; justify-content: center;\n    transition: background 0.2s, color 0.2s;\n}\n.zoom-btn:hover {\n    background: var(--bg-card-hover);\n    color: var(--text-primary);\n}\n.zoom-level {\n    font-size: var(--small-size);\n    font-family: var(--font-mono);\n    color: var(--text-secondary);\n    min-width: 3.2em; text-align: center;\n    user-select: none;\n}\n\n/* Edit history (visible only when edit mode active) */\n.edit-history {\n    display: none;\n    align-items: center; gap: 2px;\n}\nbody.edit-active .edit-history { display: flex; }\n\n.edit-history-btn {\n    width: 26px; height: 26px;\n    border: none; border-radius: 4px; cursor: pointer;\n    background: transparent;\n    font-size: 14px; color: var(--text-secondary);\n    display: flex; align-items: center; justify-content: center;\n}\n.edit-history-btn:hover:not(:disabled) {\n    background: var(--bg-card-hover);\n    color: var(--text-primary);\n}\n.edit-history-btn:disabled { opacity: 0.3; cursor: default; }\n\n/* === LANGUAGE SWITCH (bilingual presentations only) === */\n.lang-switch {\n    display: flex;\n    border-radius: 6px;\n    overflow: hidden;\n    border: 1px solid var(--border-subtle, #e0e0e0);\n    height: 28px;\n}\n.lang-option {\n    padding: 0 10px;\n    height: 100%;\n    border: none;\n    background: transparent;\n    font-size: 12px; font-weight: 600;\n    font-family: var(--font-mono);\n    cursor: pointer;\n    color: var(--text-secondary);\n    transition: background 0.2s, color 0.2s;\n    line-height: 28px;\n}\n.lang-option.active {\n    background: var(--accent);\n    color: #fff;\n}\n.lang-option:hover:not(.active) {\n    background: var(--bg-card-hover, #f5f5f5);\n}\n\n/* === BILINGUAL CONTENT SWITCHING === */\nbody.lang-en .lang-cn { display: none; }\nbody.lang-cn .lang-en { display: none; }\n```\n\n---\n\n### Comment Panel\n\nThe comment panel HTML remains separate from the toolbar. The toolbar's comment button toggles it.\n\n```html\n<aside class=\"comment-panel\" id=\"commentPanel\" aria-label=\"Slide comments\">\n    <div class=\"comment-panel-header\">\n        <div class=\"comment-panel-title\">\n            <span class=\"comment-slide-label\" id=\"commentSlideLabel\"></span>\n            <span class=\"comment-slide-name\" id=\"commentSlideName\"></span>\n        </div>\n        <div style=\"display: flex; gap: 0.3rem; flex-shrink: 0;\">\n            <button class=\"comment-copy-all comment-clear-all\" id=\"commentClearAll\" title=\"Clear all comments\">\n                <svg width=\"14\" height=\"14\" viewBox=\"0 0 14 14\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n                    <path d=\"M2 4h10M5 4V2h4v2M3 4v8a1 1 0 001 1h6a1 1 0 001-1V4\"/>\n                </svg>\n                Clear All\n            </button>\n            <button class=\"comment-copy-all\" id=\"commentCopyAll\" title=\"Copy all comments to clipboard\">\n                <svg width=\"14\" height=\"14\" viewBox=\"0 0 14 14\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n                    <rect x=\"4\" y=\"4\" width=\"9\" height=\"9\" rx=\"1\"/>\n                    <path d=\"M1 10V2a1 1 0 011-1h8\"/>\n                </svg>\n                Copy All\n            </button>\n        </div>\n    </div>\n    <textarea class=\"comment-textarea\" id=\"commentTextarea\" placeholder=\"Add notes for this slide...\"></textarea>\n    <div class=\"comment-status\" id=\"commentStatus\"></div>\n</aside>\n```\n\n---\n\n## Chrome CSS Summary\n\nAll chrome CSS uses only CSS custom properties — brand-agnostic by design. Key structural rules:\n\n| Element | Positioning | Key CSS |\n|---------|-------------|---------|\n| **Sidebar** | Fixed left, `width: var(--sidebar-width)` | `z-index: 1000`, white bg, transition via `transform` |\n| **Sidebar toggle** | Fixed, `left: calc(var(--sidebar-width) + 4px)` | Sits just outside sidebar right edge, follows sidebar |\n| **Progress bar** | Fixed top, `left: var(--sidebar-width)` to `right: 0` | Only covers slide area, never overlaps sidebar |\n| **Chrome toolbar** | Fixed top-right, horizontal flex | Contains: lang → present → zoom → edit → comment |\n| **Comment panel** | Fixed right, slides out from off-screen | `z-index: 1000`, pushes toolbar left when open |\n\n### Body State Classes\n\n| Class | Effect |\n|-------|--------|\n| `body.lang-cn` | Shows `.lang-cn` spans, hides `.lang-en` spans (default for bilingual) |\n| `body.lang-en` | Shows `.lang-en` spans, hides `.lang-cn` spans |\n| `body.sidebar-hidden` | Sidebar translateX(-100%), toggle snaps to left:6px, progress bar left:0 |\n| `body.comments-open` | Comment panel visible, toolbar shifts right by panel width |\n| `body.edit-active` | Edit history buttons appear in toolbar, contentEditable enabled |\n| `body.present-mode` | Hides ALL chrome (sidebar, toggle, toolbar, progress bar, comment panel) |\n\nFile v1.0.0:skill-card.md\n\n## Description:\n\nCreates interactive, self-contained HTML slide decks with sidebar navigation, comments, zoom controls, inline editing, present mode, bilingual support, and configurable brand presets.\n\nThis skill is ready for commercial/non-commercial use.\n\n## Publisher:\n\n[edsml-yl10823](https://clawhub.ai/user/edsml-yl10823)\n\n### License/Terms of Use:\n\nMIT-0\n\n## Use Case:\n\nDevelopers and business users use this skill to create or enhance browser-based presentation decks for periodic updates, product reviews, roadmap discussions, retrospectives, quarterly business reviews, and training material.\n\n### Deployment Geography for Use:\n\nGlobal\n\n## Known Risks and Mitigations:\n\nRisk: Generated decks may include external font links.\n\nMitigation: Review the final HTML before sharing or deployment, and replace remote font links with approved local assets when required.\n\nRisk: The skill may rely on prior presentation files for copied logos or JavaScript.\n\nMitigation: Confirm the source and permissions for any reused presentation, logo, or script before publishing generated slides.\n\nRisk: Corporate or confidential material may be exposed through brand assets or deck content.\n\nMitigation: Prefer the Neutral preset or provide explicit trusted asset paths when handling confidential corporate material.\n\n## Reference(s):\n\n- [Reusable Components](artifact/references/components.md)\n- [Design Tokens](artifact/references/design-tokens.md)\n- [JS Controller - SlidePresentation Class](artifact/references/js-controller.md)\n- [Slide Types](artifact/references/slide-types.md)\n- [Viewport Fitting and Interactive Chrome](artifact/references/viewport-chrome.md)\n- [ClawHub skill page](https://clawhub.ai/edsml-yl10823/skills/html-slides)\n\n## Skill Output:\n\n**Output Type(s):** [Code, Files, Markdown, Guidance]\n\n**Output Format:** [Self-contained HTML files with inline CSS and JavaScript, plus concise Markdown delivery notes]\n\n**Output Parameters:** [1D]\n\n**Other Properties Related to Output:** [Generated decks may include bilingual English/Chinese text, embedded or referenced brand assets, browser-side interaction controls, and localStorage-backed comments.]\n\n## Skill Version(s):\n\n1.0.0 (source: server release metadata and changelog)\n\n## Ethical Considerations:\n\nUsers should evaluate whether this skill is appropriate for their environment, review any generated or modified files before relying on them, and apply their organization's safety, security, and compliance requirements before deployment.","readmeExcerpt":"Skill: html-based slides Owner: edsml-yl10823 Summary: Create interactive, self-contained HTML slide decks with sidebar navigation, comment panel, zoom controls, inline editing, and present mode. Default brand is... Tags: latest:1.0.0 Version history: v1.0.0 | 2026-04-15T07:54:46.314Z | user - Initial release of corporate-slides version 1.0.0. - Create interactive, self-contained HTML slide decks with built-in sideba","codeSnippets":[],"executableExamples":[{"language":"text","snippet":"<!DOCTYPE html>\n<html lang=\"zh\">\n<head>\n    <!-- Google Fonts (based on brand preset) -->\n    <style>\n        /* 1. CSS Custom Properties (from design-tokens.md — brand-resolved) */\n        /* 2. Reset & Base Typography */\n        /* 3. Viewport Fitting (MANDATORY — from viewport-chrome.md) */\n        /* 4. Language Toggle (bilingual only — from viewport-chrome.md) */\n        /* 5. Sidebar Navigation */\n        /* 6. Progress Bar */\n        /* 7. Comment Panel */\n        /* 8. Zoom Controls */\n        /* 9. Slide Type Styles (cover, section, content, closing) */\n        /* 10. Component Styles */\n        /* 11. Edit Mode */\n        /* 12. Present Mode */\n        /* 13. Responsive Breakpoints */\n        /* 14. Embedded Logos (if applicable) */\n    </style>\n</head>\n<body class=\"lang-cn\">\n    <!-- Chrome: sidebar + toggle (left), progress bar (top, slide area only), horizontal toolbar (top-right: lang→present→zoom→edit→comment), comment panel (right) -->\n    <!-- SLIDES (each is a <section class=\"slide\">) with lang-en/lang-cn spans -->\n    <!-- JS: SlidePresentation class -->\n</body>\n</html>"},{"language":"html","snippet":"<h2>\n    <span class=\"lang-en\">Architecture Overview</span>\n    <span class=\"lang-cn\">架构概览</span>\n</h2>\n<p>\n    <span class=\"lang-en\">Smart acts as a Package Registry.</span>\n    <span class=\"lang-cn\">Smart 作为 Package Registry。</span>\n</p>"},{"language":"css","snippet":"body.lang-en .lang-cn { display: none; }\nbody.lang-cn .lang-en { display: none; }"},{"language":"html","snippet":"<div class=\"metrics-grid reveal\">\n    <div class=\"metric-card\">\n        <span class=\"metric-label\">Label</span>\n        <span class=\"metric-value\">7,800+</span>\n        <span class=\"metric-change positive\">+12.5% vs last period</span>\n    </div>\n    <div class=\"metric-card\">\n        <span class=\"metric-label\">Label</span>\n        <span class=\"metric-value\">3,200+</span>\n        <span class=\"metric-change negative\">-8.3% vs target</span>\n    </div>\n    <div class=\"metric-card\">\n        <span class=\"metric-label\">Label</span>\n        <span class=\"metric-value\">34%</span>\n        <span class=\"metric-change neutral\">Stable</span>\n    </div>\n</div>"},{"language":"css","snippet":".metrics-grid {\n    display: grid; grid-template-columns: repeat(3, 1fr);\n    gap: clamp(8px, 1.2vw, 16px); width: 100%;\n}\n.metric-card {\n    background: var(--bg-secondary);\n    border-radius: clamp(6px, 0.8vw, 12px);\n    padding: clamp(10px, 1.5vh, 20px) clamp(10px, 1.2vw, 18px);\n    display: flex; flex-direction: column; gap: clamp(3px, 0.5vh, 8px);\n    border-left: 3px solid var(--accent);\n    transition: transform 0.2s ease, box-shadow 0.2s ease;\n}\n.metric-card:hover { transform: translateY(-2px); box-shadow: 0 4px 16px rgba(0,0,0,0.06); }\n.metric-label { font-family: var(--font-body); font-size: var(--small-size); color: var(--text-muted); text-transform: uppercase; letter-spacing: 0.05em; font-weight: 600; }\n.metric-value { font-family: var(--font-display); font-size: var(--cta-size); font-weight: 900; color: var(--color-heading); line-height: 1; }\n.metric-change { font-family: var(--font-body); font-size: var(--small-size); font-weight: 600; }\n.metric-change.positive { color: #16803c; }\n.metric-change.negative { color: #dc2626; }\n.metric-change.neutral { color: var(--text-muted); }"},{"language":"html","snippet":"<div class=\"comparison-grid reveal\">\n    <div class=\"comparison-table-wrap\">\n        <div class=\"comparison-table-caption\">Comparison Table</div>\n        <table class=\"comparison-table\">\n            <thead>\n                <tr>\n                    <th>Section</th><th>Metric</th>\n                    <th class=\"num\">Period 1</th><th class=\"num\">Period 2</th>\n                    <th class=\"num\">&Delta;</th>\n                </tr>\n            </thead>\n            <tbody>\n                <tr>\n                    <td class=\"section-cell\" rowspan=\"2\">Group A</td>\n                    <td>Metric 1</td>\n                    <td class=\"num\">2,121</td><td class=\"num\">2,349</td>\n                    <td class=\"num delta-pos\">+10.7%</td>\n                </tr>\n                <tr>\n                    <td>Metric 2</td>\n                    <td class=\"num\">65,219</td><td class=\"num\">74,826</td>\n                    <td class=\"num delta-pos\">+14.7%</td>\n                </tr>\n                <tr class=\"section-divider\">\n                    <td class=\"section-cell\" rowspan=\"2\">Group B</td>\n                    <td>Metric 3</td>\n                    <td class=\"num\">1,253,158</td><td class=\"num\">993,785</td>\n                    <td class=\"num delta-neg\">&minus;20.7%</td>\n                </tr>\n                <tr>\n                    <td class=\"indent\">Sub-metric</td>\n                    <td class=\"num\">222,879</td><td class=\"num\">261,876</td>\n                    <td class=\"num delta-pos\">+17.5%</td>\n                </tr>\n            </tbody>\n        </table>\n        <div class=\"comparison-source\">Source: ...</div>\n    </div>\n    <div class=\"comparison-insights\">\n        <div class=\"insight-card\">\n            <span class=\"insight-num\">01 &middot; Theme</span>\n            <span class=\"insight-title\">Key Insight Headline</span>\n            <p class=\"insight-body\">Narrative with <span class=\"pos\">+10.7%</span> inline.</p>\n        </div>\n        <!-- Up to 3 insight cards -->\n    </div>\n</div>"}],"parameters":null,"dependencies":[],"permissions":[],"extractedFiles":[{"path":"SKILL.md","content":"---\nname: corporate-slides\ndescription: Create interactive, self-contained HTML slide decks with sidebar navigation, comment panel, zoom controls, inline editing, and present mode. Default brand is Shopee/Sea but supports custom brand presets. Use when the user says \"做slides\"、\"create slides\"、\"创建幻灯片\"、\"做PPT\"、\"做汇报\"、\"bi-weekly\"、\"biweekly\"、\"双周汇报\"、\"quarterly review\"、\"product review\"、\"roadmap presentation\"、\"strategy deck\"、\"post-mortem slides\", or any request to create a presentation deck.\n---\n\n# Corporate Slides\n\nCreate zero-dependency, interactive HTML presentations that run in any browser. Every output is a single self-contained HTML file with built-in navigation, commenting, editing, and presentation capabilities.\n\n## Core Principles\n\n1. **Zero Dependencies** — Single HTML file with inline CSS/JS. No npm, no build tools.\n2. **Interactive Chrome** — Left sidebar navigation (bilingual-aware), right comment panel, zoom controls, inline text editing, present mode, EN/CN language switch — all built in by default.\n3. **Viewport Fitting (NON-NEGOTIABLE)** — Every slide MUST fit exactly within 100vh. No scrolling within slides.\n4. **Brand-Configurable** — Default brand is Shopee/Sea. User can select a different brand preset or define custom colors/fonts. The design token system makes this a single-point swap.\n5. **Content-Driven** — Slides are built around data, comparisons, timelines, and action items — not filler graphics.\n6. **Bilingual by Default** — Unless user specifies a single language, generate **both EN and CN** content for every text element with an EN/CN toggle in the toolbar. If user explicitly requests a single language, skip the toggle and generate monolingual content.\n\n---\n\n## Phase 0: Detect Mode\n\n- **Mode A: New Presentation** — Create from scratch. Go to Phase 1.\n- **Mode B: Enhancement** — Modify an existing HTML slide deck. Read it first, understand its brand/style, then modify. When adding content, check density limits; split slides if overflow would occur.\n\n---\n\n## Phase 1: Content Discovery\n\n**Ask ALL questions in a single call:**\n\n**Question 1 — Purpose** (header: \"Purpose\"):\nWhat is this presentation for? Options:\n- Bi-weekly / periodic update\n- Product review / feature walkthrough\n- Roadmap / strategy deck\n- Post-mortem / retrospective\n- Quarterly business review\n- Training / onboarding\n- Other (describe)\n\n**Question 2 — Brand** (header: \"Brand\"):\nWhich brand preset? Options:\n- Shopee / Sea (default — orange + navy)\n- Custom (I'll provide colors/fonts)\n- Neutral / Minimal (dark charcoal + blue accent, no logos)\n\n**Question 3 — Content** (header: \"Content\"):\nDo you have content ready? Options:\n- All content ready (paste text, metrics, etc.)\n- Rough notes / bullet points\n- Topic only — help me structure it\n\n**Question 4 — Length** (header: \"Length\"):\nApproximately how many slides? Options: Short 5-8 / Medium 8-14 / Long 14+\n\n**Question 5 — Interactive Features** (header: \"Features\"):\nWhich interactive features to include? Options:\n- "},{"path":"_meta.json","content":"{\n  \"ownerId\": \"kn7embg2epew9fdvnh29tq4sws844k82\",\n  \"slug\": \"html-slides\",\n  \"version\": \"1.0.0\",\n  \"publishedAt\": 1776239686314\n}"},{"path":"references/components.md","content":"# Reusable Components\n\nThese components are placed inside `.slide-content` of Content Slides. Always add `class=\"reveal\"` to the component wrapper for entrance animation.\n\nAll components use CSS custom properties for colors, so they automatically adapt to any brand preset.\n\n---\n\n## 1. Metrics Grid\n\n3-column KPI cards with label, large value, and change indicator. Great for dashboards, status updates, quarterly metrics.\n\n```html\n<div class=\"metrics-grid reveal\">\n    <div class=\"metric-card\">\n        <span class=\"metric-label\">Label</span>\n        <span class=\"metric-value\">7,800+</span>\n        <span class=\"metric-change positive\">+12.5% vs last period</span>\n    </div>\n    <div class=\"metric-card\">\n        <span class=\"metric-label\">Label</span>\n        <span class=\"metric-value\">3,200+</span>\n        <span class=\"metric-change negative\">-8.3% vs target</span>\n    </div>\n    <div class=\"metric-card\">\n        <span class=\"metric-label\">Label</span>\n        <span class=\"metric-value\">34%</span>\n        <span class=\"metric-change neutral\">Stable</span>\n    </div>\n</div>\n```\n\n### CSS\n\n```css\n.metrics-grid {\n    display: grid; grid-template-columns: repeat(3, 1fr);\n    gap: clamp(8px, 1.2vw, 16px); width: 100%;\n}\n.metric-card {\n    background: var(--bg-secondary);\n    border-radius: clamp(6px, 0.8vw, 12px);\n    padding: clamp(10px, 1.5vh, 20px) clamp(10px, 1.2vw, 18px);\n    display: flex; flex-direction: column; gap: clamp(3px, 0.5vh, 8px);\n    border-left: 3px solid var(--accent);\n    transition: transform 0.2s ease, box-shadow 0.2s ease;\n}\n.metric-card:hover { transform: translateY(-2px); box-shadow: 0 4px 16px rgba(0,0,0,0.06); }\n.metric-label { font-family: var(--font-body); font-size: var(--small-size); color: var(--text-muted); text-transform: uppercase; letter-spacing: 0.05em; font-weight: 600; }\n.metric-value { font-family: var(--font-display); font-size: var(--cta-size); font-weight: 900; color: var(--color-heading); line-height: 1; }\n.metric-change { font-family: var(--font-body); font-size: var(--small-size); font-weight: 600; }\n.metric-change.positive { color: #16803c; }\n.metric-change.negative { color: #dc2626; }\n.metric-change.neutral { color: var(--text-muted); }\n```\n\n---\n\n## 2. Comparison Table with Insights\n\n2-column layout: left is a comparison table, right is insight cards. Best for period-over-period metrics, bi-weekly/quarterly comparisons.\n\n```html\n<div class=\"comparison-grid reveal\">\n    <div class=\"comparison-table-wrap\">\n        <div class=\"comparison-table-caption\">Comparison Table</div>\n        <table class=\"comparison-table\">\n            <thead>\n                <tr>\n                    <th>Section</th><th>Metric</th>\n                    <th class=\"num\">Period 1</th><th class=\"num\">Period 2</th>\n                    <th class=\"num\">&Delta;</th>\n                </tr>\n            </thead>\n            <tbody>\n                <tr>\n                    <td class=\"section-cell\" rowspan=\"2\">Group A</td>\n                    <td>Metric"},{"path":"references/design-tokens.md","content":"# Design Tokens\n\nThis file defines the CSS custom property system. Select a brand preset and copy the corresponding `:root` block into the presentation.\n\n---\n\n## Brand Presets\n\n### Preset: Shopee / Sea (DEFAULT)\n\n```html\n<link rel=\"preconnect\" href=\"https://fonts.googleapis.com\">\n<link rel=\"preconnect\" href=\"https://fonts.gstatic.com\" crossorigin>\n<link href=\"https://fonts.googleapis.com/css2?family=Lato:wght@300;400;700;900&family=Open+Sans:wght@300;400;500;600;700&family=Roboto+Mono:wght@400;500;600&display=swap\" rel=\"stylesheet\">\n```\n\n```css\n:root {\n    /* Colors — Shopee Corporate */\n    --accent-primary: #ee4d2d;\n    --accent-secondary: #05007E;\n    --color-heading: #05007E;\n    --accent: #ee4d2d;\n    --accent-glow: rgba(238, 77, 45, 0.3);\n    --bg-primary: #ffffff;\n    --bg-secondary: #f7f8fa;\n    --bg-card: #f7f8fa;\n    --bg-card-hover: #f0f1f5;\n    --text-primary: #1a1a1a;\n    --text-secondary: #5a5f6b;\n    --text-muted: #999999;\n    --text-on-accent: #ffffff;\n    --border-subtle: rgba(0,0,0,0.06);\n    --border-card: #eee;\n\n    /* Typography */\n    --font-display: 'Lato', sans-serif;\n    --font-body: 'Open Sans', sans-serif;\n    --font-mono: 'Roboto Mono', monospace;\n\n    /* Brand Config */\n    --brand-has-logo: 1; /* 1 = show logo elements, 0 = hide */\n    --section-bg: #05007E; /* section divider background */\n}\n```\n\n**Logos (MANDATORY — both Shopee AND SeaMoney):** Embed via CSS `content: url(data:image/png;base64,...)` targeting `img.brand-logo.shopee` and `img.brand-logo.seamoney`. Both logos MUST appear on cover slides, section dividers, content headers, and closing slides. Copy the actual base64 data from the most recent presentation file.\n\n```css\nimg.brand-logo.shopee { content: url(data:image/png;base64,...SHOPEE_LOGO_DATA...); }\nimg.brand-logo.seamoney { content: url(data:image/png;base64,...SEAMONEY_LOGO_DATA...); }\n```\n\nHTML pattern: `<img src=\"data:,\" class=\"brand-logo shopee\" alt=\"Shopee\">` and `<img src=\"data:,\" class=\"brand-logo seamoney\" alt=\"SeaMoney\">`.\n\n---\n\n### Preset: Neutral / Minimal\n\n```html\n<link href=\"https://fonts.googleapis.com/css2?family=DM+Sans:wght@400;500;700;800&family=Inter:wght@300;400;500;600;700&family=JetBrains+Mono:wght@400;500;600&display=swap\" rel=\"stylesheet\">\n```\n\n```css\n:root {\n    /* Colors — Neutral Corporate */\n    --accent-primary: #2563eb;\n    --accent-secondary: #1e293b;\n    --color-heading: #1e293b;\n    --accent: #2563eb;\n    --accent-glow: rgba(37, 99, 235, 0.2);\n    --bg-primary: #ffffff;\n    --bg-secondary: #f8fafc;\n    --bg-card: #f8fafc;\n    --bg-card-hover: #f1f5f9;\n    --text-primary: #0f172a;\n    --text-secondary: #475569;\n    --text-muted: #94a3b8;\n    --text-on-accent: #ffffff;\n    --border-subtle: rgba(0,0,0,0.06);\n    --border-card: #e2e8f0;\n\n    /* Typography */\n    --font-display: 'DM Sans', sans-serif;\n    --font-body: 'Inter', sans-serif;\n    --font-mono: 'JetBrains Mono', monospace;\n\n    /* Brand Config */\n    --brand-has-logo: 0;\n    --section-bg: #1e293b;\n}\n```\n\n**Log"},{"path":"references/js-controller.md","content":"# JS Controller — SlidePresentation Class\n\nCopy this complete `<script>` block at the end of `<body>`. The class is fully brand-agnostic — it reads from DOM elements and CSS properties only.\n\n## Features\n\n| Feature | Trigger | Description |\n|---------|---------|-------------|\n| Language switch | Click EN or CN segment, or press `L` | Switches `body.lang-cn` ↔ `body.lang-en`, updates sidebar text, persisted to localStorage |\n| Sidebar auto-build | On load | Reads `data-title` (CN) and `data-title-en` from slides; `data-group` (CN) and `data-group-en` for group headers |\n| Slide visibility | Intersection observer | Adds `.visible` class at 50% threshold (triggers reveal animations) |\n| Keyboard nav | Arrow keys, Space, PageUp/Down, Home/End | Smooth scroll between slides |\n| Touch/swipe | Vertical swipe >50px | Mobile-friendly navigation |\n| Mouse wheel | With 800ms debounce | Scroll one slide at a time |\n| Sidebar click | Click any sidebar item | Jump to slide |\n| Progress bar | Auto-update | Top bar width = % of slides viewed |\n| Page numbers | On load | `N / Total` rendered in each `.page-number` |\n| Sidebar toggle | Click hamburger | Toggles `body.sidebar-hidden` |\n| Comment panel | Press `C` or click icon | Per-slide notes, localStorage persistence, Copy All, Clear All |\n| Zoom | +/- buttons | 70%–150%, step 10%, applies CSS `zoom` to `.slide-content` |\n| Inline edit | Press `E` or click pencil | contentEditable on text elements, undo/redo history |\n| Present mode | Press `F5` or click play | fullscreen, hides all chrome |\n\n## Complete Script\n\n**IMPORTANT:** Always copy the full ~600-line JS implementation from the most recent source presentation. The stub below shows the class structure.\n\n```javascript\nclass SlidePresentation {\n    constructor() {\n        this.slides = document.querySelectorAll('.slide');\n        this.currentSlide = 0;\n        this.isScrolling = false;\n        this.scrollTimeout = null;\n\n        // Language switch (bilingual only — skipped if #langSwitch absent)\n        this.setupLanguageToggle();\n\n        this.setupPageNumbers();\n        this.buildSidebar();\n        this.setupIntersectionObserver();\n        this.setupKeyboardNav();\n        this.setupTouchNav();\n        this.setupProgressBar();\n        this.setupWheelNav();\n        this.setupSidebarNav();\n\n        this.sidebarVisible = true;\n        this.setupSidebarToggle();\n\n        // Comment panel\n        this.commentPanel = document.getElementById('commentPanel');\n        this.commentTextarea = document.getElementById('commentTextarea');\n        this.commentSlideLabel = document.getElementById('commentSlideLabel');\n        this.commentSlideName = document.getElementById('commentSlideName');\n        this.commentCopyAllBtn = document.getElementById('commentCopyAll');\n        this.commentStatus = document.getElementById('commentStatus');\n        this.commentsOpen = false;\n        this.comments = this.loadComments();\n        this.slideNames = Array.from(this.slides).map(\n   "}],"languages":[],"docsSourceLabel":"CLAWHUB","editorialOverview":"Create interactive, self-contained HTML slide decks with sidebar navigation, comment panel, zoom controls, inline editing, and present mode. Default brand is... Skill: html-based slides Owner: edsml-yl10823 Summary: Create interactive, self-contained HTML slide decks with sidebar navigation, comment panel, zoom controls, inline editing, and present mode. Default brand is... Tags: latest:1.0.0 Version history: v1.0.0 | 2026-04-15T07:54:46.314Z | user - Initial release of corporate-slides version 1.0.0. - Create interactive, self-contained HTML slide decks with built-in sideba","editorialQuality":{"score":100,"threshold":65,"status":"ready","wordCount":1351,"uniquenessScore":50,"reasons":[]}},"media":{"evidence":{"source":"no-media","verified":false,"confidence":"low","updatedAt":"2026-10-11T23:43:37.321Z","emptyReason":"No screenshots, media assets, or demo links are available."},"primaryImageUrl":null,"mediaAssetCount":0,"assets":[],"demoUrl":null},"ownerResources":{"evidence":{"source":"unclaimed","verified":false,"confidence":"low","updatedAt":"2026-10-11T23:43:37.321Z","emptyReason":"This page has not been claimed by the agent owner."},"hasCustomPage":false,"customPageUpdatedAt":null,"customLinks":[],"structuredLinks":{"docsUrl":null,"demoUrl":null,"supportUrl":null,"pricingUrl":null,"statusUrl":null},"customPage":null},"relatedAgents":{"evidence":{"source":"protocol-neighbors","verified":false,"confidence":"medium","updatedAt":"2026-10-12T21:27:47.265Z","emptyReason":null},"items":[{"id":"8ebccd8e-3863-4187-8355-c3f14e1f9edf","entityType":"agent","canonicalPath":"/agent/iofficeai-aionui","slug":"iofficeai-aionui","name":"AionUi","description":"Free, local, open-source 24/7 Cowork app and OpenClaw for Gemini CLI, Claude Code, Codex, OpenCode, Qwen Code, Goose CLI, Auggie, and more | 🌟 Star if you like it!","url":"https://github.com/iOfficeAI/AionUi","homepage":"https://www.aionui.com","source":"GITHUB_REPOS","protocols":["MCP","OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-10-09T19:11:12.944Z","createdAt":"2026-02-25T03:38:16.584Z","downloads":null},{"id":"b917f68a-ebff-438e-84f8-3f4b2494c0bc","entityType":"agent","canonicalPath":"/agent/activepieces-activepieces","slug":"activepieces-activepieces","name":"activepieces","description":"AI Agents & MCPs & AI Workflow Automation • (~400 MCP servers for AI agents) • AI Automation / AI Agent with MCPs • AI Workflows & AI Agents • MCPs for AI Agents","url":"https://github.com/activepieces/activepieces","homepage":"https://www.activepieces.com","source":"GITHUB_REPOS","protocols":["OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-04-15T02:22:12.426Z","createdAt":"2026-02-25T03:38:12.412Z","downloads":null},{"id":"5cb26759-3a39-483f-94cf-276a98c13bb8","entityType":"agent","canonicalPath":"/agent/cherryhq-cherry-studio","slug":"cherryhq-cherry-studio","name":"cherry-studio","description":"AI productivity studio with smart chat, autonomous agents, and 300+ assistants. Unified access to frontier LLMs","url":"https://github.com/CherryHQ/cherry-studio","homepage":"https://cherry-ai.com","source":"GITHUB_REPOS","protocols":["MCP","OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-04-11T14:38:40.986Z","createdAt":"2026-02-25T03:38:19.379Z","downloads":null},{"id":"6f6582d0-5d76-4f0f-b81d-86520247950b","entityType":"agent","canonicalPath":"/agent/copilotkit-copilotkit","slug":"copilotkit-copilotkit","name":"CopilotKit","description":"The Frontend for Agents & Generative UI. React + Angular","url":"https://github.com/CopilotKit/CopilotKit","homepage":"https://docs.copilotkit.ai","source":"GITHUB_REPOS","protocols":["OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-03-25T09:50:57.846Z","createdAt":"2026-02-25T03:39:14.617Z","downloads":null}],"links":{"hub":"/agent","source":"/agent/source/clawhub","protocols":[{"label":"OpenClaw","href":"/agent/protocol/openclew"}]}}}