87e2c7a877
User reported intro text was in wrong position (inside Training section). Changes: - Moved intro text INSIDE cv-header-left div (GREEN BOX position) - Positioned right after "20 years of experience" - Removed duplicate Training section that showed summary - NO section heading - just the text flowing naturally CSS Updates: - Removed .cv-excerpt and .excerpt-text (wrong implementation) - Added .intro-text with exact styling from old React CV: * Font: Quicksand, 1.0em * Line height: 1.6 * Text align: justify * Style: italic * Margin-top: 20px * Color: rgb(51, 51, 51) - Added responsive styles for mobile (0.9em, 15px margin) Verified with Playwright analysis of old React CV. Intro text now appears exactly as in original implementation.
731 lines
13 KiB
CSS
731 lines
13 KiB
CSS
/* CV Design - Original Style Recreation */
|
|
|
|
/* Import Quicksand Font */
|
|
@import url('https://fonts.googleapis.com/css2?family=Quicksand:wght@400;500;600;700&family=Source+Sans+Pro:wght@400;600&display=swap');
|
|
|
|
:root {
|
|
--bg-gray: rgb(82, 86, 89);
|
|
--sidebar-gray: #d1d4d2;
|
|
--black-bar: #2b2b2b;
|
|
--paper-white: #ffffff;
|
|
--text-dark: rgb(0, 0, 0);
|
|
--text-gray: rgb(51, 51, 51);
|
|
--accent-blue: #0066cc;
|
|
--border-gray: #dddddd;
|
|
}
|
|
|
|
* {
|
|
margin: 0;
|
|
padding: 0;
|
|
box-sizing: border-box;
|
|
}
|
|
|
|
body {
|
|
font-family: 'Quicksand', 'Source Sans Pro', -apple-system, system-ui, sans-serif;
|
|
background-color: var(--bg-gray);
|
|
color: rgb(41, 43, 44);
|
|
line-height: 1.5;
|
|
font-size: 16px;
|
|
font-weight: 400;
|
|
}
|
|
|
|
a {
|
|
color: var(--accent-blue);
|
|
text-decoration: none;
|
|
}
|
|
|
|
a:hover {
|
|
text-decoration: underline;
|
|
}
|
|
|
|
/* Single Black Top Bar */
|
|
.action-bar {
|
|
background: var(--black-bar);
|
|
color: white;
|
|
position: sticky;
|
|
top: 0;
|
|
z-index: 100;
|
|
box-shadow: 0 2px 5px rgba(0,0,0,0.3);
|
|
}
|
|
|
|
.action-bar-content {
|
|
max-width: 1200px;
|
|
margin: 0 auto;
|
|
padding: 1rem 2rem;
|
|
display: grid;
|
|
grid-template-columns: 1fr auto 1fr;
|
|
align-items: center;
|
|
gap: 2rem;
|
|
}
|
|
|
|
.language-toggle {
|
|
display: flex;
|
|
gap: 0.5rem;
|
|
justify-self: start;
|
|
}
|
|
|
|
.lang-btn {
|
|
padding: 0.4rem 1rem;
|
|
border: 1px solid rgba(255,255,255,0.3);
|
|
background: transparent;
|
|
color: white;
|
|
border-radius: 3px;
|
|
cursor: pointer;
|
|
font-size: 0.875rem;
|
|
font-weight: 400;
|
|
text-transform: capitalize;
|
|
transition: all 0.2s ease;
|
|
}
|
|
|
|
.lang-btn:hover {
|
|
background: rgba(255,255,255,0.1);
|
|
border-color: rgba(255,255,255,0.5);
|
|
}
|
|
|
|
.lang-btn.active {
|
|
background: #27ae60 !important;
|
|
border-color: #27ae60 !important;
|
|
font-weight: 500;
|
|
}
|
|
|
|
.export-btn {
|
|
padding: 0.4rem 1rem;
|
|
background: transparent;
|
|
color: white;
|
|
border: 1px solid rgba(255,255,255,0.3);
|
|
border-radius: 3px;
|
|
cursor: pointer;
|
|
font-size: 0.875rem;
|
|
font-weight: 400;
|
|
transition: all 0.2s ease;
|
|
display: inline-flex;
|
|
align-items: center;
|
|
gap: 0.5rem;
|
|
text-decoration: none; /* For anchor tags */
|
|
}
|
|
|
|
.export-btn:hover {
|
|
background: rgba(255,255,255,0.1);
|
|
border-color: rgba(255,255,255,0.5);
|
|
text-decoration: none; /* Override default anchor hover */
|
|
}
|
|
|
|
/* CV Length Toggle - Center of action bar */
|
|
.cv-length-toggle {
|
|
display: flex;
|
|
gap: 0.5rem;
|
|
justify-self: center;
|
|
}
|
|
|
|
.length-btn {
|
|
padding: 0.4rem 1rem;
|
|
border: 1px solid rgba(255,255,255,0.4);
|
|
background: rgba(255,255,255,0.1);
|
|
color: white;
|
|
border-radius: 4px;
|
|
cursor: pointer;
|
|
font-size: 0.9rem;
|
|
font-weight: 500;
|
|
transition: all 0.2s ease;
|
|
}
|
|
|
|
.length-btn:hover {
|
|
background: rgba(255,255,255,0.2);
|
|
border-color: rgba(255,255,255,0.6);
|
|
}
|
|
|
|
.length-btn.active {
|
|
background: white;
|
|
color: #1a1a1a;
|
|
border-color: white;
|
|
font-weight: 600;
|
|
}
|
|
|
|
/* Action buttons on right */
|
|
.action-buttons {
|
|
display: flex;
|
|
gap: 0.5rem;
|
|
align-items: center;
|
|
justify-self: end;
|
|
}
|
|
|
|
/* Loading Indicator */
|
|
.htmx-indicator {
|
|
display: none;
|
|
}
|
|
|
|
.htmx-indicator.htmx-request {
|
|
display: inline-block;
|
|
}
|
|
|
|
.loader {
|
|
border: 2px solid #f3f3f3;
|
|
border-top: 2px solid white;
|
|
border-radius: 50%;
|
|
width: 20px;
|
|
height: 20px;
|
|
animation: spin 1s linear infinite;
|
|
}
|
|
|
|
@keyframes spin {
|
|
0% { transform: rotate(0deg); }
|
|
100% { transform: rotate(360deg); }
|
|
}
|
|
|
|
/* Main CV Container */
|
|
.cv-container {
|
|
width: 100%;
|
|
max-width: 1200px;
|
|
margin: 0 auto;
|
|
padding: 100px 0 0 0; /* Top padding to prevent sticky action bar overlap */
|
|
display: flex;
|
|
flex-direction: column;
|
|
}
|
|
|
|
/* CV Paper - Two-column layout with shadow */
|
|
.cv-paper {
|
|
width: 100%;
|
|
background: var(--paper-white);
|
|
box-shadow: 0 0 30px rgba(0,0,0,0.4);
|
|
margin: 0;
|
|
position: relative;
|
|
display: grid;
|
|
grid-template-columns: 300px 1fr;
|
|
grid-template-rows: auto 1fr;
|
|
min-height: 100vh;
|
|
}
|
|
|
|
/* Page break helpers */
|
|
.page-break {
|
|
page-break-after: always;
|
|
break-after: page;
|
|
}
|
|
|
|
.avoid-break {
|
|
page-break-inside: avoid;
|
|
break-inside: avoid;
|
|
}
|
|
|
|
/* Sidebar - Left column */
|
|
.cv-sidebar {
|
|
background: var(--sidebar-gray);
|
|
padding: 2rem 1.5rem;
|
|
font-size: 0.9rem;
|
|
}
|
|
|
|
.sidebar-section {
|
|
margin-bottom: 2rem;
|
|
}
|
|
|
|
.sidebar-title {
|
|
font-family: 'Quicksand', sans-serif;
|
|
font-size: 1.3em;
|
|
font-weight: 500;
|
|
line-height: 1.2em;
|
|
margin-bottom: 8px;
|
|
padding: 8px 0;
|
|
color: rgb(51, 51, 51);
|
|
}
|
|
|
|
.sidebar-content {
|
|
font-family: 'Quicksand', sans-serif;
|
|
font-size: 0.9em;
|
|
font-weight: 500;
|
|
line-height: 1.5;
|
|
}
|
|
|
|
.skill-item {
|
|
margin-bottom: 0.3rem;
|
|
color: rgb(0, 0, 0);
|
|
}
|
|
|
|
/* Main Content - Right column */
|
|
.cv-main {
|
|
background: var(--paper-white);
|
|
padding: 2rem 2.5rem;
|
|
}
|
|
|
|
/* Professional Title Badges - Spans Both Columns */
|
|
.cv-title-badges-header {
|
|
grid-column: 1 / -1; /* Span all columns */
|
|
background: #303030 !important; /* Elegant dark gray */
|
|
padding: 10px 20px;
|
|
display: flex;
|
|
flex-wrap: wrap;
|
|
justify-content: center;
|
|
align-items: center;
|
|
gap: 0;
|
|
border-bottom: 2px solid #34495e;
|
|
}
|
|
|
|
.title-badge {
|
|
font-size: 0.9em;
|
|
font-weight: normal;
|
|
color: #ccc;
|
|
text-transform: uppercase;
|
|
white-space: nowrap;
|
|
}
|
|
|
|
.badge-separator {
|
|
color: #ccc;
|
|
font-weight: normal;
|
|
padding: 0 15px;
|
|
position: relative;
|
|
top: -1px;
|
|
}
|
|
|
|
/* Header with photo and name */
|
|
.cv-header {
|
|
margin-bottom: 2rem;
|
|
}
|
|
|
|
.cv-header-content {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: flex-start;
|
|
gap: 2rem;
|
|
}
|
|
|
|
.cv-header-left {
|
|
flex: 1;
|
|
}
|
|
|
|
.cv-photo {
|
|
width: 150px;
|
|
height: 200px;
|
|
flex-shrink: 0;
|
|
overflow: hidden;
|
|
border: 3px solid white;
|
|
box-shadow: 0 2px 8px rgba(0,0,0,0.15);
|
|
}
|
|
|
|
.cv-photo img {
|
|
width: 100%;
|
|
height: 100%;
|
|
object-fit: cover;
|
|
}
|
|
|
|
.cv-name {
|
|
font-family: 'Quicksand', sans-serif;
|
|
font-size: 2.2em;
|
|
font-weight: 400;
|
|
line-height: 1.1;
|
|
margin-bottom: 8px;
|
|
color: rgb(0, 0, 0);
|
|
}
|
|
|
|
.cv-experience-years {
|
|
font-family: 'Quicksand', sans-serif;
|
|
font-size: 0.9em;
|
|
font-weight: 500;
|
|
line-height: 1.5;
|
|
color: rgb(0, 0, 0);
|
|
margin: 0;
|
|
}
|
|
|
|
/* Intro/Excerpt Text - Positioned inside header, matching old React CV */
|
|
.intro-text {
|
|
font-family: 'Quicksand', sans-serif;
|
|
font-size: 1.0em;
|
|
line-height: 1.6;
|
|
color: rgb(51, 51, 51);
|
|
margin-top: 20px;
|
|
text-align: justify;
|
|
font-style: italic;
|
|
}
|
|
|
|
/* Sections */
|
|
.cv-section {
|
|
margin-bottom: 2rem;
|
|
page-break-inside: avoid;
|
|
}
|
|
|
|
.section-title {
|
|
font-family: 'Quicksand', sans-serif;
|
|
font-size: 1.3em;
|
|
font-weight: 500;
|
|
line-height: 1.2em;
|
|
margin: 10px 0;
|
|
padding: 0;
|
|
color: rgb(51, 51, 51);
|
|
}
|
|
|
|
.summary-text {
|
|
font-family: 'Quicksand', sans-serif;
|
|
line-height: 1.5;
|
|
text-align: justify;
|
|
font-size: 0.9em;
|
|
font-weight: 400;
|
|
color: rgb(0, 0, 0);
|
|
}
|
|
|
|
/* Experience */
|
|
.experience-item {
|
|
margin-bottom: 1.5rem;
|
|
page-break-inside: avoid;
|
|
}
|
|
|
|
.experience-header {
|
|
margin-bottom: 0.6rem;
|
|
}
|
|
|
|
.experience-title-line {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: baseline;
|
|
gap: 1rem;
|
|
flex-wrap: wrap;
|
|
}
|
|
|
|
.position {
|
|
font-size: 1rem;
|
|
font-weight: 600;
|
|
margin: 0;
|
|
color: var(--text-dark);
|
|
}
|
|
|
|
.experience-period {
|
|
color: var(--text-gray);
|
|
font-size: 0.85rem;
|
|
font-style: italic;
|
|
}
|
|
|
|
.short-desc {
|
|
color: var(--text-dark);
|
|
font-size: 0.9rem;
|
|
line-height: 1.6;
|
|
margin-top: 0.5rem;
|
|
}
|
|
|
|
.responsibilities {
|
|
list-style: none;
|
|
margin-top: 0.5rem;
|
|
padding-left: 0;
|
|
}
|
|
|
|
.responsibilities li {
|
|
padding-left: 1.2rem;
|
|
margin-bottom: 0.4rem;
|
|
position: relative;
|
|
font-size: 0.9rem;
|
|
color: var(--text-dark);
|
|
line-height: 1.5;
|
|
}
|
|
|
|
.responsibilities li:before {
|
|
content: "•";
|
|
position: absolute;
|
|
left: 0;
|
|
color: var(--text-gray);
|
|
}
|
|
|
|
/* Education */
|
|
.education-item {
|
|
margin-bottom: 1rem;
|
|
font-size: 0.9rem;
|
|
line-height: 1.6;
|
|
color: var(--text-dark);
|
|
}
|
|
|
|
|
|
/* Languages */
|
|
.languages-list {
|
|
display: flex;
|
|
flex-wrap: wrap;
|
|
gap: 1.5rem;
|
|
}
|
|
|
|
.language-item {
|
|
font-size: 0.9rem;
|
|
color: var(--text-dark);
|
|
margin-bottom: 0.5rem;
|
|
}
|
|
|
|
.language-item small {
|
|
display: block;
|
|
font-size: 0.8em;
|
|
margin-top: 0.2rem;
|
|
font-style: italic;
|
|
}
|
|
|
|
/* Courses */
|
|
.course-item {
|
|
margin-bottom: 1rem;
|
|
padding-bottom: 0.8rem;
|
|
border-bottom: 1px solid rgba(0, 0, 0, 0.1);
|
|
}
|
|
|
|
.course-item:last-child {
|
|
border-bottom: none;
|
|
padding-bottom: 0;
|
|
margin-bottom: 0;
|
|
}
|
|
|
|
.course-item strong {
|
|
font-size: 0.95em;
|
|
color: var(--text-dark);
|
|
line-height: 1.3;
|
|
}
|
|
|
|
.course-item small {
|
|
display: block;
|
|
font-size: 0.85em;
|
|
color: var(--text-gray);
|
|
margin-top: 0.2rem;
|
|
}
|
|
|
|
.course-desc {
|
|
font-size: 0.85em;
|
|
color: var(--text-gray);
|
|
margin-top: 0.4rem;
|
|
line-height: 1.4;
|
|
text-align: justify;
|
|
}
|
|
|
|
/* References */
|
|
.reference-item {
|
|
margin-bottom: 0.6rem;
|
|
line-height: 1.4;
|
|
}
|
|
|
|
.reference-item a {
|
|
font-size: 0.9em;
|
|
color: var(--accent-blue);
|
|
text-decoration: none;
|
|
word-break: break-word;
|
|
}
|
|
|
|
.reference-item a:hover {
|
|
text-decoration: underline;
|
|
}
|
|
|
|
.ref-type {
|
|
display: block;
|
|
font-size: 0.8em;
|
|
color: var(--text-gray);
|
|
font-style: italic;
|
|
margin-top: 0.2rem;
|
|
}
|
|
|
|
/* Footer */
|
|
footer {
|
|
text-align: center;
|
|
padding: 2rem;
|
|
color: rgba(255,255,255,0.7);
|
|
font-size: 0.85rem;
|
|
}
|
|
|
|
|
|
/* CV Version Toggle Animations */
|
|
@keyframes fadeInGrow {
|
|
from {
|
|
opacity: 0;
|
|
max-height: 0;
|
|
transform: scaleY(0.8);
|
|
transform-origin: top;
|
|
}
|
|
to {
|
|
opacity: 1;
|
|
max-height: 5000px;
|
|
transform: scaleY(1);
|
|
}
|
|
}
|
|
|
|
@keyframes fadeOutShrink {
|
|
from {
|
|
opacity: 1;
|
|
max-height: 5000px;
|
|
transform: scaleY(1);
|
|
}
|
|
to {
|
|
opacity: 0;
|
|
max-height: 0;
|
|
transform: scaleY(0.8);
|
|
transform-origin: top;
|
|
}
|
|
}
|
|
|
|
/* Elements that appear/disappear */
|
|
.long-only,
|
|
.short-desc {
|
|
overflow: hidden;
|
|
transition: all 0.3s ease-in-out;
|
|
}
|
|
|
|
/* Short CV - Hide detailed content with animation */
|
|
.cv-short .long-only {
|
|
display: none;
|
|
animation: fadeOutShrink 0.3s ease-in-out;
|
|
}
|
|
|
|
.cv-short .short-desc {
|
|
display: block;
|
|
animation: fadeInGrow 0.3s ease-in-out;
|
|
}
|
|
|
|
/* Long CV - Hide short descriptions with animation */
|
|
.cv-long .short-desc,
|
|
.short-desc {
|
|
display: none;
|
|
animation: fadeOutShrink 0.3s ease-in-out;
|
|
}
|
|
|
|
.cv-long .long-only {
|
|
display: block;
|
|
animation: fadeInGrow 0.3s ease-in-out;
|
|
}
|
|
|
|
.cv-long .responsibilities {
|
|
display: block;
|
|
animation: fadeInGrow 0.3s ease-in-out;
|
|
}
|
|
|
|
/* Responsive - tablet/mobile */
|
|
@media (max-width: 900px) {
|
|
.cv-paper {
|
|
grid-template-columns: 1fr;
|
|
box-shadow: none;
|
|
}
|
|
|
|
.cv-sidebar {
|
|
padding: 1.5rem 1rem;
|
|
}
|
|
|
|
.cv-main {
|
|
padding: 1.5rem 1rem;
|
|
}
|
|
|
|
.cv-name {
|
|
font-size: 1.8rem;
|
|
}
|
|
|
|
.cv-photo {
|
|
width: 120px;
|
|
height: 150px;
|
|
}
|
|
|
|
.action-bar-content {
|
|
grid-template-columns: 1fr;
|
|
gap: 1rem;
|
|
padding: 1rem;
|
|
}
|
|
|
|
.language-toggle,
|
|
.cv-length-toggle,
|
|
.action-buttons {
|
|
justify-self: center !important;
|
|
justify-content: center;
|
|
width: 100%;
|
|
}
|
|
|
|
.experience-title-line {
|
|
flex-direction: column;
|
|
align-items: flex-start;
|
|
gap: 0.25rem;
|
|
}
|
|
|
|
.intro-text {
|
|
font-size: 0.9em;
|
|
margin-top: 15px;
|
|
}
|
|
}
|
|
|
|
.no-print {}
|
|
|
|
/* Smooth Transitions for HTMX Swaps */
|
|
.cv-paper {
|
|
transition: opacity 200ms ease-in-out;
|
|
}
|
|
|
|
.cv-paper.htmx-swapping {
|
|
opacity: 0;
|
|
}
|
|
|
|
.cv-paper.htmx-settling {
|
|
opacity: 1;
|
|
}
|
|
|
|
/* Focus Styles for Accessibility */
|
|
button:focus,
|
|
a:focus {
|
|
outline: 2px solid var(--accent-blue);
|
|
outline-offset: 2px;
|
|
}
|
|
|
|
/* Loading indicator animation */
|
|
@keyframes spin {
|
|
to { transform: rotate(360deg); }
|
|
}
|
|
|
|
/* Error Toast */
|
|
.error-toast {
|
|
position: fixed;
|
|
bottom: 2rem;
|
|
right: 2rem;
|
|
background: #fee2e2;
|
|
color: #dc2626;
|
|
padding: 1rem 1.5rem;
|
|
border-radius: 8px;
|
|
border-left: 4px solid #dc2626;
|
|
box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 1rem;
|
|
max-width: 400px;
|
|
z-index: 1000;
|
|
animation: slideIn 0.3s ease-out;
|
|
font-size: 0.95rem;
|
|
}
|
|
|
|
@keyframes slideIn {
|
|
from {
|
|
transform: translateX(120%);
|
|
opacity: 0;
|
|
}
|
|
to {
|
|
transform: translateX(0);
|
|
opacity: 1;
|
|
}
|
|
}
|
|
|
|
.error-icon {
|
|
font-size: 1.25rem;
|
|
flex-shrink: 0;
|
|
}
|
|
|
|
.error-toast button.error-close {
|
|
background: none;
|
|
border: none;
|
|
font-size: 1.5rem;
|
|
color: #dc2626;
|
|
cursor: pointer;
|
|
padding: 0;
|
|
width: 24px;
|
|
height: 24px;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
transition: opacity 0.2s;
|
|
flex-shrink: 0;
|
|
line-height: 1;
|
|
}
|
|
|
|
.error-toast button.error-close:hover {
|
|
opacity: 0.7;
|
|
}
|
|
|
|
.error-toast button.error-close:focus {
|
|
outline: 2px solid #dc2626;
|
|
outline-offset: 2px;
|
|
}
|
|
|
|
/* Mobile responsive error toast */
|
|
@media (max-width: 768px) {
|
|
.error-toast {
|
|
left: 1rem;
|
|
right: 1rem;
|
|
bottom: 1rem;
|
|
max-width: none;
|
|
}
|
|
}
|