CMS logo CERN logo PKU logo

Frontend Slides PKU
AI-Driven Academic Presentations

A Vibe Coding Approach to Stunning Slides

Leyan Li1

1 Peking University (CN)

May 7th 2026

Repo: https://github.com/ky230/frontend-slides-PKU

  • Introduction
  • Built-in Elements
  • Web Hosting
  • Summary
📁 ky230 — -zsh — 70x20
$ python3 init-slides.py \  --logos PKU_logo.jpeg CMS_logo.png CERN_logo.png \  --title "Frontend Slides PKU Documentation" \  --subtitle "Technical Tutorial" \  --author "Leyan Li:1" \  --speaker "Leyan Li" \  --affiliations "Peking University (CN)" \  --date "May 7th 2026" \  --event "PKU-CMS Group Meeting" \  --highlight "Frontend Slides" "PKU" \  --skin voltage \  --outline "Introduction:2" "Built-in Elements:3" \    "Web Hosting:3" "Summary:2" \  --out frontend_slides_intro.html ✅ Slide harness created successfully   Total slides: 17   Skin: voltage   Logos: PKU_logo.jpeg, CMS_logo.png, CERN_logo.png   Outline sections: 4     1. Introduction (2 pages)     2. Built-in Elements (3 pages)     3. Web Hosting (3 pages)     4. Summary (2 pages) $ 
Introduction
  • Origin — Forked from @zarazhangrui/frontend-slides (aesthetic HTML slide maker), re-engineered for rigorous Academic Presentations.
  • Agent Skill — Specifically designed as an AI Agent Skill (compatible with VSCode, Claude Code, Gemini, Copilot).
  • Scaffold Harness — Uses init-slides.py to generate a fixed 1920×1080 HTML harness first, preventing LLM structural instability from breaking the layout.
  • Context-Aware — Provide your Analysis Note (AN), codebase, or images directly, and let the AI assemble the slides natively.
  • Built-in Elements — Natively supports MathJax $\LaTeX$, hyperlinks, animated terminals, and syntax-highlighted code blocks.
  • Frontend Paradigm — Slides as web dev. For models with strong frontend skills, this unlocks boundless creativity beyond predefined templates.
Traditional PPTX Pain Points:
  • Binary format: Cannot be meaningfully version-controlled via Git. Diffing changes is impossible.
  • AI Hostile: LLMs cannot natively read context from or reliably generate binary .pptx files.
  • Developer Friction: Native $\LaTeX$ math and syntax-highlighted code blocks require tedious screenshots.
  • Distribution: Every minor typo fix means re-uploading bulky files (e.g., final_v3.pptx).
Adopted by:
• CMS Pre-Approval (98 slides, HIG-25-006)
• CEPC 2026 Lisbon Workshop
• CERN Test Beam Energy Sharing reports
Zero dependencies: One single HTML file — no Node.js, no framework, just open in any browser.
  • Skill Definition (Master Controller)hep-frontend-slides.md is the core entry point. It instructs the AI on the repository's Iron Rules and how to execute all Python/Bash scripts and CLI arguments. Users don't need to learn any of these commands—simply interact in natural language and let the AI drive the pipeline.
  • Reference Docsreference/ contains the core spec, 12 fine-tuning parameters, figure layouts, and skins specs for the AI to read.
  • Scripts Usage:
    • init-slides.py: Scaffold generator
    • renumber-slides.py: Sync slide markers
    • bundle-html.py: Base64 image bundling
    • export-pdf.sh: Playwright PDF export
  • Templates & Assets — Contains the empty HTML template, CSS skins, and auto-detects Logos.
📁 Hfrontend-slides-PKU — tree — 50x18
$ tree . -L 2.├── LICENSE├── README.md├── README_EN.md├── assets│   ├── logos│   ├── skins│   └── templates├── hep-frontend-slides.md # AI Skill Entry├── reference│   ├── FIGURE_LAYOUTS.md│   ├── FINE_TUNING.md│   ├── PKU_ACADEMIC_CLASSIC.md│   ├── PKU_SKINS.md│   ├── TERMINAL_BOX.md│   └── animation-patterns.md└── scripts    ├── bundle-html.py    ├── export-pdf.sh    ├── init-slides.py    └── renumber-slides.py6 directories, 14 files$ 
① Plan + Scaffold
  • AI asks Q0–Q11: logos, title, subtitle, author, speaker, affiliations, date, reference, event, outline, highlight, skin
  • Run init-slides.py
  • Generates full 1920×1080 skeleton with header/footer/progress bar
