diff --git a/data/cv-en.json b/data/cv-en.json
index b2bc454..6a1ae20 100644
--- a/data/cv-en.json
+++ b/data/cv-en.json
@@ -350,6 +350,7 @@
{
"category": "Go Ecosystem",
"proficiency": 5,
+ "sidebar": "left",
"items": [
"Hono - High-Performance Web Framework",
"Gin - Web Framework",
@@ -363,6 +364,7 @@
{
"category": "JavaScript Ecosystem",
"proficiency": 5,
+ "sidebar": "left",
"items": [
"Node.js & Express",
"React & React Ecosystem",
@@ -375,6 +377,7 @@
{
"category": "Frontend Technologies",
"proficiency": 5,
+ "sidebar": "left",
"items": [
"HTMX - Hypermedia-Driven Applications",
"HTML5 & Semantic Web",
@@ -386,20 +389,10 @@
"Template Engines (Handlebars, Panini, Mustache)"
]
},
- {
- "category": "Legacy Enterprise Technologies",
- "proficiency": 3,
- "items": [
- "Java & J2EE",
- "Spring Framework, Struts, Hibernate",
- "PHP & WordPress",
- "Yii Framework, Zend Framework",
- "Enterprise Application Servers (Tomcat, JBoss, WebLogic)"
- ]
- },
{
"category": "Backend Technologies",
"proficiency": 5,
+ "sidebar": "left",
"items": [
"Go - Current Primary Stack",
"Hono Framework - High-Performance Web Server",
@@ -409,9 +402,22 @@
"Database Design & Optimization"
]
},
+ {
+ "category": "Legacy Enterprise Technologies",
+ "proficiency": 3,
+ "sidebar": "left",
+ "items": [
+ "Java & J2EE",
+ "Spring Framework, Struts, Hibernate",
+ "PHP & WordPress",
+ "Yii Framework, Zend Framework",
+ "Enterprise Application Servers (Tomcat, JBoss, WebLogic)"
+ ]
+ },
{
"category": "Databases",
"proficiency": 4,
+ "sidebar": "right",
"items": [
"PostgreSQL",
"MySQL",
@@ -425,6 +431,7 @@
{
"category": "Infrastructure & Servers",
"proficiency": 5,
+ "sidebar": "right",
"items": [
"Linux Server Administration",
"VPS Deployment & Configuration",
@@ -436,6 +443,7 @@
{
"category": "DevOps & CI/CD",
"proficiency": 5,
+ "sidebar": "right",
"items": [
"CI/CD Pipeline Design & Implementation",
"Custom Deployment Solutions",
@@ -447,6 +455,7 @@
{
"category": "Team Management",
"proficiency": 4,
+ "sidebar": "right",
"items": [
"Preparation and projects startup",
"Fluid communication with clients",
@@ -458,6 +467,7 @@
{
"category": "Design Tools",
"proficiency": 3,
+ "sidebar": "right",
"items": [
"Corel Draw",
"Adobe PhotoShop",
@@ -793,9 +803,9 @@
"technologies": ["JavaScript", "React", "Node.js", "PHP", "WordPress", "Web Development"],
"shortDescription": "Collection of client projects and websites where I contributed to development, implementation, and technical solutions across various industries.",
"responsibilities": [
- "
Lidering (via Twentic): Real estate and property management platform development
",
- "
Jorpack (via Twentic): Industrial packaging solutions and corporate website
",
- "",
+ "
Lidering (via Twentic): Real estate and property management platform development
",
+ "
Jorpack (via Twentic): Industrial packaging solutions and corporate website
",
+ "
",
"Mobbeel: Biometric authentication and identity verification solutions website
"
]
}
diff --git a/data/cv-es.json b/data/cv-es.json
index d795ea3..579356c 100644
--- a/data/cv-es.json
+++ b/data/cv-es.json
@@ -350,6 +350,7 @@
{
"category": "Ecosistema Go",
"proficiency": 5,
+ "sidebar": "left",
"items": [
"Hono - Framework Web de Alto Rendimiento",
"Gin - Framework Web",
@@ -363,6 +364,7 @@
{
"category": "Ecosistema JavaScript",
"proficiency": 5,
+ "sidebar": "left",
"items": [
"Node.js y Express",
"React y Ecosistema React",
@@ -375,6 +377,7 @@
{
"category": "Tecnologías Frontend",
"proficiency": 5,
+ "sidebar": "left",
"items": [
"HTMX - Aplicaciones Basadas en Hipermedia",
"HTML5 y Web Semántica",
@@ -386,20 +389,10 @@
"Motores de Plantillas (Handlebars, Panini, Mustache)"
]
},
- {
- "category": "Tecnologías Enterprise Anteriores",
- "proficiency": 3,
- "items": [
- "Java y J2EE",
- "Spring Framework, Struts, Hibernate",
- "PHP y WordPress",
- "Yii Framework, Zend Framework",
- "Servidores de Aplicaciones Enterprise (Tomcat, JBoss, WebLogic)"
- ]
- },
{
"category": "Tecnologías Backend",
"proficiency": 5,
+ "sidebar": "left",
"items": [
"Go - Stack Principal Actual",
"Hono Framework - Servidor Web de Alto Rendimiento",
@@ -409,9 +402,22 @@
"Diseño y Optimización de Bases de Datos"
]
},
+ {
+ "category": "Tecnologías Enterprise Anteriores",
+ "proficiency": 3,
+ "sidebar": "left",
+ "items": [
+ "Java y J2EE",
+ "Spring Framework, Struts, Hibernate",
+ "PHP y WordPress",
+ "Yii Framework, Zend Framework",
+ "Servidores de Aplicaciones Enterprise (Tomcat, JBoss, WebLogic)"
+ ]
+ },
{
"category": "Bases de Datos",
"proficiency": 4,
+ "sidebar": "right",
"items": [
"PostgreSQL",
"MySQL",
@@ -425,6 +431,7 @@
{
"category": "Infraestructura y Servidores",
"proficiency": 5,
+ "sidebar": "right",
"items": [
"Administración de Servidores Linux",
"Despliegue y Configuración de VPS",
@@ -436,6 +443,7 @@
{
"category": "DevOps y CI/CD",
"proficiency": 5,
+ "sidebar": "right",
"items": [
"Diseño e Implementación de Pipelines CI/CD",
"Soluciones de Despliegue Personalizadas",
@@ -447,6 +455,7 @@
{
"category": "Gestión de Equipos",
"proficiency": 4,
+ "sidebar": "right",
"items": [
"Preparación y puesta en marcha de proyectos",
"Comunicación fluida con los clientes",
@@ -458,6 +467,7 @@
{
"category": "Herramientas de Diseño",
"proficiency": 3,
+ "sidebar": "right",
"items": [
"Corel Draw",
"Adobe PhotoShop",
@@ -798,9 +808,9 @@
"technologies": ["JavaScript", "React", "Node.js", "PHP", "WordPress", "Desarrollo Web"],
"shortDescription": "Colección de proyectos de clientes y sitios web donde contribuí al desarrollo, implementación y soluciones técnicas en diversas industrias.",
"responsibilities": [
- "
Lidering (a través de Twentic): Desarrollo de plataforma de gestión inmobiliaria y propiedades
",
- "
Jorpack (a través de Twentic): Soluciones de embalaje industrial y sitio web corporativo
",
- "",
+ "
Lidering (a través de Twentic): Desarrollo de plataforma de gestión inmobiliaria y propiedades
",
+ "
Jorpack (a través de Twentic): Soluciones de embalaje industrial y sitio web corporativo
",
+ "
",
"Mobbeel: Sitio web de soluciones de autenticación biométrica y verificación de identidad
"
]
}
diff --git a/internal/handlers/cv.go b/internal/handlers/cv.go
index f7bc15f..1a3eae2 100644
--- a/internal/handlers/cv.go
+++ b/internal/handlers/cv.go
@@ -199,21 +199,22 @@ func (h *CVHandler) ExportPDF(w http.ResponseWriter, r *http.Request) {
}
// splitSkills splits skill categories between left (page 1) and right (page 2) sidebars
-// Left sidebar shows first 7 categories, right sidebar shows remaining categories
+// Each category explicitly specifies which sidebar it belongs to via the "sidebar" field
func splitSkills(skills []models.SkillCategory) (left, right []models.SkillCategory) {
if len(skills) == 0 {
return nil, nil
}
- // Split at index 7 (first 7 items on left)
- splitIndex := 7
- if len(skills) < splitIndex {
- return skills, nil
+ // Filter by sidebar field
+ for _, skill := range skills {
+ if skill.Sidebar == "right" {
+ right = append(right, skill)
+ } else {
+ // Default to left if not specified or if set to "left"
+ left = append(left, skill)
+ }
}
- left = skills[:splitIndex]
- right = skills[splitIndex:]
-
return left, right
}
diff --git a/internal/models/cv.go b/internal/models/cv.go
index bb80af7..f465d0b 100644
--- a/internal/models/cv.go
+++ b/internal/models/cv.go
@@ -89,6 +89,7 @@ type SkillCategory struct {
Category string `json:"category"`
Proficiency int `json:"proficiency"`
Items []string `json:"items"`
+ Sidebar string `json:"sidebar"` // "left" or "right"
}
type Language struct {
diff --git a/static/css/main.css b/static/css/main.css
index df4c70e..50fb097 100644
--- a/static/css/main.css
+++ b/static/css/main.css
@@ -1899,3 +1899,158 @@ html {
height: 45px;
}
}
+
+/* ========================================
+ Desktop: Ensure Sidebar Content Visible (>1280px)
+ ======================================== */
+
+@media (min-width: 1281px) {
+ /* Ensure sidebar content is always visible in desktop view */
+ .sidebar-content {
+ max-height: none !important;
+ opacity: 1 !important;
+ overflow: visible !important;
+ display: block !important;
+ margin-top: 10px !important;
+ }
+
+ .skill-category .sidebar-content,
+ .cv-sidebar-section .sidebar-content {
+ max-height: none !important;
+ opacity: 1 !important;
+ overflow: visible !important;
+ }
+
+ .sidebar-title::after {
+ display: none !important;
+ }
+
+ .sidebar-title {
+ cursor: default !important;
+ }
+}
+
+/* ========================================
+ Responsive: Medium Screens (1024px - 1280px)
+ ======================================== */
+
+@media (min-width: 1024px) and (max-width: 1280px) {
+
+ /* ========== Global Font Size Reduction ========== */
+ html {
+ font-size: 14px; /* Reduced from default 16px */
+ }
+
+ .cv-name {
+ font-size: 1.8em; /* Reduced from 2.2em */
+ }
+
+ .sidebar-title {
+ font-size: 0.95rem;
+ }
+
+ .sidebar-content {
+ font-size: 0.9rem;
+ }
+
+ .experience-item h3,
+ .project-item h3 {
+ font-size: 1rem;
+ }
+
+ .experience-item p,
+ .project-item p,
+ .experience-item li,
+ .project-item li {
+ font-size: 0.85rem;
+ }
+
+ /* ========== Selector Labels - Hide, Show on Hover ========== */
+ .selector-label {
+ max-width: 0;
+ overflow: hidden;
+ opacity: 0;
+ transition: all 0.3s ease;
+ white-space: nowrap;
+ }
+
+ .selector-group:hover .selector-label {
+ max-width: 200px;
+ opacity: 1;
+ margin-right: 0.75rem;
+ }
+
+ /* ========== Language Selector - Collapse to EN/ES ========== */
+ .language-selector .selector-btn {
+ position: relative;
+ padding: 0.4rem 0.8rem;
+ min-width: 50px;
+ font-size: 0; /* Hide actual text */
+ overflow: visible;
+ }
+
+ /* Show only short version (EN/ES) */
+ .language-selector .selector-btn::before {
+ content: attr(data-short);
+ font-size: 1rem; /* Restore font size for pseudo-element */
+ opacity: 1;
+ }
+
+ /* On hover, show full text */
+ .language-selector:hover .selector-btn,
+ .language-selector .selector-btn:hover {
+ font-size: 1rem; /* Restore font size */
+ padding: 0.4rem 1rem;
+ min-width: auto;
+ }
+
+ .language-selector:hover .selector-btn::before,
+ .language-selector .selector-btn:hover::before {
+ content: ''; /* Hide short version */
+ opacity: 0;
+ }
+
+ /* ========== Action Buttons - Icon Only, Expand on Hover ========== */
+ .action-btn {
+ position: relative;
+ width: 45px;
+ overflow: hidden;
+ transition: width 0.3s ease, padding 0.3s ease;
+ white-space: nowrap;
+ text-indent: 0;
+ }
+
+ /* Hide button text, keep icon */
+ .action-btn iconify-icon {
+ flex-shrink: 0;
+ }
+
+ .action-btn {
+ font-size: 0;
+ padding: 0 0.65rem;
+ justify-content: center;
+ }
+
+ /* On hover, show text */
+ .action-btn:hover {
+ width: auto;
+ font-size: 0.95rem;
+ padding: 0.65rem 1.5rem;
+ gap: 0.5rem;
+ }
+
+ /* ========== Sidebar Content - Hide Text, Show on Hover ========== */
+ .sidebar-content {
+ max-height: 0;
+ overflow: hidden;
+ opacity: 0;
+ }
+
+ /* Show sidebar content on hover */
+ .skill-category:hover .sidebar-content,
+ .cv-sidebar-section:hover .sidebar-content {
+ max-height: 1000px;
+ opacity: 1;
+ margin-top: 10px;
+ }
+}
diff --git a/static/images/projects/deliverybikes.png b/static/images/projects/deliverybikes.png
new file mode 100644
index 0000000..61cd793
Binary files /dev/null and b/static/images/projects/deliverybikes.png differ
diff --git a/static/images/projects/jorpack.png b/static/images/projects/jorpack.png
new file mode 100644
index 0000000..d56a4ef
Binary files /dev/null and b/static/images/projects/jorpack.png differ
diff --git a/static/images/projects/lidering.png b/static/images/projects/lidering.png
new file mode 100644
index 0000000..4ca9580
Binary files /dev/null and b/static/images/projects/lidering.png differ
diff --git a/templates/index.html b/templates/index.html
index f403259..836884d 100644
--- a/templates/index.html
+++ b/templates/index.html
@@ -110,10 +110,10 @@
-