-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathscript.js
More file actions
233 lines (202 loc) · 10.8 KB
/
Copy pathscript.js
File metadata and controls
233 lines (202 loc) · 10.8 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
/**
* i18n translations
*/
const translations = {
en: {
'nav.start': 'Start',
'nav.about': 'About',
'nav.experience': 'Experience',
'nav.skills': 'Skills',
'nav.contact': 'Contact',
'hero.overline': 'Tech Lead & Senior Backend Engineer',
'hero.h1a': 'Building',
'hero.h1b': 'Cloud Architectures',
'hero.h1c': 'for the',
'hero.h1d': 'Future',
'hero.h1e': 'Present.',
'hero.desc': 'Over 20 years of experience shaping the energy and transportation sectors with scalable solutions and resilient software.',
'hero.cta1': 'Get in Touch',
'hero.cta2': 'View Work',
'about.title': 'Professional Summary',
'about.p1': 'Experienced Technical Lead and Software Engineer with over <strong>20 years</strong> of experience in the IT industry, specializing in software architecture, microservices, and cloud solutions (AWS, GCP, Azure).',
'about.p2': 'Proven track record of leading development teams and delivering complex projects in the energy and transportation sectors. Expertise in Java/Spring ecosystems, modern web frameworks, and agile methodologies.',
'exp.title': 'Experience',
'exp.edp.date': 'Aug 2019 – Present',
'exp.edp.sector': 'Electric Power Distribution Industry',
'exp.edp.li1': 'Managing five development teams (2-6 people each) for multiple IT projects.',
'exp.edp.li2': 'Responsible for public/customer sites: eredesdistribucion.es, viesgodistribucion.com, begasa.es.',
'exp.edp.li3': 'Tech Lead & SCRUM Master for EDP Solar and EDP MiVe (mobility).',
'exp.edp.li4': 'Tech Stack: Java+Spring, Angular, NodeJS, Python, Cloud (GCP/OnPrem), Microservices.',
'exp.meep.sector': 'Transportation Industry',
'exp.meep.li1': 'Led definition and implementation of startup systems and IT strategy.',
'exp.meep.li2': 'Designed microservice backend architecture (Java/Spring, AWS).',
'exp.meep.li3': 'Managed team of 7 developers.',
'exp.alsa.sector': 'Transportation Industry',
'exp.alsa.li1': 'Technical Supervisor in IT planning for 9 years.',
'exp.alsa.li2': 'Project Manager for vehicle/personnel management systems.',
'exp.eci.sector': 'IT and Services Industry',
'exp.eci.li1': 'Developed reusable software components for JEE/Vignette web portals.',
'exp.panda.sector': 'Software Industry',
'exp.panda.li1': 'R&D for proactive malware detection tools in TruPrevent area.',
'skills.title': 'Technical Expertise',
'skills.languages': 'Languages',
'skills.data': 'Data',
'skills.methodologies': 'Methodologies',
'skills.scrum': 'Scrum Master (Certified)',
'edu.title': 'Education & Certs',
'edu.education': 'Education',
'edu.postgrad': 'Postgraduate in Smart Mobility - ITS',
'edu.bachelor': 'Bachelor of Computer Science',
'edu.uniOviedo': 'University of Oviedo | 2001 – 2005',
'edu.certs': 'Certifications',
'footer.title': "Let's Build Something Great",
'footer.cta': 'Contact Me',
},
es: {
'nav.start': 'Inicio',
'nav.about': 'Sobre mí',
'nav.experience': 'Experiencia',
'nav.skills': 'Habilidades',
'nav.contact': 'Contacto',
'hero.overline': 'Tech Lead & Ingeniero Backend Senior',
'hero.h1a': 'Construyendo',
'hero.h1b': 'Arquitecturas Cloud',
'hero.h1c': 'para el',
'hero.h1d': 'Futuro',
'hero.h1e': 'Presente.',
'hero.desc': 'Más de 20 años de experiencia transformando los sectores energético y del transporte con soluciones escalables y software resiliente.',
'hero.cta1': 'Contáctame',
'hero.cta2': 'Ver trabajo',
'about.title': 'Resumen Profesional',
'about.p1': 'Tech Lead y Arquitecto de Software con más de <strong>20 años</strong> de experiencia en el sector IT, especializado en arquitectura de software, microservicios y soluciones cloud (AWS, GCP, Azure).',
'about.p2': 'Amplia trayectoria liderando equipos de desarrollo y entregando proyectos complejos en los sectores energético y del transporte. Experto en ecosistemas Java/Spring, frameworks web modernos y metodologías ágiles.',
'exp.title': 'Experiencia',
'exp.edp.date': 'Ago 2019 – Actualidad',
'exp.edp.sector': 'Sector Distribución Eléctrica',
'exp.edp.li1': 'Gestión de cinco equipos de desarrollo (2-6 personas cada uno) en múltiples proyectos IT.',
'exp.edp.li2': 'Responsable de los sitios públicos: eredesdistribucion.es, viesgodistribucion.com, begasa.es.',
'exp.edp.li3': 'Tech Lead & SCRUM Master para EDP Solar y EDP MiVe (movilidad).',
'exp.edp.li4': 'Stack tecnológico: Java+Spring, Angular, NodeJS, Python, Cloud (GCP/OnPrem), Microservicios.',
'exp.meep.sector': 'Sector del Transporte',
'exp.meep.li1': 'Definición e implementación de los sistemas y la estrategia IT de la startup.',
'exp.meep.li2': 'Diseño de la arquitectura backend de microservicios (Java/Spring, AWS).',
'exp.meep.li3': 'Gestión de un equipo de 7 desarrolladores.',
'exp.alsa.sector': 'Sector del Transporte',
'exp.alsa.li1': 'Supervisor técnico en planificación IT durante 9 años.',
'exp.alsa.li2': 'Project Manager para sistemas de gestión de vehículos y personal.',
'exp.eci.sector': 'Sector IT y Servicios',
'exp.eci.li1': 'Desarrollo de componentes software reutilizables para portales web JEE/Vignette.',
'exp.panda.sector': 'Sector Software',
'exp.panda.li1': 'I+D para herramientas de detección proactiva de malware en el área TruPrevent.',
'skills.title': 'Expertise Técnico',
'skills.languages': 'Lenguajes',
'skills.data': 'Datos',
'skills.methodologies': 'Metodologías',
'skills.scrum': 'Scrum Master (Certificado)',
'edu.title': 'Formación & Certificaciones',
'edu.education': 'Formación',
'edu.postgrad': 'Postgrado en Movilidad Inteligente - ITS',
'edu.bachelor': 'Ingeniería en Informática',
'edu.uniOviedo': 'Universidad de Oviedo | 2001 – 2005',
'edu.certs': 'Certificaciones',
'footer.title': 'Construyamos algo grande',
'footer.cta': 'Contáctame',
}
};
/**
* Apply translations to all [data-i18n] elements
*/
function applyLanguage(lang) {
const t = translations[lang];
document.querySelectorAll('[data-i18n]').forEach(el => {
const key = el.getAttribute('data-i18n');
if (t[key] !== undefined) {
el.innerHTML = t[key];
}
});
// Update <html lang> attribute
document.documentElement.lang = lang;
// Save preference
localStorage.setItem('lang', lang);
// Update active button
document.querySelectorAll('.lang-btn').forEach(btn => {
btn.classList.toggle('active', btn.dataset.lang === lang);
});
}
document.addEventListener('DOMContentLoaded', () => {
// ── Language select (custom dropdown) ───────────────────────────────
const langSelect = document.getElementById('langSelect');
const langSelected = document.getElementById('langSelected');
const langDropdown = document.getElementById('langDropdown');
const langFlag = document.getElementById('langFlag');
const langCode = document.getElementById('langCode');
const flagMap = { en: '🇬🇧', es: '🇪🇸' };
const codeMap = { en: 'EN', es: 'ES' };
const savedLang = localStorage.getItem('lang') || 'en';
applyLanguage(savedLang);
langFlag.textContent = flagMap[savedLang];
langCode.textContent = codeMap[savedLang];
// Toggle open
langSelected.addEventListener('click', (e) => {
e.stopPropagation();
langSelect.classList.toggle('open');
});
// Select option
document.querySelectorAll('.lang-option').forEach(opt => {
opt.addEventListener('click', () => {
const lang = opt.dataset.lang;
applyLanguage(lang);
langFlag.textContent = flagMap[lang];
langCode.textContent = codeMap[lang];
document.querySelectorAll('.lang-option').forEach(o => o.classList.remove('active'));
opt.classList.add('active');
langSelect.classList.remove('open');
});
});
// Close on outside click
document.addEventListener('click', () => langSelect.classList.remove('open'));
// ── Custom Cursor Glow ───────────────────────────────────────────────
const cursorGlow = document.querySelector('.cursor-glow');
document.addEventListener('mousemove', (e) => {
cursorGlow.style.left = e.clientX + 'px';
cursorGlow.style.top = e.clientY + 'px';
});
// ── Mobile Menu Toggle ───────────────────────────────────────────────
const menuToggle = document.querySelector('.mobile-menu-toggle');
const navLinks = document.querySelector('.nav-links');
menuToggle.addEventListener('click', () => {
navLinks.classList.toggle('active');
const icon = menuToggle.querySelector('i');
if (navLinks.classList.contains('active')) {
icon.classList.replace('fa-bars', 'fa-times');
} else {
icon.classList.replace('fa-times', 'fa-bars');
}
});
// Close menu when clicking a link
document.querySelectorAll('.nav-links a').forEach(link => {
link.addEventListener('click', () => {
navLinks.classList.remove('active');
menuToggle.querySelector('i').classList.replace('fa-times', 'fa-bars');
});
});
// ── Header Scroll Effect ─────────────────────────────────────────────
const header = document.querySelector('.glass-header');
window.addEventListener('scroll', () => {
header.classList.toggle('scrolled', window.scrollY > 50);
});
// ── Scroll Animations (Intersection Observer) ────────────────────────
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
entry.target.classList.add('fade-in-up');
observer.unobserve(entry.target);
}
});
}, { threshold: 0.1, rootMargin: '0px 0px -50px 0px' });
document.querySelectorAll('.card, .section-title, .hero-content > *, .timeline-item, .skill-tag')
.forEach(el => {
el.style.opacity = '0';
observer.observe(el);
});
});