📁 python3 — init-slides.py
$ python3 init-slides.py \    --logos CMS_logo.png CERN_logo.png PKU_logo.jpeg \    --title "Frontend Slides PKU Documentation" \    --author "Leyan Li:1" \    --affiliations "Peking University" \    --date "Apr 29th 2026" \    --skin voltage \    --out frontend_slides_intro.html 📦 Reading template...🎨 Applying skin: voltage...🖼️  Injecting logos: CMS, CERN, PKU...📝 Generating 18 slides... ================================================✅ Scaffold ready: frontend_slides_intro.html (1920x1080)
② Content + Fine-tune
  • AI injects figures, tables, $\LaTeX$, and code blocks
  • Live Server auto-reloads for instant visual feedback
  • Iterate via chat: "S5 图缩小 80%, S6 补充推导"
  • Context-aware: Provide AN.tex or TWiki links
📁 HTML — fine-tuning
<!-- [Slide 6] Content: 3-Step Workflow --><section class="slide normal-slide" data-title="3-Step Workflow">     <!-- FINE TUNING:          - overall container: adjust 'margin-top' and 'padding'         - each step block: adjust 'width', 'padding', 'font-size' -->    <div class="slide-content" style="padding: 0 30px;">        <div class="reveal d1" style="display: flex; gap: 25px; margin-top: 8%;">             <!-- [ELEMENT: Step 1 — Plan + Scaffold] -->            <div style="flex: 1; border: 2px solid var(--theme-primary);">                <div style="font-size: 32px; font-weight: bold;">                    ① Plan + Scaffold</div>                <ul class="bullet-list" style="font-size: 22px;">                    <li>AI asks <strong>Q0–Q11</strong>...</li>                    <li>Run <code>init-slides.py</code></li>                </ul>            </div>             <!-- [ELEMENT: Step 2 — Content + Fine-tune] -->            <div style="flex: 1; border: 2px solid var(--theme-accent);">                <div style="font-size: 32px; font-weight: bold;">                    ② Content + Fine-tune</div>                <ul class="bullet-list">...</ul>            </div>        </div>    </div></section>
③ Bundle + PDF
  • bundle-html.py → Base64 encodes all local images
  • Output: Single self-contained HTML artifact
  • Zero broken image links when sharing via email/web
  • Optional: export-pdf.sh for offline PDF backup
📁 ky230 — -zsh — 60x4
$ python3 bundle-html.py frontend_slides_intro.html🖼️  Embedded image: attachment/Figures/S1/PKU_logo.jpeg🖼️  Embedded image: attachment/Figures/S1/CMS_logo.png... (16 more images embedded)✨ Bundle complete! Output: frontend_slides_bundle.html $ bash export-pdf.sh frontend_slides_intro.html --dpr 3 Checking dependencies...  Node.js found Setting up Playwright (headless browser)...  Local server on port 58213  Captured slide 1/18 (1 link)  Captured slide 2/18  ...  Captured slide 18/18  Assembling PDF...✓ PDF exported successfully! (frontend_slides_intro.pdf)
Built-in Elements
Element HTML Class Use
Bullet List bullet-list L1 red dot + L2 dash
Highlight highlight-accent Keyword emphasis
MathJax $...$ $E=mc^2$
Figure Grid fig fig-2x4 Multi-plot layout
Table tab Data tables
Terminal (anim) mac-terminal Typewriter effect
Terminal (static) mac-terminal-lined Code + line numbers
Hyperlink <a target=_blank> External refs
  • Primary Bullet (Level 1): Inherits theme color (Red dot).
    • Secondary Bullet (Level 2): Grey dash marker.
🔴 Highlight Box: Primary conclusions, main takeaway. Inherits --theme-primary.
🔵 Important Box: Critical assumptions, analysis caveats, methodology.
🟠 Warning Box: Non-closure issues, large systematics, problematic regions.
🟢 Tip Box: Positive results, successful validation, best practices.
  • Keyboard: F = fullscreen, G = go-to-slide, ⬆️⬇️ = navigate
