Add photo, company logos, and short/long CV toggle

Features:
- Profile photo display (right side, inline with header)
- Company logos for all major employers (8 logos downloaded)
- Short/Long CV toggle for condensed/detailed view
- Short descriptions (1-2 lines) for quick overview
- Experience separators with border lines

Photo Implementation:
- Circular photo (120px) on right side of header
- Placeholder SVG if photo not uploaded
- Instructions in ADDING-YOUR-PHOTO.md
- Photo stored in static/images/profile/

Company Logos:
- Olympic Broadcasting Services, AENA, SAP, Gigya
- Accenture, Everis, Indra, Megabanner
- 40px logos displayed inline with experience
- Auto-hide if logo missing
- Mobile: logos hidden for cleaner layout

Short/Long Toggle:
- Toggle buttons in action bar (Corto/Largo)
- Short mode: shows shortDescription only
- Long mode: shows full responsibilities + technologies
- CSS-based show/hide (no page reload)
- Defaults to short view

Layout Updates:
- Header: text left, photo right, inline alignment
- Experience items: separated by border lines
- Responsive: photo centers on mobile
- Print-optimized: smaller photo in PDF

Data Updates:
- Added shortDescription field to Experience struct
- 13 short descriptions for all positions (EN/ES)
- Added companyLogo field with filename mapping
- JSON updated with all new fields

Tech:
- Pure CSS toggle (no HTMX needed)
- Vanilla JavaScript for button states
- Maintains bilingual support (ES/EN)
This commit is contained in:
juanatsap
2025-10-27 22:32:32 +00:00
parent dab68f34f2
commit cd5d5cff02
17 changed files with 397 additions and 43 deletions
+151 -6
View File
@@ -124,13 +124,39 @@ a:hover {
min-height: 11in;
}
/* Header */
/* Header - Photo on right, inline with text */
.cv-header {
display: flex;
justify-content: space-between;
align-items: flex-start;
gap: 2rem;
border-bottom: 2px solid var(--text-dark);
padding-bottom: 1.5rem;
margin-bottom: 2rem;
}
.cv-header-left {
flex: 1;
}
.cv-header-right {
flex-shrink: 0;
}
.cv-photo {
width: 120px;
height: 120px;
border-radius: 50%;
overflow: hidden;
border: 3px solid var(--border-gray);
}
.cv-photo img {
width: 100%;
height: 100%;
object-fit: cover;
}
.cv-name {
font-size: 2.5rem;
font-weight: 700;
@@ -170,9 +196,15 @@ a:hover {
text-align: justify;
}
/* Experience */
/* Experience - with separators */
.experience-item {
margin-bottom: 1.5rem;
padding-bottom: 1.5rem;
border-bottom: 1px solid var(--border-gray);
}
.experience-item:last-child {
border-bottom: none;
}
.experience-header {
@@ -180,6 +212,27 @@ a:hover {
justify-content: space-between;
margin-bottom: 0.75rem;
gap: 1rem;
align-items: center;
}
.company-logo {
width: 40px;
height: 40px;
flex-shrink: 0;
display: flex;
align-items: center;
justify-content: center;
margin-right: 1rem;
}
.company-logo img {
max-width: 100%;
max-height: 100%;
object-fit: contain;
}
.experience-title {
flex: 1;
}
.position {
@@ -335,17 +388,109 @@ footer {
font-size: 2rem;
}
.cv-header {
flex-direction: column;
align-items: center;
text-align: center;
}
.cv-photo {
order: -1;
margin-bottom: 1rem;
}
.experience-header,
.project-header,
.education-header {
flex-direction: column;
gap: 0.25rem;
}
.action-bar-content {
flex-direction: column;
gap: 1rem;
.company-logo {
display: none;
}
}
.no-print {}
/* Print Styles for Photo */
@media print {
.cv-photo {
width: 100px;
height: 100px;
border-width: 2px;
}
.company-logo {
width: 30px;
height: 30px;
}
}
/* CV Length Toggle */
.cv-length-toggle {
display: flex;
gap: 0.5rem;
}
.length-btn {
padding: 0.4rem 1rem;
border: 1px solid var(--border-gray);
background: white;
border-radius: 4px;
cursor: pointer;
font-size: 0.9rem;
}
.length-btn:hover {
background: #f5f5f5;
}
.length-btn.active {
background: var(--accent-blue);
color: white;
border-color: var(--accent-blue);
}
/* Short CV - Hide detailed content */
.cv-short .long-only {
display: none;
}
.cv-short .short-desc {
display: block;
color: var(--text-gray);
font-size: 0.95rem;
line-height: 1.6;
margin-bottom: 0.75rem;
}
/* Long CV - Hide short descriptions */
.cv-long .short-desc,
.short-desc {
display: none;
}
.cv-long .long-only {
display: block;
}
/* Ensure lists display correctly in long mode */
.cv-long .responsibilities {
display: block;
}
/* Responsive adjustments */
@media (max-width: 768px) {
.action-bar-content {
flex-wrap: wrap;
justify-content: center;
}
.cv-length-toggle {
order: 1;
width: 100%;
justify-content: center;
margin-top: 0.5rem;
}
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 8.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.8 KiB

+1
View File
@@ -0,0 +1 @@
Not Found
+1
View File
@@ -0,0 +1 @@
Not Found
Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.8 KiB

+6
View File
@@ -0,0 +1,6 @@
<svg width="150" height="150" xmlns="http://www.w3.org/2000/svg">
<rect width="150" height="150" fill="#e0e0e0"/>
<circle cx="75" cy="60" r="25" fill="#999"/>
<path d="M 35 110 Q 75 90 115 110" fill="#999"/>
<text x="75" y="140" text-anchor="middle" font-size="10" fill="#666">Add your photo</text>
</svg>

After

Width:  |  Height:  |  Size: 314 B