f3cce51fb3
Complete color theme system (light/dark/auto) with dynamic UI: Features: - Color theme switcher with auto/light/dark modes - Dynamic button colors on hover (purple/yellow/blue per theme) - localStorage persistence across sessions - Proper button positioning (desktop and mobile) - Mobile: 5-button layout with theme before info button Fixes: - CSP updated to allow jsDelivr CDN for iconify icons - Button repositioning: Download PDF and Print Friendly at top - Hover-only colors (not persistent) - Mobile button order corrected Files: - static/css/color-theme.css - Theme system with CSS variables - static/js/color-theme.js - Theme switching logic - templates/partials/color-theme-switcher.html - Button component - internal/middleware/security.go - CSP fix for jsDelivr - tests/mjs/13-color-theme-switcher.test.mjs - Comprehensive test - tests/TEST-SUMMARY.md - Updated test documentation
115 lines
4.6 KiB
HTML
115 lines
4.6 KiB
HTML
<!-- Primary response: Updated language selector -->
|
|
<div class="language-selector" id="language-selector">
|
|
<button class="selector-btn {{if eq .Lang "en"}}active{{end}}"
|
|
data-short="EN"
|
|
hx-get="/switch-language?lang=en"
|
|
hx-target="#language-selector"
|
|
hx-swap="outerHTML swap:250ms settle:250ms"
|
|
hx-indicator="#lang-indicator-en"
|
|
hx-push-url="/?lang=en"
|
|
aria-label="English">
|
|
<span>English</span>
|
|
</button>
|
|
<button class="selector-btn {{if eq .Lang "es"}}active{{end}}"
|
|
data-short="ES"
|
|
hx-get="/switch-language?lang=es"
|
|
hx-target="#language-selector"
|
|
hx-swap="outerHTML swap:250ms settle:250ms"
|
|
hx-indicator="#lang-indicator-es"
|
|
hx-push-url="/?lang=es"
|
|
aria-label="Español">
|
|
<span>Español</span>
|
|
</button>
|
|
</div>
|
|
<!-- Out-of-band swap: Page 1 content wrapper with fade transition -->
|
|
<div id="cv-inner-content-page-1"
|
|
class="cv-page-content-wrapper"
|
|
hx-swap-oob="innerHTML"
|
|
_="on htmx:oobAfterSwap wait 100ms then remove .loading from me">
|
|
{{template "title-badges" .}}
|
|
|
|
<!-- Page 1 Content Grid: Left Sidebar + Main Content -->
|
|
<div class="page-content">
|
|
<!-- Left Sidebar - Skills (first half) -->
|
|
<aside class="cv-sidebar cv-sidebar-left">
|
|
<details class="sidebar-accordion" open>
|
|
<summary class="sidebar-accordion-header">
|
|
<iconify-icon icon="mdi:brain" width="20" height="20"></iconify-icon>
|
|
<span>{{if eq .Lang "es"}}Competencias Técnicas{{else}}Technical Skills{{end}}</span>
|
|
<iconify-icon icon="mdi:chevron-down" width="20" height="20" class="chevron"></iconify-icon>
|
|
</summary>
|
|
<div class="sidebar-accordion-content">
|
|
{{range .SkillsLeft}}
|
|
<section class="sidebar-section">
|
|
<details open>
|
|
<summary>
|
|
<h3 class="sidebar-title">{{.Category}}</h3>
|
|
</summary>
|
|
<div class="sidebar-content">
|
|
{{range .Items}}<div class="skill-item">{{.}}</div>{{end}}
|
|
</div>
|
|
</details>
|
|
</section>
|
|
{{end}}
|
|
</div>
|
|
</details>
|
|
</aside>
|
|
|
|
<!-- Main Content Area - Page 1 -->
|
|
<main class="cv-main">
|
|
{{template "section-header" .}}
|
|
{{template "section-education" .}}
|
|
{{template "section-skills-summary" .}}
|
|
{{template "section-experience" .}}
|
|
</main>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Out-of-band swap: Page 2 content wrapper with fade transition -->
|
|
<div id="cv-inner-content-page-2"
|
|
class="cv-page-content-wrapper"
|
|
hx-swap-oob="innerHTML"
|
|
_="on htmx:oobAfterSwap wait 100ms then remove .loading from me">
|
|
{{template "title-badges" .}}
|
|
|
|
<!-- Page 2 Content Grid: Main Content + Right Sidebar -->
|
|
<div class="page-content">
|
|
<!-- Main Content Area - Page 2 -->
|
|
<main class="cv-main">
|
|
{{template "section-awards" .}}
|
|
{{template "section-projects" .}}
|
|
{{template "section-courses" .}}
|
|
{{template "section-languages" .}}
|
|
{{template "section-references" .}}
|
|
{{template "section-other" .}}
|
|
</main>
|
|
|
|
<!-- Right Sidebar - Skills (second half) -->
|
|
<aside class="cv-sidebar cv-sidebar-right">
|
|
<details class="sidebar-accordion" open>
|
|
<summary class="sidebar-accordion-header">
|
|
<iconify-icon icon="mdi:brain" width="20" height="20"></iconify-icon>
|
|
<span>{{if eq .Lang "es"}}Más Competencias{{else}}More Skills{{end}}</span>
|
|
<iconify-icon icon="mdi:chevron-down" width="20" height="20" class="chevron"></iconify-icon>
|
|
</summary>
|
|
<div class="sidebar-accordion-content">
|
|
{{range .SkillsRight}}
|
|
<section class="sidebar-section">
|
|
<details open>
|
|
<summary>
|
|
<h3 class="sidebar-title">{{.Category}}</h3>
|
|
</summary>
|
|
<div class="sidebar-content">
|
|
{{range .Items}}<div class="skill-item">{{.}}</div>{{end}}
|
|
</div>
|
|
</details>
|
|
</section>
|
|
{{end}}
|
|
</div>
|
|
</details>
|
|
</aside>
|
|
</div>
|
|
|
|
{{template "cv-footer" .}}
|
|
</div>
|