f5276431ea
Visitors can ask questions about the CV via a floating chat panel. The agent uses Gemini to answer questions about experience, projects, skills, and education by querying the cached CV JSON data. - internal/chat/agent.go: LLM agent with query_cv tool that searches CV data by section (experience, projects, skills, etc.) with keyword filtering - internal/chat/handler.go: POST /api/chat endpoint with session management, graceful degradation when GOOGLE_API_KEY is not set - chat-widget.html: HTMX-powered floating chat panel with Hyperscript toggle - _chat.css: Responsive chat UI with dark theme support - Wired into existing architecture via dependency injection (CVHandler, routes, main.go) — zero breaking changes, all existing tests pass
70 lines
3.1 KiB
HTML
70 lines
3.1 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="{{if eq .Lang "es"}}es{{else}}en{{end}}">
|
|
{{template "head" .}}
|
|
<body {{if .ThemeClean}}class="theme-clean"{{end}}
|
|
_="on load call initScrollBehavior()
|
|
on scroll from window call handleScroll()
|
|
on keydown(key, target, ctrlKey, metaKey, altKey)
|
|
set ninjaKeys to #cmd-k-bar
|
|
set ninjaOpen to (ninjaKeys is not null and ninjaKeys.opened)
|
|
set skip to (target.tagName is 'INPUT' or target.tagName is 'TEXTAREA' or ninjaOpen)
|
|
set noMod to (not ctrlKey and not metaKey and not altKey)
|
|
if key is '?' and noMod and not skip then halt the event then call openModalShortcut('shortcuts-modal') end
|
|
if (key is 'l' or key is 'L') and noMod and not skip then halt the event then call handleToggleShortcut('lengthToggle', 'lengthToggleMenu') end
|
|
if (key is 'i' or key is 'I') and noMod and not skip then halt the event then call handleToggleShortcut('iconToggle', 'iconToggleMenu') end
|
|
if (key is 'v' or key is 'V') and noMod and not skip then halt the event then call handleToggleShortcut('themeToggle', 'themeToggleMenu') end
|
|
end">
|
|
|
|
<!-- ============================================ -->
|
|
<!-- TOP NAVIGATION & CONTROLS -->
|
|
<!-- ============================================ -->
|
|
<div id="top"></div>
|
|
{{template "action-bar" .}}
|
|
{{template "hamburger-menu" .}}
|
|
{{template "color-theme-switcher" .}}
|
|
|
|
<!-- ============================================ -->
|
|
<!-- MAIN CV CONTENT -->
|
|
<!-- ============================================ -->
|
|
<div id="zoom-wrapper" class="zoom-wrapper">
|
|
<div class="cv-container">
|
|
{{template "cv-content.html" .}}
|
|
</div>
|
|
</div>
|
|
|
|
<!-- ============================================ -->
|
|
<!-- PAGE FOOTER & NOTIFICATIONS -->
|
|
<!-- ============================================ -->
|
|
{{template "page-footer" .}}
|
|
{{template "error-toast" .}}
|
|
{{template "pdf-toast" .}}
|
|
|
|
<!-- ============================================ -->
|
|
<!-- FLOATING BUTTONS -->
|
|
<!-- ============================================ -->
|
|
<div class="fixed-buttons-backdrop no-print"></div>
|
|
{{template "back-to-top" .}}
|
|
{{template "info-button" .}}
|
|
{{template "download-button" .}}
|
|
{{template "print-friendly-button" .}}
|
|
{{template "contact-button" .}}
|
|
{{template "zoom-toggle-button" .}}
|
|
{{template "shortcuts-button" .}}
|
|
{{template "chat-widget" .}}
|
|
|
|
<!-- ============================================ -->
|
|
<!-- MODALS -->
|
|
<!-- ============================================ -->
|
|
{{template "info-modal" .}}
|
|
{{template "shortcuts-modal" .}}
|
|
{{template "pdf-modal" .}}
|
|
{{template "contact-modal" .}}
|
|
{{template "zoom-control" .}}
|
|
|
|
<!-- ============================================ -->
|
|
<!-- SCRIPTS & ANALYTICS -->
|
|
<!-- ============================================ -->
|
|
{{template "body-scripts" .}}
|
|
</body>
|
|
</html>
|