📁 HTML — frontend_slides_intro.html
<!-- [Slide 9] Content: Built-in Elements --><section class="slide normal-slide" data-header="visible" data-title="Slide Structure">    <div class="slide-content reveal d1" style="margin-top: 0; padding-top: 0; padding-left: 0;">        <div class="two-col" style="gap: 30px; margin-top: 6%; align-items: stretch;">            <!-- [ELEMENT: Left — HTML Code Terminal] -->            <div class="left-col" style="padding-top: 0;">                <div class="mac-terminal"                    style="--term-accent: #f38ba8; margin-top: 0; width: 100%;">                    <div class="mac-terminal-bar">                        <span class="mac-dot mac-dot-red"></span>                        <span class="mac-dot mac-dot-yellow"></span>                        <span class="mac-dot mac-dot-green"></span>                        ...                    </div>                    <div class="mac-terminal-body mac-terminal-lined">                        ... (this terminal)                    </div>                </div>            </div>            <!-- [ELEMENT: Right — Annotations] -->            <div class="right-col" style="justify-content: flex-start; padding-top: 0;">                <ul class="bullet-list" style="margin-top: 10px; font-size: 24px;">                    <li style="margin-bottom: 10px;"><code                            style="color: var(--theme-accent);">data-header="visible"</code> — show/hide top                        red bar                    </li>                    <li><code>data-title="..."</code> — text shown in the header bar</li>                    <li><code>class="bullet-list"</code> — auto L1 red dot + L2 dash</li>                    <li><code>highlight-accent</code> — theme-color keyword</li>                </ul>                <div class="mac-terminal" style="margin-top: 10px; width: 100%;">                    <div class="mac-terminal-bar">                        ... (directory tree)                    </div>                </div>                <div class="tip-box">Attachment: ...</div>            </div>        </div>    </div></section>
  • data-header="visible" — show/hide top red bar
    • Title slides + transitions use "hidden"
  • data-title="..." — text shown in the header bar
  • class="bullet-list" — auto L1 red dot + L2 dash styling
  • style="font-size: 1.6em" — inline CSS for fine-tuning
  • highlight-accent — theme-color keyword highlight
  • width: 100% — control element width (terminal, figure, box)
  • margin-top / margin-left — position any element freely
📁 Directory — project structure
my_talk/
├── talk.html        # source
├── attachment_talk_html/
│   └── Figures/
│       ├── S1/    # title slide imgs
│       ├── S4/    # content imgs
│       ├── S5/
│       └── ...
├── talk_bundle.html  # packaged
└── talk_export.pdf   # optional
Attachment: images in attachment_{name}_html/Figures/S{N}/, bundle-html.py auto-embeds as Base64.
📁 HTML — Figure Grid (2×4)
<!-- [Slide 38] Control Plots --><section class="slide normal-slide" data-header="visible"    data-title="Prefit Control Plots - 2022postEE $e\mu$">    <div class="slide-content" style="position: relative; overflow: visible;">        <div class="reveal d1" style="position: absolute; top: 3%; left: -3.5%; width: 110%;">            <div class="fig fig-2x4" style="--gap: 10px;">                <!-- Row 1: nob -->                <img src="attachment/.../m_fastmtt_nob_lin.png">                <img src="attachment/.../met_nob_lin.png">                <img src="attachment/.../pt_1_nob_lin.png">                <img src="attachment/.../pt_2_nob_lin.png">                <!-- Row 2: btag -->                <img src="attachment/.../m_fastmtt_btag_lin.png">                <img src="attachment/.../met_btag_lin.png">                <img src="attachment/.../pt_1_btag_lin.png">                <img src="attachment/.../pt_2_btag_lin.png">            </div>        </div>    </div></section>
  • Supported grids: fig-{R}x{C} (up to 4x4, see FIGURE_LAYOUTS.md)
  • --gap: 10px — controls spacing between figures
  • width: 110% / left: -3.5% — expand figure area & center it
  • position: absolute / top: 3% — break grid for precise placement
Natural Language FINE-TUNING Protocol:
User inputs vague requests: "S5: shrink text, move table up, make image grid tighter".
AI safely translates this to precise inline CSS updates (e.g., font-size for text/tables, margin for position, --gap for figures) → Zero global CSS breakage.
Slide renumbering: After add/delete slides → run renumber-slides.py to resync <!-- [Slide N] --> markers + Figures/S{N}/ directories.
# Skin --theme-primary --theme-accent Style Preview
1 🏛️ classic #cc0000 #ffff00 PKU Red-Yellow-White (default) Preview
2 🔥 bold #ec5f18 #f3ecdb Orange cards + dark gradient Preview
3 💎 cobalt #4361ee #f6f606 Cobalt blue + bright yellow Preview
4 voltage #0066ff #d0f804 Electric blue + neon yellow Preview
5 🌺 botanical #d4a574 #cb2c64 Warm brown + magenta Preview
6 🍀 jade #2ca657 #f6f606 Jade green + bright yellow Preview
7 💜 lavender #9171a6 #f7f706 Lavender purple + lemon yellow Preview
8 🌐 cyber #2dd4bf #f4f81d Cyber teal + neon yellow Preview
9 💻 terminal #39d353 #39d353 Hacker terminal green Preview
DIY skin: cp skins/diy.css.example skins/diy.css → edit CSS variables → --skin diy
Custom logos: drop {Name}_logo.png into assets/logos/ → auto-detected by init-slides.py
Web Hosting
📁 leyan@lxplus — -bash — 80x10
# 1. Request Personal Website
# → https://webeos.cern.ch/site/new

