refactor: Modularize CSS into ITCSS architecture + update documentation
CSS Refactoring: - Split 2,287-line monolith into 6 focused modules - New structure: Navigation, Scroll, Buttons, Modals, Zoom, Breakpoints - Organized by ITCSS layers (Interactive + Responsive) - 245 lines saved through better organization - Site verified working at localhost:1999 New CSS Files: - 04-interactive/_navigation.css (357 lines, 8.2KB) - 04-interactive/_scroll-behavior.css (200 lines, 5.0KB) - 04-interactive/_buttons.css (184 lines, 4.7KB) - 04-interactive/_modals.css (487 lines, 16KB) - 04-interactive/_zoom-control.css (253 lines, 6.3KB) - 05-responsive/_breakpoints.css (561 lines, 14KB) Documentation Updates: - Added doc/12-CSS-ARCHITECTURE.md (comprehensive CSS guide) - Updated doc/README.md (new entry + correct numbering) - Updated tests/README.md (test count 8 → 27) - Updated tests/TEST-SUMMARY.md (coverage expansion) - Rewrote tests/mjs/README.md (complete test listing) Removed: - static/css/04-interactive/_remaining.css (replaced by modules)
This commit is contained in:
@@ -0,0 +1,561 @@
|
||||
/* ========================================
|
||||
Desktop: Ensure Sidebar Content Visible (>1280px)
|
||||
======================================== */
|
||||
|
||||
/* ========================================
|
||||
Responsive: Medium Screens (901px - 1023px)
|
||||
======================================== */
|
||||
|
||||
@media (min-width: 901px) and (max-width: 1023px) {
|
||||
|
||||
/* ========== 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;
|
||||
}
|
||||
|
||||
/* ========== 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 1rem; /* Keep padding consistent */
|
||||
min-width: 50px;
|
||||
font-size: 0; /* Hide actual text */
|
||||
overflow: visible;
|
||||
transition: font-size 0.3s ease; /* Slower animation */
|
||||
display: inline-flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
/* 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;
|
||||
transition: opacity 0.3s ease; /* Slower animation */
|
||||
display: block;
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
/* On hover of INDIVIDUAL button only, show full text */
|
||||
.language-selector .selector-btn:hover {
|
||||
font-size: 1rem; /* Restore font size to show full text */
|
||||
min-width: auto;
|
||||
}
|
||||
|
||||
.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 !important;
|
||||
overflow: hidden !important;
|
||||
opacity: 0 !important;
|
||||
}
|
||||
|
||||
/* Show sidebar content on hover */
|
||||
.skill-category:hover .sidebar-content,
|
||||
.cv-sidebar-section:hover .sidebar-content {
|
||||
max-height: 1000px !important;
|
||||
opacity: 1 !important;
|
||||
margin-top: 10px !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;
|
||||
}
|
||||
|
||||
/* ========== 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 1rem; /* Keep padding consistent */
|
||||
min-width: 50px;
|
||||
font-size: 0; /* Hide actual text */
|
||||
overflow: visible;
|
||||
transition: font-size 0.3s ease; /* Slower animation */
|
||||
display: inline-flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
/* 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;
|
||||
transition: opacity 0.3s ease; /* Slower animation */
|
||||
display: block;
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
/* On hover of INDIVIDUAL button only, show full text */
|
||||
.language-selector .selector-btn:hover {
|
||||
font-size: 1rem; /* Restore font size to show full text */
|
||||
min-width: auto;
|
||||
}
|
||||
|
||||
.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 !important;
|
||||
overflow: hidden !important;
|
||||
opacity: 0 !important;
|
||||
}
|
||||
|
||||
/* Show sidebar content on hover */
|
||||
.skill-category:hover .sidebar-content,
|
||||
.cv-sidebar-section:hover .sidebar-content {
|
||||
max-height: 1000px !important;
|
||||
opacity: 1 !important;
|
||||
margin-top: 10px !important;
|
||||
}
|
||||
}
|
||||
|
||||
/* ========================================
|
||||
Responsive: Small Screens (up to 540px)
|
||||
======================================== */
|
||||
|
||||
/* ========================================
|
||||
Responsive: Tablet Screens - Center Photo (up to 768px)
|
||||
======================================== */
|
||||
|
||||
@media (max-width: 768px) {
|
||||
/* ========================================
|
||||
TYPOGRAPHY - Subtle font size reductions
|
||||
======================================== */
|
||||
.cv-name {
|
||||
text-align: center;
|
||||
font-size: 1.6rem;
|
||||
}
|
||||
|
||||
.years-experience {
|
||||
text-align: center;
|
||||
font-size: 1.1em;
|
||||
}
|
||||
|
||||
.section-title {
|
||||
font-size: 1.2em;
|
||||
}
|
||||
|
||||
.sidebar-title {
|
||||
font-size: 1.2em;
|
||||
}
|
||||
|
||||
.experience-period,
|
||||
.experience-separator,
|
||||
.experience-location,
|
||||
.experience-duration {
|
||||
font-size: 0.95rem;
|
||||
}
|
||||
|
||||
.position {
|
||||
font-size: 0.95rem;
|
||||
}
|
||||
|
||||
.short-desc,
|
||||
.responsibilities li {
|
||||
font-size: 0.85rem;
|
||||
}
|
||||
|
||||
/* ========================================
|
||||
TEXT ALIGNMENT FIXES - Selective alignment
|
||||
======================================== */
|
||||
/* Keep justified for intro and skills */
|
||||
.intro-text,
|
||||
.summary-text {
|
||||
text-align: justify;
|
||||
font-size: 0.85rem;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.intro-text {
|
||||
margin-top: 0;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
/* Left-align for course/project descriptions */
|
||||
.course-desc,
|
||||
.project-desc {
|
||||
text-align: left !important;
|
||||
font-size: 0.85rem !important;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
/* ========================================
|
||||
HEADER LAYOUT - Centered photo
|
||||
======================================== */
|
||||
.cv-header-content {
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 1rem;
|
||||
}
|
||||
|
||||
.cv-header-left {
|
||||
width: 100%;
|
||||
position: static;
|
||||
padding-right: 0;
|
||||
}
|
||||
|
||||
.cv-photo {
|
||||
position: static;
|
||||
width: auto;
|
||||
height: auto;
|
||||
max-width: 250px;
|
||||
margin: 1.5rem auto;
|
||||
text-align: center;
|
||||
right: auto;
|
||||
top: auto;
|
||||
}
|
||||
|
||||
.cv-photo img {
|
||||
width: 100%;
|
||||
height: auto;
|
||||
max-height: none;
|
||||
}
|
||||
|
||||
/* ========================================
|
||||
UNIFIED LOGO/ICON SIZING - Consistent 60px
|
||||
======================================== */
|
||||
.company-logo,
|
||||
.course-icon,
|
||||
.project-icon,
|
||||
.award-logo {
|
||||
width: 60px !important;
|
||||
height: 60px !important;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.company-logo img,
|
||||
.course-icon img,
|
||||
.project-icon img,
|
||||
.award-logo img {
|
||||
width: 60px !important;
|
||||
height: 60px !important;
|
||||
object-fit: contain;
|
||||
}
|
||||
|
||||
/* Default icons inherit base 80px size from _toggles.css */
|
||||
/* Removed !important to allow base styles to apply */
|
||||
|
||||
/* ========================================
|
||||
CONSISTENT ITEM LAYOUT - Uniform spacing
|
||||
======================================== */
|
||||
.experience-item,
|
||||
.course-item,
|
||||
.project-item,
|
||||
.award-item {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
gap: 1rem !important;
|
||||
align-items: flex-start;
|
||||
margin-bottom: 2rem !important;
|
||||
padding-bottom: 1.5rem !important;
|
||||
border-bottom: 1px solid rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.experience-item {
|
||||
margin-bottom: 1.8rem !important;
|
||||
}
|
||||
|
||||
.experience-content,
|
||||
.course-content,
|
||||
.project-content,
|
||||
.award-content {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
/* ========================================
|
||||
FONT SIZE CONSISTENCY - Titles and descriptions
|
||||
======================================== */
|
||||
.course-title,
|
||||
.project-title,
|
||||
.award-item strong {
|
||||
font-size: 0.95rem !important;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
.course-item small,
|
||||
.project-item small,
|
||||
.award-item small {
|
||||
font-size: 0.8rem !important;
|
||||
}
|
||||
|
||||
.course-desc,
|
||||
.project-desc,
|
||||
.award-desc {
|
||||
font-size: 0.85rem !important;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
/* ========================================
|
||||
RESPONSIBILITIES MOBILE OPTIMIZATION
|
||||
======================================== */
|
||||
.responsibilities li:has(img),
|
||||
.responsibilities li:has(iconify-icon) {
|
||||
grid-template-columns: 60px 1fr !important;
|
||||
gap: 0.75rem !important;
|
||||
margin-bottom: 0.75rem !important;
|
||||
}
|
||||
|
||||
.responsibilities li img,
|
||||
.responsibilities li iconify-icon.default-company-icon {
|
||||
width: 60px !important;
|
||||
height: 60px !important;
|
||||
}
|
||||
|
||||
/* ========================================
|
||||
SIDEBAR ITEMS MOBILE OPTIMIZATION
|
||||
======================================== */
|
||||
.language-item,
|
||||
.reference-item,
|
||||
.other-content {
|
||||
margin-bottom: 0 !important;
|
||||
line-height: 1.4 !important;
|
||||
margin-left: 1rem !important;
|
||||
font-size: 0.85rem !important;
|
||||
}
|
||||
}
|
||||
|
||||
/* ========================================
|
||||
Responsive: All Mobile Screens (up to 540px)
|
||||
======================================== */
|
||||
|
||||
@media (max-width: 540px) {
|
||||
/* Simplify action bar grid for mobile: single column */
|
||||
.action-bar-content {
|
||||
grid-template-columns: 1fr;
|
||||
gap: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
/* Hide center controls on mobile (moved to hamburger menu) */
|
||||
.view-controls-center {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* Hide action buttons on small screens (available in hamburger menu) */
|
||||
.action-buttons-right {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* Site title uses flexbox with percentage widths */
|
||||
.site-title {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
padding: 0 0.5rem;
|
||||
gap: 0.5rem;
|
||||
}
|
||||
|
||||
/* Left group (hamburger + title) takes ~50-60% */
|
||||
.site-title-left {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
flex: 1 1 1;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
/* Title link is flexible within left group */
|
||||
.site-title-link {
|
||||
flex: 1 1 auto;
|
||||
min-width: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.site-title-text {
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
/* Language selector takes ~30-35% */
|
||||
.language-selector {
|
||||
display: flex;
|
||||
flex: 0 0 35%;
|
||||
margin-left: auto;
|
||||
padding-left: 0;
|
||||
margin-right: 0;
|
||||
justify-content: flex-end;
|
||||
gap: 0.25rem;
|
||||
}
|
||||
|
||||
/* Hide year from title in mobile view */
|
||||
.site-title-year {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* Hide desktop logo, show mobile icon in title */
|
||||
.site-logo-link {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.site-icon-mobile {
|
||||
display: inline-flex;
|
||||
}
|
||||
|
||||
/* ========== Language Selector - Show Short Names Only ========== */
|
||||
.language-selector .selector-btn {
|
||||
position: relative;
|
||||
padding: 0.4rem 0.75rem;
|
||||
min-width: 40px;
|
||||
font-size: 0; /* Hide actual text */
|
||||
overflow: visible;
|
||||
transition: font-size 0.3s ease;
|
||||
display: inline-flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
/* Show only short version (EN/ES) */
|
||||
.language-selector .selector-btn::before {
|
||||
content: attr(data-short);
|
||||
font-size: 0.95rem;
|
||||
opacity: 1;
|
||||
transition: opacity 0.3s ease;
|
||||
display: block;
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
/* Keep short names on hover (no expansion) */
|
||||
.language-selector .selector-btn:hover {
|
||||
font-size: 0;
|
||||
min-width: 40px;
|
||||
}
|
||||
|
||||
.language-selector .selector-btn:hover::before {
|
||||
content: attr(data-short);
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user