feat: implement proper two-page CV layout matching original React design
**Page 1 Changes:** - Left sidebar with first half of skills categories - Main content: Personal info, Education, Skills summary, Experience - No footer on page 1 **Page 2 Changes:** - Main content: Awards, Courses, Languages, References, Other - Right sidebar with second half of skills categories - Footer with address, phone, email (dark gray #303030 background) - Same header as page 1 **Technical Implementation:** - Split skills between left/right sidebars using midpoint calculation in Go handler - CSS Grid layout: Page 1 (left sidebar + main), Page 2 (main + right sidebar) - Footer styled to match React CV exactly (centered, horizontal layout) - Print CSS with proper page breaks for A4 layout - Mobile responsive: stacks to single column, hides page 2 header - All links in References section are clickable **Data Model:** - Moved Languages, Courses, References, Other from sidebar to page 2 main content - Skills split evenly between SkillsLeft and SkillsRight template variables Matches pixel-perfect design from original React CV screenshot.
This commit is contained in:
@@ -728,3 +728,304 @@ a:focus {
|
||||
max-width: none;
|
||||
}
|
||||
}
|
||||
|
||||
/* ===============================================
|
||||
TWO-PAGE LAYOUT STYLES
|
||||
=============================================== */
|
||||
|
||||
/* Page Container - Each CV page */
|
||||
.cv-page {
|
||||
background: var(--paper-white);
|
||||
max-width: 1200px;
|
||||
margin: 2rem auto;
|
||||
box-shadow: 2px 2px 9px rgba(0,0,0,0.5);
|
||||
border: 1px solid #333;
|
||||
transform: scale(0.95);
|
||||
transform-origin: top center;
|
||||
transition: transform 0.3s ease;
|
||||
}
|
||||
|
||||
/* Page Content Grid */
|
||||
.page-content {
|
||||
display: grid;
|
||||
}
|
||||
|
||||
/* Page 1: Left sidebar + Main content */
|
||||
.page-1 .page-content {
|
||||
grid-template-columns: 300px 1fr;
|
||||
}
|
||||
|
||||
/* Page 2: Main content + Right sidebar */
|
||||
.page-2 .page-content {
|
||||
grid-template-columns: 1fr 300px;
|
||||
}
|
||||
|
||||
/* Sidebar positioning */
|
||||
.cv-sidebar-left {
|
||||
grid-column: 1;
|
||||
grid-row: 1;
|
||||
}
|
||||
|
||||
.cv-sidebar-right {
|
||||
grid-column: 2;
|
||||
grid-row: 1;
|
||||
}
|
||||
|
||||
/* Main content positioning */
|
||||
.page-1 .cv-main {
|
||||
grid-column: 2;
|
||||
grid-row: 1;
|
||||
}
|
||||
|
||||
.page-2 .cv-main {
|
||||
grid-column: 1;
|
||||
grid-row: 1;
|
||||
}
|
||||
|
||||
/* ===============================================
|
||||
FOOTER STYLES
|
||||
=============================================== */
|
||||
|
||||
.cv-footer {
|
||||
background: #303030;
|
||||
color: #ccc;
|
||||
padding: 20px 0;
|
||||
margin: 0;
|
||||
grid-column: 1 / -1; /* Span all columns */
|
||||
}
|
||||
|
||||
.footer-content {
|
||||
list-style: none;
|
||||
text-align: center;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.footer-content li {
|
||||
display: inline-block;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.footer-content li > div {
|
||||
display: inline-block;
|
||||
margin: 0 20px;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.footer-label {
|
||||
width: 200px;
|
||||
font-size: 1.7em;
|
||||
}
|
||||
|
||||
.footer-value {
|
||||
width: 450px;
|
||||
font-size: 1em;
|
||||
}
|
||||
|
||||
.footer-value b {
|
||||
font-weight: normal;
|
||||
font-size: 1.7em;
|
||||
}
|
||||
|
||||
.footer-separator {
|
||||
position: relative;
|
||||
left: -4%;
|
||||
font-size: 0.6em;
|
||||
}
|
||||
|
||||
.footer-separator i {
|
||||
opacity: 0.3;
|
||||
}
|
||||
|
||||
.cv-footer a {
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
.cv-footer a:hover {
|
||||
color: #0275d8;
|
||||
text-decoration: none;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
/* ===============================================
|
||||
PRINT STYLES - TWO-PAGE LAYOUT
|
||||
=============================================== */
|
||||
|
||||
@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
|
||||
=============================================== */
|
||||
|
||||
.award-item,
|
||||
.course-item,
|
||||
.language-item,
|
||||
.reference-item,
|
||||
.other-content {
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
|
||||
.award-item strong,
|
||||
.course-item strong,
|
||||
.language-item strong {
|
||||
font-weight: 600;
|
||||
color: var(--text-dark);
|
||||
}
|
||||
|
||||
.award-item small,
|
||||
.course-item small {
|
||||
color: #666;
|
||||
font-size: 0.875em;
|
||||
}
|
||||
|
||||
.award-desc,
|
||||
.course-desc {
|
||||
margin-top: 0.5em;
|
||||
color: var(--text-gray);
|
||||
font-size: 0.95em;
|
||||
}
|
||||
|
||||
.reference-item {
|
||||
margin-bottom: 0.5em;
|
||||
}
|
||||
|
||||
.reference-item a {
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.ref-type {
|
||||
color: #999;
|
||||
margin-left: 0.5em;
|
||||
font-size: 0.875em;
|
||||
}
|
||||
|
||||
/* ===============================================
|
||||
MOBILE RESPONSIVE - TWO-PAGE LAYOUT
|
||||
=============================================== */
|
||||
|
||||
@media (max-width: 900px) {
|
||||
.cv-page {
|
||||
margin: 1rem;
|
||||
transform: scale(1);
|
||||
}
|
||||
|
||||
/* Stack layout on mobile */
|
||||
.page-1 .page-content,
|
||||
.page-2 .page-content {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
.cv-sidebar-left,
|
||||
.cv-sidebar-right {
|
||||
grid-column: 1;
|
||||
}
|
||||
|
||||
.page-1 .cv-main,
|
||||
.page-2 .cv-main {
|
||||
grid-column: 1;
|
||||
}
|
||||
|
||||
/* Hide header on page 2 for mobile to merge pages */
|
||||
.page-2 .cv-title-badges-header {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* Adjust footer for mobile */
|
||||
.footer-content li > div {
|
||||
display: block;
|
||||
margin: 0;
|
||||
text-align: center;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.footer-label {
|
||||
font-size: 1em;
|
||||
margin-top: 15px;
|
||||
color: #777;
|
||||
}
|
||||
|
||||
.footer-separator {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.footer-value {
|
||||
font-size: 1.5em;
|
||||
margin-bottom: 0;
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* ===============================================
|
||||
TABLET RESPONSIVE
|
||||
=============================================== */
|
||||
|
||||
@media (max-width: 768px) and (min-width: 577px) {
|
||||
.page-content {
|
||||
gap: 1rem;
|
||||
}
|
||||
|
||||
.footer-label {
|
||||
font-size: 1.2em;
|
||||
}
|
||||
|
||||
.footer-value {
|
||||
font-size: 1em;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user