# 2. Clone php-plots into EOS
$ cp -r php-plots/ /eos/user/l/leyan/www/slides/

# 3. Copy bundled HTML into web dir
$ cp talk_bundle.html /eos/user/l/leyan/www/slides/

# 4. Access online:
https://leyan.web.cern.ch/slides/talk_bundle.html
index.php key config:
$plot_extensions: png, pdf, jpg, gif — shown as image cards
$additional_extensions: eps, svg, root, txt — listed as downloadable files
show_entry(): hides files starting with . or _
⚠️ EOS permissions: Make sure your /eos/user/ directory has www symlink created by the webEOS service. Files must be world-readable (chmod 644).
Pro tip: The plot browser supports depth control (recursive search), pattern matching (any/all/exact modes), and drag-and-drop reordering of cards.
  • Simpler than CERN — no PHP needed, just static HTML
  • Enable in Settings → Pages → Source → main branch
  • Only for public content (no CMS internal plots!)
  • Live github.io example: ky230.github.io/Html-slides-public/
📁 ky230 — -zsh — 80x6
$ cp talk_bundle.html /path/to/pages-repo/
$ cd /path/to/pages-repo
$ git add . && git commit -m "add slides"
$ git push

# → https://{user}.github.io/{repo}/talk_bundle.html
⚠️ File size: Bundle HTML = 10–50 MB (Base64 images). GitHub single file limit = 100 MB. For large decks, use CERN EOS.
🔧 GitHub Pages Setup (3 steps):

Create a public repo (e.g. Html-slides-public)

Go to Settings → Pages:
   • Source: Deploy from a branch
   • Branch: main / / (root)
   • Click Save

Push your *_bundle.html → live in ~60s at:
https://{user}.github.io/{repo}/
Custom domain: Settings → Pages → Custom domain → enter your domain. Add a CNAME record pointing to {user}.github.io.
Summary
Dimension HTML Slides (This Tool) PPTX
Version Control Pure text — Git diff line-by-line Binary blob, impossible to diff
AI Generation Agent reads/writes HTML directly Vector layout hard for AI to adjust
Online Sharing Single URL, zero download Must download + open in Office
Math / $\LaTeX$ MathJax native rendering ⚠️ Built-in formula editor limited
Animations CSS + JS — web-design-level creativity ⚠️ Built-in presets only
Batch Scripting Scripts: bulk image insert, renumber, bundle GUI-only, manual one-by-one
Cross-platform Any browser, any OS ⚠️ Office/Keynote/LibreOffice
Pixel-perfect Fixed 1920×1080 canvas ⚠️ Depends on display device
Custom Styles Full CSS freedom, 10 skins ⚠️ Template master limited
PDF Export ⚠️ Screenshot mode — text not selectable
(but hyperlinks remain clickable)
Vector text, fully selectable
Collaboration Git branch + PR review Office 365 real-time co-edit
Conclusion: For academic talks requiring frequent iteration, AI assistance, and instant online sharing, HTML Slides are the superior choice. The only trade-off is PDF text selectability — a minor issue for presentation decks.
  • 3-step workflow: Plan → Content → Bundle
  • 10 skins covering all HEP aesthetics
  • AI-native: works with Gemini, Antigravity, Claude Code, Copilot
  • Zero dependencies: one HTML file, any browser
  • Dual hosting: CERN EOS Web + GitHub Pages
🔗 Resources

GitHub:
ky230/frontend-slides-PKU

Live Demo:
ky230.github.io/Html-slides-public/

CERN Hosted (HIG-25-006):
hig-25006.web.cern.ch/HTML_SLIDES/
Try it: Fork the repo → run init-slides.py → open in browser → start presenting! 🚀