Files
cv-site/templates/index.html
T

193 lines
8.6 KiB
HTML
Raw Normal View History

2025-10-20 08:54:21 +01:00
<!DOCTYPE html>
<html lang="{{if eq .Lang "es"}}es{{else}}en{{end}}">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
2025-10-31 11:06:38 +00:00
<!-- Primary Meta Tags -->
<title>{{.CV.Personal.Name}} - {{if eq .Lang "es"}}Curriculum Vitae{{else}}Curriculum Vitae{{end}}</title>
<meta name="title" content="{{.CV.Personal.Name}} - {{if eq .Lang "es"}}CV Profesional{{else}}Professional CV{{end}}">
<meta name="description" content="{{.CV.Personal.Title}} | {{if eq .Lang "es"}}18 años de experiencia en desarrollo web, SAP CDC, React, Node.js, Go, HTMX y desarrollo asistido por IA{{else}}18 years of experience in web development, SAP CDC, React, Node.js, Go, HTMX and AI-assisted development{{end}}">
<meta name="keywords" content="{{if eq .Lang "es"}}CV, Curriculum Vitae, {{.CV.Personal.Name}}, Desarrollador FullStack, SAP CDC, React, Node.js, Go, HTMX, IA, Desarrollo Web, Consultor Técnico{{else}}CV, Resume, {{.CV.Personal.Name}}, FullStack Developer, SAP CDC, React, Node.js, Go, HTMX, AI, Web Development, Technical Consultant{{end}}">
<meta name="author" content="{{.CV.Personal.Name}}">
<meta name="robots" content="index, follow">
<link rel="canonical" href="{{.CanonicalURL}}">
<!-- Hreflang tags for international SEO -->
<link rel="alternate" hreflang="en" href="{{.AlternateEN}}">
<link rel="alternate" hreflang="es" href="{{.AlternateES}}">
<link rel="alternate" hreflang="x-default" href="https://juan.andres.morenorub.io/?lang=en">
2025-10-31 11:06:38 +00:00
<!-- Open Graph / Facebook -->
<meta property="og:type" content="profile">
<meta property="og:url" content="{{.CV.Personal.Website}}">
<meta property="og:title" content="{{.CV.Personal.Name}} - {{if eq .Lang "es"}}CV Profesional{{else}}Professional CV{{end}}">
<meta property="og:description" content="{{.CV.Personal.Title}} | {{if eq .Lang "es"}}Consultor Técnico Senior con 18 años de experiencia{{else}}Senior Technical Consultant with 18 years of experience{{end}}">
<meta property="og:image" content="{{.CV.Personal.Website}}/static/images/profile.jpg">
<meta property="og:locale" content="{{if eq .Lang "es"}}es_ES{{else}}en_US{{end}}">
<meta property="og:site_name" content="{{.CV.Personal.Name}}">
<meta property="profile:first_name" content="Juan Andrés">
<meta property="profile:last_name" content="Moreno Rubio">
<meta property="profile:username" content="txeo">
<!-- Social Media Card (Generic) -->
<meta name="twitter:card" content="summary">
<meta name="twitter:title" content="{{.CV.Personal.Name}} - {{if eq .Lang "es"}}CV Profesional{{else}}Professional CV{{end}}">
<meta name="twitter:description" content="{{.CV.Personal.Title}}">
<meta name="twitter:image" content="{{.CV.Personal.Website}}/static/images/profile.jpg">
<!-- HTMX Configuration -->
<meta name="htmx-config" content='{"timeout":5000,"defaultSwapStyle":"innerHTML","defaultSwapDelay":0,"defaultSettleDelay":20}'>
<!-- HTMX with SRI (Subresource Integrity) -->
<script src="https://unpkg.com/htmx.org@1.9.10"
integrity="sha384-D1Kt99CQMDuVetoL1lrYwg5t+9QdHe7NLX/SoJYkXDFfX37iInKRy5xLSi8nO7UC"
crossorigin="anonymous"></script>
2025-10-20 08:54:21 +01:00
2025-11-14 21:38:09 +00:00
<!-- Hyperscript Functions - Must load BEFORE hyperscript library -->
<script type="text/hyperscript" src="/static/hyperscript/functions._hs"></script>
2025-11-12 22:54:46 +00:00
<!-- Hyperscript - Declarative event handling for enhanced interactivity -->
<script src="https://unpkg.com/hyperscript.org@0.9.12"></script>
<!-- Iconify - Load synchronously for immediate rendering -->
<script src="https://code.iconify.design/iconify-icon/1.0.7/iconify-icon.min.js"></script>
2025-10-20 08:54:21 +01:00
<!-- CSS -->
<link rel="stylesheet" href="/static/css/main.css">
<link rel="stylesheet" href="/static/css/logo-toggle.css">
2025-10-20 08:54:21 +01:00
<link rel="stylesheet" href="/static/css/print.css" media="print">
2025-10-31 11:06:38 +00:00
<!-- Fonts with Preload -->
2025-10-20 08:54:21 +01:00
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
2025-10-31 11:06:38 +00:00
<link rel="dns-prefetch" href="https://fonts.googleapis.com">
2025-10-20 08:54:21 +01:00
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap" rel="stylesheet">
2025-10-31 11:06:38 +00:00
<!-- Structured Data (JSON-LD) -->
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "Person",
"name": "{{.CV.Personal.Name}}",
"jobTitle": "{{.CV.Personal.Title}}",
"url": "{{.CV.Personal.Website}}",
"email": "{{.CV.Personal.Email}}",
"telephone": "{{.CV.Personal.Phone}}",
"address": {
"@type": "PostalAddress",
"addressLocality": "{{.CV.Personal.Location}}"
},
"sameAs": [
"{{.CV.Personal.LinkedIn}}",
"{{.CV.Personal.GitHub}}",
"{{.CV.Personal.Domestika}}"
2025-10-31 11:06:38 +00:00
],
"alumniOf": {
"@type": "EducationalOrganization",
"name": "Universidad de Extremadura"
},
"knowsAbout": [
"Web Development",
"SAP Customer Data Cloud",
"React",
"Node.js",
"Go",
"HTMX",
"AI-Assisted Development",
"Full Stack Development"
],
"worksFor": {
"@type": "Organization",
"name": "Olympic Broadcasting Services"
}
}
</script>
2025-10-20 08:54:21 +01:00
</head>
2025-11-12 23:07:44 +00:00
<body {{if .ThemeClean}}class="theme-clean"{{end}}
2025-11-15 15:59:54 +00:00
_="on load call initScrollBehavior()
on scroll from window call handleScroll()
on keydown
2025-11-17 08:34:50 +00:00
set tagName to event.target.tagName
set isInputField to (tagName is 'INPUT' or tagName is 'TEXTAREA')
-- Show shortcuts modal with '?'
if event.key is '?' and not event.ctrlKey and not event.metaKey and not event.altKey and not isInputField
halt the event
set modal to #shortcuts-modal
if modal then call modal.showModal() end
end
-- Toggle CV length with 'L'
if event.key is 'l' or event.key is 'L' and not event.ctrlKey and not event.metaKey and not event.altKey and not isInputField
halt the event
set paper to the first .cv-paper
set isCurrentlyLong to paper.classList.contains('cv-long')
call toggleCVLength(not isCurrentlyLong)
end
-- Toggle icons with 'I'
if event.key is 'i' or event.key is 'I' and not event.ctrlKey and not event.metaKey and not event.altKey and not isInputField
halt the event
set paper to the first .cv-paper
set hasIcons to paper.classList.contains('show-icons')
call toggleIcons(not hasIcons)
end
-- Toggle theme with 'V'
if event.key is 'v' or event.key is 'V' and not event.ctrlKey and not event.metaKey and not event.altKey and not isInputField
halt the event
set container to the first .cv-container
set isClean to container.classList.contains('theme-clean')
call toggleTheme(not isClean)
2025-11-15 15:59:54 +00:00
end
end">
2025-11-12 19:54:56 +00:00
<!-- Top anchor for back-to-top link -->
<div id="top"></div>
2025-11-12 18:26:18 +00:00
{{template "action-bar" .}}
{{template "hamburger-menu" .}}
<!-- Zoom Wrapper (for zoom functionality) -->
<div id="zoom-wrapper" class="zoom-wrapper">
<!-- CV Content Container -->
<div class="cv-container">
2025-11-12 18:55:06 +00:00
{{template "cv-content.html" .}}
</div>
2025-11-12 18:26:18 +00:00
{{template "page-footer" .}}
</div> <!-- End zoom-wrapper -->
2025-11-12 18:26:18 +00:00
{{template "error-toast" .}}
{{template "back-to-top" .}}
2025-11-17 08:34:50 +00:00
{{template "info-button" .}}
{{template "download-button" .}}
{{template "print-friendly-button" .}}
{{template "zoom-toggle-button" .}}
{{template "shortcuts-button" .}}
2025-11-12 18:26:18 +00:00
{{template "info-modal" .}}
2025-11-15 15:59:54 +00:00
{{template "shortcuts-modal" .}}
2025-11-12 18:26:18 +00:00
{{template "pdf-modal" .}}
{{template "zoom-control" .}}
<!-- External JavaScript - CSP Compliant -->
<script src="/static/js/main.js"></script>
2025-11-09 15:02:31 +00:00
<!-- Matomo Analytics - Nonce-based CSP -->
<script nonce="{{.CSPNonce}}">
2025-11-09 15:02:31 +00:00
var _paq = window._paq = window._paq || [];
/* tracker methods like "setCustomDimension" should be called before "trackPageView" */
_paq.push(['trackPageView']);
_paq.push(['enableLinkTracking']);
(function() {
var u="https://matomo.drolo.club/";
_paq.push(['setTrackerUrl', u+'matomo.php']);
_paq.push(['setSiteId', '4']);
var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0];
g.async=true; g.src=u+'matomo.js'; s.parentNode.insertBefore(g,s);
})();
</script>
2025-11-09 15:02:31 +00:00
<!-- End Matomo Code -->
2025-10-20 08:54:21 +01:00
</body>
</html>