feat: comprehensive print optimization for professional PDF output

Print CSS overhaul:
- Fixed photo aspect ratio (60x80, 3:4 portrait) with contain fit
- Unified font sizes across all sections (10pt titles, 9pt content, 8pt metadata)
- Removed excessive spacing (reduced by 50-70%)
- Applied clean theme automatically (no sidebars, icons, logos, badges)
- Force short version for concise 5-page output
- Natural page breaks (removed forced breaks causing blank spaces)
- Consistent section title spacing with proper breathing room
- Match Training/Skills spacing pattern across all sections
- Fixed Languages and References spacing
- Equalized Experience, Courses, Projects, and Awards formatting
- Single separator for "See all projects" link

UI improvements:
- Enhanced icon toggle visibility with better contrast
- Reorganized navigation menu structure
This commit is contained in:
juanatsap
2025-11-10 14:00:32 +00:00
parent eda746407e
commit 18db4011f8
3 changed files with 852 additions and 190 deletions
+183 -85
View File
@@ -224,7 +224,8 @@ iconify-icon {
justify-content: space-between; justify-content: space-between;
width: 75px; width: 75px;
height: 30px; height: 30px;
background: rgba(255,255,255,0.1); background: #e0e0e0;
border: 2px solid #d0d0d0;
border-radius: 15px; border-radius: 15px;
padding: 0 6px; padding: 0 6px;
transition: all 0.3s ease; transition: all 0.3s ease;
@@ -250,6 +251,7 @@ iconify-icon {
.icon-toggle input:checked + .icon-toggle-slider { .icon-toggle input:checked + .icon-toggle-slider {
background: #27ae60; background: #27ae60;
border-color: #229954;
} }
.icon-toggle-slider .icon-left, .icon-toggle-slider .icon-left,
@@ -271,18 +273,22 @@ iconify-icon {
.icon-toggle input:not(:checked) + .icon-toggle-slider .icon-left { .icon-toggle input:not(:checked) + .icon-toggle-slider .icon-left {
color: #333; color: #333;
font-weight: bold;
} }
.icon-toggle input:not(:checked) + .icon-toggle-slider .icon-right { .icon-toggle input:not(:checked) + .icon-toggle-slider .icon-right {
color: rgba(255,255,255,0.3); color: #999;
opacity: 0.5;
} }
.icon-toggle input:checked + .icon-toggle-slider .icon-left { .icon-toggle input:checked + .icon-toggle-slider .icon-left {
color: rgba(255,255,255,0.3); color: rgba(255,255,255,0.4);
opacity: 0.5;
} }
.icon-toggle input:checked + .icon-toggle-slider .icon-right { .icon-toggle input:checked + .icon-toggle-slider .icon-right {
color: #333; color: #fff;
font-weight: bold;
} }
.icon-toggle input:focus + .icon-toggle-slider { .icon-toggle input:focus + .icon-toggle-slider {
@@ -1424,7 +1430,7 @@ footer {
.action-bar-content { .action-bar-content {
grid-template-columns: 1fr; grid-template-columns: 1fr;
gap: 1rem; gap: 1rem;
padding: 1rem; padding: 0rem;
} }
.language-toggle, .language-toggle,
@@ -1445,6 +1451,22 @@ footer {
font-size: 0.9em; font-size: 0.9em;
margin-top: 15px; margin-top: 15px;
} }
/* ========== Hide header controls, show in menu ========== */
/* Keep language selector visible in header */
.view-controls-center {
display: none !important;
}
.action-buttons-right {
display: none !important;
}
/* Show controls and actions in hamburger menu */
.menu-controls-section,
.menu-actions-section {
display: block !important;
}
} }
.no-print {} .no-print {}
@@ -1666,67 +1688,9 @@ a:focus {
} }
/* =============================================== /* ===============================================
PRINT STYLES - TWO-PAGE LAYOUT PRINT STYLES - Handled by print.css
=============================================== */ =============================================== */
/* All print styles consolidated in /static/css/print.css */
@media print {
body {
background: white;
margin: 0;
padding: 0;
}
.action-bar {
display: none !important;
}
.cv-page {
box-shadow: none;
border: none;
margin: 0 auto;
transform: scale(1);
max-width: 100%;
page-break-after: always;
page-break-inside: avoid;
}
.cv-page.page-2 {
page-break-after: auto;
}
.page-content {
page-break-inside: avoid;
}
.cv-section {
page-break-inside: avoid;
}
/* Ensure footer only on page 2 */
.page-1 .cv-footer {
display: none !important;
}
.cv-footer {
page-break-inside: avoid;
background: #ddd !important;
color: #333 !important;
-webkit-print-color-adjust: exact;
print-color-adjust: exact;
}
a {
text-decoration: none;
font-weight: 800;
color: inherit;
}
/* Set up proper A4 page dimensions */
@page {
size: A4 portrait;
margin: 0.5in;
}
}
/* =============================================== /* ===============================================
SECTION STYLES FOR PAGE 2 SECTION STYLES FOR PAGE 2
@@ -2043,14 +2007,14 @@ a:focus {
/* Show menu when hovering menu itself OR when it has the hover class */ /* Show menu when hovering menu itself OR when it has the hover class */
.navigation-menu:hover, .navigation-menu:hover,
.navigation-menu.menu-hover { .navigation-menu.menu-hover {
max-height: 800px; /* Fixed height for consistent animation timing */ max-height: calc(100vh - 60px); /* Viewport height minus header + some spacing */
pointer-events: auto; /* Enable pointer events when visible */ pointer-events: auto; /* Enable pointer events when visible */
opacity: 1; opacity: 1;
} }
/* Legacy class for JS compatibility - keep for backward compatibility */ /* Legacy class for JS compatibility - keep for backward compatibility */
.navigation-menu.menu-open { .navigation-menu.menu-open {
max-height: 800px; max-height: calc(100vh - 60px);
pointer-events: auto; pointer-events: auto;
opacity: 1; opacity: 1;
} }
@@ -2090,16 +2054,15 @@ a:focus {
} }
/* Menu item action controls (Expand All, Collapse All) */ /* Menu item action controls (Expand All, Collapse All) */
.menu-item-action span { /* Removed centered text styling - action items now behave like regular menu items */
width: calc(100% - 65px);
text-align: center;
}
/* Remove extra padding - all menu items should align consistently */ /* Remove extra padding - all menu items should align consistently */
/* Submenu styles - hover triggered */ /* Submenu styles - hover triggered, opens to the right */
.menu-item-submenu { .menu-item-submenu {
position: relative; position: relative;
border-bottom: 1px solid rgba(0, 0, 0, 0.1);
padding: 0 0 1rem 0;
} }
.menu-item.has-submenu { .menu-item.has-submenu {
@@ -2109,41 +2072,176 @@ a:focus {
.submenu-arrow { .submenu-arrow {
transition: transform 0.2s ease; transition: transform 0.2s ease;
margin-left: auto;
} }
/* Show submenu on hover */ /* Rotate arrow slightly on hover */
.menu-item-submenu:hover .submenu-arrow { .menu-item-submenu:hover .submenu-arrow {
transform: rotate(180deg); transform: translateX(3px);
} }
.submenu-content { .submenu-content {
background-color: rgba(0, 0, 0, 0.02); position: fixed; /* Changed from absolute to fixed to break out of parent overflow */
max-height: 0; left: 278px; /* Slight overlap with menu to eliminate any gap */
overflow: hidden; background: #ffffff;
box-shadow: 2px 2px 10px rgba(0, 0, 0, 0.15);
border-radius: 8px;
min-width: 250px;
max-width: 300px;
opacity: 0; opacity: 0;
transition: max-height 0.4s ease-in-out, opacity 0.3s ease; visibility: hidden;
transform: translateX(-3px);
transition: all 0.3s ease;
z-index: 1000; /* Higher z-index to appear above everything */
padding: 0.5rem 0;
max-height: calc(100vh - 100px); /* Ensure it fits viewport */
overflow-y: auto; /* Scroll if content is too long */
} }
/* Show submenu when hovering the submenu container */ /* Show submenu when hovering the submenu container OR the submenu itself */
.menu-item-submenu:hover .submenu-content { .menu-item-submenu:hover .submenu-content,
max-height: 600px; .submenu-content:hover {
opacity: 1; opacity: 1;
visibility: visible;
transform: translateX(0);
} }
/* Legacy class for JS compatibility */ /* Legacy class for JS compatibility */
.menu-item-submenu.submenu-open .submenu-arrow { .menu-item-submenu.submenu-open .submenu-arrow {
transform: rotate(180deg); transform: translateX(3px);
} }
.menu-item-submenu.submenu-open .submenu-content { .menu-item-submenu.submenu-open .submenu-content {
max-height: 600px;
opacity: 1; opacity: 1;
visibility: visible;
transform: translateX(0);
} }
.submenu-content .menu-item { .submenu-content .menu-item {
padding-left: 3rem; padding: 0.875rem 1.5rem;
font-size: 0.9rem; font-size: 0.9rem;
border-left-width: 2px; border-left: 3px solid transparent;
border-radius: 0;
}
.submenu-content .menu-item:first-child {
border-top-left-radius: 8px;
border-top-right-radius: 8px;
}
.submenu-content .menu-item:last-child {
border-bottom-left-radius: 8px;
border-bottom-right-radius: 8px;
}
/* ========== Menu Sections with Separators ========== */
/* Quick Actions section - always visible */
.menu-section-wrapper {
padding: 0.5rem 1.5rem 1rem;
border-bottom: 1px solid rgba(0, 0, 0, 0.1);
}
/* Remove border from last visible section */
.menu-content > *:last-child,
.menu-content > div:last-child {
border-bottom: none !important;
}
/* ========== Menu Controls & Actions (Mobile) ========== */
/* Hidden by default, shown only on mobile (< 900px) */
.menu-controls-section,
.menu-actions-section {
display: none;
padding: 0.5rem 1.5rem 1rem;
border-bottom: 1px solid rgba(0, 0, 0, 0.1);
}
.menu-item-header {
display: flex;
align-items: center;
gap: 1rem;
padding: 0.875rem 0 0.875rem 0;
color: var(--text-dark);
font-size: 0.85rem;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.5px;
cursor: default;
}
/* Disable hover effect for headers */
.menu-item-header:hover {
background-color: transparent !important;
color: var(--text-dark) !important;
border-left-color: transparent !important;
}
.menu-item-header iconify-icon {
color: var(--text-gray);
flex-shrink: 0;
}
.menu-item-header:hover iconify-icon {
color: var(--text-gray) !important;
}
.menu-item-header span {
flex: 1;
}
.menu-control-item {
display: flex;
align-items: center;
justify-content: space-between;
padding: 0.75rem 0;
}
.menu-control-label {
display: flex;
align-items: center;
gap: 0.75rem;
color: var(--text-dark);
font-size: 0.9rem;
font-weight: 500;
}
.menu-control-label iconify-icon {
color: var(--text-gray);
}
.menu-action-btn {
display: flex;
align-items: center;
justify-content: center;
gap: 1rem;
padding: 0.875rem 1rem;
margin: 0.25rem 0;
background: rgba(0, 0, 0, 0.03);
border: none;
border-radius: 8px;
color: var(--text-dark);
text-decoration: none;
font-size: 0.9rem;
font-weight: 500;
cursor: pointer;
transition: all 0.2s ease;
width: 100%;
}
.menu-action-btn:hover {
background: rgba(0, 102, 204, 0.08);
color: var(--accent-blue);
text-decoration: none;
}
.menu-action-btn iconify-icon {
color: var(--text-gray);
flex-shrink: 0;
transition: color 0.2s ease;
}
.menu-action-btn:hover iconify-icon {
color: var(--accent-blue);
} }
/* Section icons in titles */ /* Section icons in titles */
+495 -73
View File
@@ -1,31 +1,80 @@
/* Print Styles - A4 Optimized */ /* Print Styles - A4 Optimized - Consolidated & Fixed */
@media print { @media print {
/* ===================================
CRITICAL: Print Color Accuracy
=================================== */
* { * {
-webkit-print-color-adjust: exact !important; -webkit-print-color-adjust: exact !important;
print-color-adjust: exact !important; print-color-adjust: exact !important;
color-adjust: exact !important; color-adjust: exact !important;
} }
/* ===================================
PAGE SETUP - A4 with Minimal Margins
=================================== */
@page { @page {
size: A4; size: A4 portrait;
margin: 0; margin: 8mm; /* Minimal printer margins */
} }
body { body {
background: white; background: white !important;
margin: 0; margin: 0 !important;
padding: 0; padding: 0 !important;
} }
/* Hide non-print elements */ /* ===================================
HIDE NON-PRINT ELEMENTS
=================================== */
.no-print, .no-print,
.action-bar, .action-bar,
footer { .navigation-menu,
.hamburger-btn,
footer,
.back-to-top,
.info-button,
.info-modal,
.error-toast,
.cv-sidebar,
.cv-sidebar-left,
.cv-sidebar-right,
.cv-title-badges-header,
.cv-footer {
display: none !important; display: none !important;
} }
/* CV Container - full page */ /* Hide ALL icons in print */
iconify-icon,
.section-icon,
.default-company-icon,
.default-project-icon,
.default-course-icon,
.default-award-icon {
display: none !important;
}
/* Hide company/project/course logos */
.company-logo,
.project-icon,
.course-icon,
.award-logo {
display: none !important;
}
/* ===================================
REMOVE ALL SHADOWS & BORDERS (Nuclear Option)
=================================== */
*,
*::before,
*::after {
box-shadow: none !important;
text-shadow: none !important;
}
/* ===================================
CV CONTAINER - Full Page Width
=================================== */
.cv-container { .cv-container {
width: 100%; width: 100%;
max-width: 100%; max-width: 100%;
@@ -34,53 +83,166 @@
gap: 0; gap: 0;
} }
.cv-container.theme-clean {
padding: 0;
}
/* ===================================
CV PAPER - Reduced Padding (20mm → 12mm)
=================================== */
.cv-paper { .cv-paper {
width: 210mm; width: 100%;
min-height: 297mm; min-height: auto !important;
background: white; background: white !important;
padding: 20mm; padding: 12mm !important; /* Reduced from 20mm */
box-shadow: none; box-shadow: none !important;
margin: 0; border: none !important;
margin: 0 !important;
page-break-after: auto; page-break-after: auto;
transform: none !important;
} }
/* Force page breaks where needed */ /* ===================================
CV PAGE - Remove All Decorations & Page Breaks
=================================== */
.cv-page,
.theme-clean .cv-page {
box-shadow: none !important;
border: none !important;
background: white !important;
margin: 0 !important;
padding: 0 !important;
transform: scale(1) !important;
max-width: 100% !important;
page-break-after: auto !important; /* Let content flow naturally */
page-break-inside: auto !important; /* Allow breaking inside */
}
.cv-page.page-2 {
page-break-after: auto !important;
}
/* ===================================
PAGE CONTENT GRID - Allow Natural Flow
=================================== */
.page-content {
page-break-inside: auto !important; /* Allow content to break naturally */
display: block !important; /* Remove grid for print */
}
/* ===================================
PAGE BREAKS - Optimized for Content Flow
=================================== */
.page-break { .page-break {
page-break-after: always; page-break-after: auto !important; /* Remove forced page breaks */
break-after: auto !important;
} }
/* Sections CAN break across pages - flow naturally */
.cv-section {
page-break-inside: auto !important;
break-inside: auto !important;
page-break-before: auto !important; /* No forced breaks before sections */
page-break-after: auto !important; /* No forced breaks after sections */
}
/* Keep individual items together */
.avoid-break, .avoid-break,
.cv-section,
.experience-item, .experience-item,
.project-item { .project-item,
page-break-inside: avoid; .course-item,
.award-item {
page-break-inside: avoid !important;
break-inside: avoid !important;
} }
/* Header */ /* Experience section should flow into Awards - no page break */
#experience {
page-break-after: auto !important;
}
/* ===================================
HEADER - Reduced Spacing
=================================== */
.cv-header { .cv-header {
page-break-after: avoid; page-break-after: avoid;
margin-bottom: 15mm; margin-bottom: 8mm !important; /* Reduced from 15mm */
}
.cv-header-content {
gap: 1.5rem !important;
} }
.cv-name { .cv-name {
font-size: 20pt; font-size: 20pt;
margin-bottom: 4pt;
} }
.cv-title { .cv-title {
font-size: 12pt; font-size: 12pt;
} }
.cv-photo { .years-experience,
width: 80px; .cv-experience-years {
height: 80px; font-size: 10pt;
border-width: 2px; }
/* ===================================
PHOTO - FIXED ASPECT RATIO (3:4 Portrait)
=================================== */
.cv-photo {
width: 60px !important;
height: 80px !important; /* Maintains 3:4 ratio */
object-fit: contain !important; /* Show full photo, no crop */
border: none !important; /* Remove border */
box-shadow: none !important;
margin: 10px 15px 10px 10px !important;
page-break-inside: avoid;
}
.cv-photo img {
width: 100%;
height: 100%;
object-fit: contain !important;
}
/* ===================================
INTRO TEXT
=================================== */
.intro-text {
font-size: 9pt;
line-height: 1.5;
margin-top: 3mm !important;
}
/* ===================================
SECTIONS - REDUCED SPACING (48px → 19px)
=================================== */
.cv-section {
margin-bottom: 5mm !important; /* ~19px, down from 48px */
margin-top: 7mm !important; /* More breathing space between sections */
} }
/* Sections */
.section-title { .section-title {
font-size: 12pt; font-size: 12pt !important; /* Equalized size for all titles */
margin-top: 10mm; font-weight: 600 !important;
margin-top: 0 !important;
margin-bottom: 1mm !important; /* Minimal bottom margin - matches Training/Skills */
page-break-after: avoid; page-break-after: avoid;
border-bottom: 0.5pt solid #dddddd !important;
padding-bottom: 2mm !important;
padding-top: 2mm !important; /* Breathing space above */
line-height: 1.3 !important; /* Consistent line height */
}
/* Languages and References need more breathing space below title */
#languages .section-title,
#references .section-title {
margin-bottom: 3mm !important; /* More space for lists */
}
.section-icon {
display: none; /* Hide section icons in print */
} }
.summary-text { .summary-text {
@@ -88,40 +250,174 @@
line-height: 1.5; line-height: 1.5;
} }
/* Experience */ /* ===================================
EXPERIENCE - REDUCED SPACING (60px → 26px)
=================================== */
.experience-item { .experience-item {
margin-bottom: 8mm; margin-bottom: 4mm !important; /* ~15px, down from 40px */
padding-bottom: 8mm; padding-bottom: 3mm !important; /* ~11px, down from 32px */
border-bottom: 0.5pt solid #dddddd !important;
}
.experience-item:last-child {
border-bottom: none !important;
margin-bottom: 0 !important; /* Remove bottom margin from last experience */
padding-bottom: 2mm !important; /* Minimal padding */
} }
.position { .position {
font-size: 10pt; font-size: 10pt;
margin-bottom: 2pt;
} }
.company { .company,
.company-link {
font-size: 9pt; font-size: 9pt;
} }
.experience-period { .experience-period,
.experience-location,
.experience-duration {
font-size: 8pt; font-size: 8pt;
} }
.short-desc, .short-desc {
.responsibilities li { font-size: 9pt !important;
font-size: 9pt; line-height: 1.4 !important;
line-height: 1.4; margin-top: 1mm !important;
margin-bottom: 1mm !important;
} }
.responsibilities {
margin-top: 2mm;
}
.responsibilities li {
font-size: 9pt !important;
line-height: 1.4 !important;
margin-bottom: 1mm;
}
/* Ensure all experience content is properly sized */
.experience-item p,
.experience-item div {
font-size: 9pt !important;
line-height: 1.4 !important;
}
/* All logos already hidden above - no exceptions */
/* ===================================
PROJECTS & COURSES
=================================== */
.project-item,
.course-item,
.award-item {
display: block !important; /* Remove flex/grid layouts for print */
margin-bottom: 4mm !important;
padding-bottom: 3mm !important;
border-bottom: 0.5pt solid #dddddd !important;
}
.project-item:last-child,
.course-item:last-child,
.award-item:last-child {
border-bottom: none !important; /* Remove border from last item */
}
/* Projects footer - "See all projects" link */
.projects-footer {
margin-top: 4mm !important;
padding-top: 3mm !important;
text-align: center !important;
font-size: 9pt !important;
border-top: 0.5pt solid #dddddd !important; /* Single separator */
}
.projects-footer p {
margin: 0 !important;
padding: 2mm 0 !important;
}
.projects-footer a {
color: #0066cc !important;
text-decoration: none !important;
font-weight: 600 !important;
}
/* Icons/logos already hidden - display: none above */
/* Consistent item titles */
.project-title,
.course-title,
.award-item strong,
.course-item strong {
font-size: 10pt !important;
font-weight: 600 !important;
line-height: 1.3 !important;
display: block !important;
margin-bottom: 1mm !important;
}
.project-desc,
.course-desc,
.award-desc {
font-size: 9pt !important;
line-height: 1.4 !important;
margin-top: 1mm !important;
}
/* Course/Project headers - match Experience spacing */
.course-header,
.project-header {
margin-bottom: 0.5mm !important; /* Minimal spacing */
}
.course-item small,
.project-item small {
font-size: 8pt !important;
color: #666 !important;
display: inline !important; /* Inline like experience dates */
margin-top: 0 !important;
margin-left: 0.5mm !important;
}
/* Course title styling to match experience */
.course-title {
font-size: 10pt !important;
font-weight: 600 !important;
line-height: 1.3 !important;
margin-bottom: 0.5mm !important;
}
/* Course metadata (date, location) - match experience style */
.course-period,
.course-location,
.course-separator {
font-size: 8pt !important;
color: #666 !important;
display: inline !important;
}
/* Ensure all text and paragraphs in course items are properly sized */
.course-item p,
.course-item div,
.project-item p,
.project-item div {
font-size: 9pt !important;
line-height: 1.4 !important;
margin-top: 1mm !important;
margin-bottom: 1mm !important;
}
.project-technologies,
.technologies { .technologies {
font-size: 8pt; font-size: 8pt;
} }
.company-logo { /* ===================================
width: 25px; EDUCATION & SKILLS
height: 25px; =================================== */
}
/* Education, Skills, etc */
.degree, .degree,
.skill-title, .skill-title,
.project-name { .project-name {
@@ -134,64 +430,190 @@
font-size: 8.5pt; font-size: 8.5pt;
} }
/* Certifications & Awards */ .education-item {
.cert-item, margin-bottom: 3mm;
.award-item {
font-size: 8.5pt;
margin-bottom: 2mm;
} }
/* Languages */ /* ===================================
CERTIFICATIONS & AWARDS
=================================== */
.cert-item,
.award-item {
margin-bottom: 3mm !important;
padding-bottom: 2mm !important;
}
.award-item strong,
.cert-item strong {
font-size: 10pt !important;
font-weight: 600 !important;
display: block !important;
margin-bottom: 1mm !important;
}
.award-item small,
.cert-item small {
font-size: 8pt !important;
color: #666 !important;
}
/* Ensure all award/cert content is properly sized */
.award-item p,
.award-item div,
.cert-item p,
.cert-item div {
font-size: 9pt !important;
line-height: 1.4 !important;
margin-top: 1mm !important;
margin-bottom: 1mm !important;
}
/* ===================================
LANGUAGES
=================================== */
.languages-list { .languages-list {
grid-template-columns: repeat(3, 1fr); display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 2mm;
} }
.language-item { .language-item {
font-size: 8.5pt; font-size: 9pt !important;
line-height: 1.3 !important;
margin-bottom: 1mm !important;
} }
/* Contact info */ .language-item small {
font-size: 8pt;
}
/* ===================================
REFERENCES & OTHER
=================================== */
.reference-item,
.other-content {
font-size: 9pt !important;
line-height: 1.3 !important;
margin-bottom: 1mm !important;
}
/* ===================================
CONTACT INFO
=================================== */
.cv-contact { .cv-contact {
font-size: 8.5pt; font-size: 8.5pt;
grid-template-columns: repeat(2, 1fr); grid-template-columns: repeat(2, 1fr);
gap: 2mm; gap: 2mm;
} }
/* Links - print URLs */ /* ===================================
CLEAN THEME - Full Width Main Content
=================================== */
.theme-clean .page-content,
.page-content {
display: block !important;
grid-template-columns: 1fr !important;
}
.theme-clean .cv-main,
.cv-main {
grid-column: 1 !important;
padding: 0 !important;
max-width: 100% !important;
}
/* ===================================
LINKS - Print Styling
=================================== */
a { a {
color: #0066cc; color: #0066cc;
text-decoration: none; text-decoration: none;
font-weight: 600;
} }
/* Ensure borders print */ /* ===================================
.cv-header { BADGES - Hidden for minimal print
border-bottom: 1.5pt solid #2d2d2d !important; =================================== */
.current-badge,
.expired-badge,
.maintained-badge {
display: none !important;
} }
.section-title { /* ===================================
border-bottom: 0.5pt solid #dddddd !important; CV LENGTH TOGGLE - Force Short Version for Print Friendly
=================================== */
/* Show short descriptions */
.cv-short .short-desc {
display: block !important;
font-size: 9pt;
line-height: 1.5;
margin-top: 2mm;
} }
.experience-item { /* Hide long-only content (detailed descriptions) */
border-bottom: 0.5pt solid #dddddd !important;
}
.experience-item:last-child {
border-bottom: none !important;
}
/* Print both short and long version content */
.cv-short .long-only, .cv-short .long-only,
.long-only {
display: none !important;
}
/* Hide responsibilities (detailed bullet points) */
.cv-short .responsibilities,
.responsibilities {
display: none !important;
}
/* Long version rules (should not apply, but just in case) */
.cv-long .short-desc {
display: none !important;
}
.cv-long .long-only { .cv-long .long-only {
display: block !important; display: block !important;
} }
.cv-short .short-desc { .cv-long .responsibilities {
display: none !important; display: block !important;
} }
/* Always print full CV in long mode */ /* ===================================
.cv-long .short-desc { THEME CLEAN - Minimal Print Mode
display: none !important; =================================== */
/* All sidebars, headers, footers already hidden above */
/* Main content takes full width */
/* ===================================
COLLAPSIBLE SECTIONS - Force Open
=================================== */
details {
display: block !important;
}
summary {
display: block !important;
list-style: none !important;
}
summary::after,
summary .section-title::after,
.sidebar-section summary::after {
display: none !important; /* Hide collapse indicators */
}
details > *:not(summary) {
display: block !important;
opacity: 1 !important;
max-height: none !important;
transform: none !important;
}
/* ===================================
ENSURE PROPER TEXT RENDERING
=================================== */
body,
.cv-paper {
font-smoothing: antialiased;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
} }
} }
+174 -32
View File
@@ -194,19 +194,12 @@
<!-- Navigation Menu (Hidden by default) --> <!-- Navigation Menu (Hidden by default) -->
<nav id="navigation-menu" class="navigation-menu no-print" role="navigation" aria-label="CV sections"> <nav id="navigation-menu" class="navigation-menu no-print" role="navigation" aria-label="CV sections">
<div class="menu-content"> <div class="menu-content">
<a href="#" class="menu-item menu-item-action" onclick="expandAllSections(event)"> <!-- CV Sections - Quick Navigation -->
<iconify-icon icon="mdi:arrow-expand-all" width="20" height="20"></iconify-icon>
<span>{{if eq .Lang "es"}}Expandir Todo{{else}}Expand All{{end}}</span>
</a>
<a href="#" class="menu-item menu-item-action" onclick="collapseAllSections(event)">
<iconify-icon icon="mdi:arrow-collapse-all" width="20" height="20"></iconify-icon>
<span>{{if eq .Lang "es"}}Colapsar Todo{{else}}Collapse All{{end}}</span>
</a>
<div class="menu-item-submenu"> <div class="menu-item-submenu">
<a href="#" class="menu-item has-submenu"> <a href="#" class="menu-item has-submenu">
<iconify-icon icon="mdi:menu" width="20" height="20"></iconify-icon> <iconify-icon icon="mdi:menu" width="20" height="20"></iconify-icon>
<span>{{if eq .Lang "es"}}Secciones CV{{else}}CV Sections{{end}}</span> <span>{{if eq .Lang "es"}}Secciones CV{{else}}CV Sections{{end}}</span>
<iconify-icon icon="mdi:chevron-down" width="16" height="16" class="submenu-arrow"></iconify-icon> <iconify-icon icon="mdi:chevron-right" width="16" height="16" class="submenu-arrow"></iconify-icon>
</a> </a>
<div class="submenu-content"> <div class="submenu-content">
<a href="#education" class="menu-item" onclick="scrollToSection('education')"> <a href="#education" class="menu-item" onclick="scrollToSection('education')">
@@ -247,6 +240,94 @@
</a> </a>
</div> </div>
</div> </div>
<!-- Quick Actions Section -->
<div class="menu-section-wrapper">
<div class="menu-item menu-item-header">
<iconify-icon icon="mdi:cog-outline" width="20" height="20"></iconify-icon>
<span>{{if eq .Lang "es"}}Acciones Rápidas{{else}}Quick Actions{{end}}</span>
</div>
<a href="#" class="menu-item menu-item-action" onclick="expandAllSections(event)">
<iconify-icon icon="mdi:arrow-expand-all" width="20" height="20"></iconify-icon>
<span>{{if eq .Lang "es"}}Expandir Todo{{else}}Expand All{{end}}</span>
</a>
<a href="#" class="menu-item menu-item-action" onclick="collapseAllSections(event)">
<iconify-icon icon="mdi:arrow-collapse-all" width="20" height="20"></iconify-icon>
<span>{{if eq .Lang "es"}}Colapsar Todo{{else}}Collapse All{{end}}</span>
</a>
</div>
<!-- View Controls in menu (visible only on mobile < 900px) -->
<div class="menu-controls-section">
<div class="menu-item menu-item-header">
<iconify-icon icon="mdi:tune-variant" width="20" height="20"></iconify-icon>
<span>{{if eq .Lang "es"}}Controles de Vista{{else}}View Controls{{end}}</span>
</div>
<!-- CV Length toggle -->
<div class="menu-control-item">
<label class="menu-control-label">
<iconify-icon icon="mdi:file-document-outline" width="20" height="20"></iconify-icon>
<span>{{if eq .Lang "es"}}Longitud{{else}}Length{{end}}</span>
</label>
<label class="icon-toggle">
<input type="checkbox" id="lengthToggleMenu" onchange="toggleCVLength()">
<span class="icon-toggle-slider">
<iconify-icon icon="mdi:file-document-outline" width="16" height="16" class="icon-left"></iconify-icon>
<iconify-icon icon="mdi:file-document-multiple-outline" width="16" height="16" class="icon-right"></iconify-icon>
</span>
</label>
</div>
<!-- Logo toggle -->
<div class="menu-control-item">
<label class="menu-control-label">
<iconify-icon icon="mdi:image-multiple-outline" width="20" height="20"></iconify-icon>
<span>{{if eq .Lang "es"}}Logos{{else}}Logos{{end}}</span>
</label>
<label class="icon-toggle">
<input type="checkbox" id="logoToggleMenu" checked onchange="toggleLogos()">
<span class="icon-toggle-slider">
<iconify-icon icon="mdi:image-off-outline" width="16" height="16" class="icon-left"></iconify-icon>
<iconify-icon icon="mdi:image-multiple-outline" width="16" height="16" class="icon-right"></iconify-icon>
</span>
</label>
</div>
<!-- Theme toggle -->
<div class="menu-control-item">
<label class="menu-control-label">
<iconify-icon icon="mdi:page-layout-sidebar-left" width="20" height="20"></iconify-icon>
<span>{{if eq .Lang "es"}}Vista{{else}}View{{end}}</span>
</label>
<label class="icon-toggle">
<input type="checkbox" id="themeToggleMenu" onchange="toggleTheme()">
<span class="icon-toggle-slider">
<iconify-icon icon="mdi:page-layout-sidebar-left" width="16" height="16" class="icon-left"></iconify-icon>
<iconify-icon icon="mdi:page-layout-body" width="16" height="16" class="icon-right"></iconify-icon>
</span>
</label>
</div>
</div>
<!-- Action Buttons in menu (visible only on mobile < 900px) -->
<div class="menu-actions-section">
<div class="menu-item menu-item-header">
<iconify-icon icon="mdi:lightning-bolt" width="20" height="20"></iconify-icon>
<span>{{if eq .Lang "es"}}Acciones{{else}}Actions{{end}}</span>
</div>
<a class="menu-action-btn" href="/export/pdf?lang={{.Lang}}" download>
<iconify-icon icon="mdi:download" width="20" height="20"></iconify-icon>
<span>{{if eq .Lang "es"}}Descargar como PDF{{else}}Download as PDF{{end}}</span>
</a>
<button class="menu-action-btn" onclick="printFriendly()">
<iconify-icon icon="mdi:leaf" width="20" height="20"></iconify-icon>
<span>{{if eq .Lang "es"}}Imprimir amigable{{else}}Print Friendly{{end}}</span>
</button>
</div>
</div> </div>
</nav> </nav>
@@ -361,6 +442,17 @@
menu.classList.remove('menu-hover'); menu.classList.remove('menu-hover');
hamburgerBtn.setAttribute('aria-expanded', 'false'); hamburgerBtn.setAttribute('aria-expanded', 'false');
}); });
// Position submenu dynamically
const submenuTrigger = document.querySelector('.menu-item-submenu');
const submenuContent = document.querySelector('.submenu-content');
if (submenuTrigger && submenuContent) {
submenuTrigger.addEventListener('mouseenter', function() {
const triggerRect = submenuTrigger.getBoundingClientRect();
submenuContent.style.top = `${triggerRect.top}px`;
});
}
}); });
// Legacy toggle function - kept for compatibility // Legacy toggle function - kept for compatibility
@@ -486,13 +578,21 @@
} }
function toggleCVLength() { function toggleCVLength() {
const toggle = document.getElementById('lengthToggle'); const headerToggle = document.getElementById('lengthToggle');
const menuToggle = document.getElementById('lengthToggleMenu');
const paper = document.querySelector('.cv-paper'); const paper = document.querySelector('.cv-paper');
// Get the state from whichever toggle was clicked
const isChecked = event?.target?.id === 'lengthToggleMenu' ? menuToggle?.checked : headerToggle?.checked;
// Sync both toggles
if (headerToggle) headerToggle.checked = isChecked;
if (menuToggle) menuToggle.checked = isChecked;
// Save current scroll position // Save current scroll position
const currentScrollY = window.scrollY || window.pageYOffset; const currentScrollY = window.scrollY || window.pageYOffset;
if (toggle.checked) { if (isChecked) {
paper.classList.add('cv-long'); paper.classList.add('cv-long');
paper.classList.remove('cv-short'); paper.classList.remove('cv-short');
localStorage.setItem('cv-length', 'long'); localStorage.setItem('cv-length', 'long');
@@ -509,13 +609,21 @@
} }
function toggleLogos() { function toggleLogos() {
const toggle = document.getElementById('logoToggle'); const headerToggle = document.getElementById('logoToggle');
const menuToggle = document.getElementById('logoToggleMenu');
const paper = document.querySelector('.cv-paper'); const paper = document.querySelector('.cv-paper');
// Get the state from whichever toggle was clicked
const isChecked = event?.target?.id === 'logoToggleMenu' ? menuToggle?.checked : headerToggle?.checked;
// Sync both toggles
if (headerToggle) headerToggle.checked = isChecked;
if (menuToggle) menuToggle.checked = isChecked;
// Save current scroll position // Save current scroll position
const currentScrollY = window.scrollY || window.pageYOffset; const currentScrollY = window.scrollY || window.pageYOffset;
if (toggle.checked) { if (isChecked) {
paper.classList.add('show-logos'); paper.classList.add('show-logos');
localStorage.setItem('cv-logos', 'show'); localStorage.setItem('cv-logos', 'show');
} else { } else {
@@ -530,10 +638,18 @@
} }
function toggleTheme() { function toggleTheme() {
const toggle = document.getElementById('themeToggle'); const headerToggle = document.getElementById('themeToggle');
const menuToggle = document.getElementById('themeToggleMenu');
const container = document.querySelector('.cv-container'); const container = document.querySelector('.cv-container');
if (toggle.checked) { // Get the state from whichever toggle was clicked
const isChecked = event?.target?.id === 'themeToggleMenu' ? menuToggle?.checked : headerToggle?.checked;
// Sync both toggles
if (headerToggle) headerToggle.checked = isChecked;
if (menuToggle) menuToggle.checked = isChecked;
if (isChecked) {
container.classList.add('theme-clean'); container.classList.add('theme-clean');
localStorage.setItem('cv-theme', 'clean'); localStorage.setItem('cv-theme', 'clean');
} else { } else {
@@ -542,25 +658,38 @@
} }
} }
// Print Friendly - applies Clean theme before printing // Print Friendly - Apply Clean Theme + Short Version for minimal printing
function printFriendly() { function printFriendly() {
const container = document.querySelector('.cv-container'); const container = document.querySelector('.cv-container');
const paper = document.querySelector('.cv-paper');
const wasClean = container.classList.contains('theme-clean'); const wasClean = container.classList.contains('theme-clean');
const wasLong = paper.classList.contains('cv-long');
// Apply clean theme for printing // Apply clean theme for minimal print (no sidebars, no header, no icons)
if (!wasClean) { if (!wasClean) {
container.classList.add('theme-clean'); container.classList.add('theme-clean');
} }
// Print // Force SHORT version for print (hide detailed content)
window.print(); paper.classList.remove('cv-long');
paper.classList.add('cv-short');
// Restore original theme after print dialog // Small delay to let CSS apply
setTimeout(() => { setTimeout(() => {
if (!wasClean) { window.print();
container.classList.remove('theme-clean');
} // Restore original theme and length after print dialog closes
}, 100); setTimeout(() => {
if (!wasClean) {
container.classList.remove('theme-clean');
}
// Restore original length
if (wasLong) {
paper.classList.remove('cv-short');
paper.classList.add('cv-long');
}
}, 100);
}, 50);
} }
// Initialize with saved preferences or defaults // Initialize with saved preferences or defaults
@@ -595,30 +724,43 @@
// Restore CV length preference // Restore CV length preference
const savedLength = localStorage.getItem('cv-length') || 'short'; const savedLength = localStorage.getItem('cv-length') || 'short';
if (savedLength === 'long') { const lengthChecked = savedLength === 'long';
if (lengthChecked) {
paper.classList.add('cv-long'); paper.classList.add('cv-long');
paper.classList.remove('cv-short'); paper.classList.remove('cv-short');
document.getElementById('lengthToggle').checked = true;
} else { } else {
paper.classList.add('cv-short'); paper.classList.add('cv-short');
paper.classList.remove('cv-long'); paper.classList.remove('cv-long');
document.getElementById('lengthToggle').checked = false;
} }
// Sync both header and menu toggles
const headerLengthToggle = document.getElementById('lengthToggle');
const menuLengthToggle = document.getElementById('lengthToggleMenu');
if (headerLengthToggle) headerLengthToggle.checked = lengthChecked;
if (menuLengthToggle) menuLengthToggle.checked = lengthChecked;
// Restore logos preference // Restore logos preference
const savedLogos = localStorage.getItem('cv-logos') || 'show'; const savedLogos = localStorage.getItem('cv-logos') || 'show';
if (savedLogos === 'show') { const logosChecked = savedLogos === 'show';
if (logosChecked) {
paper.classList.add('show-logos'); paper.classList.add('show-logos');
document.getElementById('logoToggle').checked = true;
} else { } else {
paper.classList.remove('show-logos'); paper.classList.remove('show-logos');
document.getElementById('logoToggle').checked = false;
} }
// Sync both header and menu toggles
const headerLogoToggle = document.getElementById('logoToggle');
const menuLogoToggle = document.getElementById('logoToggleMenu');
if (headerLogoToggle) headerLogoToggle.checked = logosChecked;
if (menuLogoToggle) menuLogoToggle.checked = logosChecked;
// Restore theme preference // Restore theme preference
const savedTheme = localStorage.getItem('cv-theme') || 'default'; const savedTheme = localStorage.getItem('cv-theme') || 'default';
if (savedTheme === 'clean') { const themeChecked = savedTheme === 'clean';
document.getElementById('themeToggle').checked = true; // Sync both header and menu toggles
const headerThemeToggle = document.getElementById('themeToggle');
const menuThemeToggle = document.getElementById('themeToggleMenu');
if (headerThemeToggle) headerThemeToggle.checked = themeChecked;
if (menuThemeToggle) menuThemeToggle.checked = themeChecked;
if (themeChecked) {
toggleTheme(); toggleTheme();
} }
}); });