Files
cv-site/doc/12-CSS-ARCHITECTURE.md
T
juanatsap 1258d61d05 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)
2025-11-20 12:34:42 +00:00

13 KiB

CSS Architecture Documentation

Overview

The CV site uses a modular CSS architecture based on ITCSS (Inverted Triangle CSS) principles, organized into layers from generic to specific styles. This approach ensures maintainability, scalability, and reduces specificity conflicts.

Directory Structure

static/css/
├── main.css                      # Entry point - imports all modules
├── 01-foundation/                # Base styles, variables, resets
│   ├── _reset.css               # CSS reset/normalize
│   ├── _variables.css           # CSS custom properties (colors, spacing)
│   ├── _typography.css          # Font definitions and text styles
│   └── _themes.css              # Theme variables (light/dark modes)
├── 02-layout/                    # Page structure and grids
│   ├── _container.css           # Container wrapper styles
│   ├── _page.css                # Page layout structure
│   ├── _grid.css                # Grid system
│   └── _paper.css               # CV paper/document styles
├── 03-components/                # UI components
│   ├── _action-bar.css          # Top action bar
│   ├── _sidebar.css             # Skills sidebar
│   ├── _cv-header.css           # CV header section
│   ├── _cv-section.css          # Generic CV sections
│   ├── _experience.css          # Work experience items
│   ├── _projects.css            # Projects section
│   ├── _courses.css             # Courses section
│   ├── _education.css           # Education section
│   └── _languages.css           # Languages section
├── 04-interactive/               # Interactive elements & HTMX patterns
│   ├── _toggles.css             # Toggle switches (theme, length, icons)
│   ├── _navigation.css          # Hamburger menu & navigation
│   ├── _scroll-behavior.css     # Scroll-based interactions
│   ├── _buttons.css             # Fixed action buttons
│   ├── _modals.css              # Modal dialogs
│   └── _zoom-control.css        # Zoom slider control
├── 05-responsive/                # Responsive breakpoints
│   └── _breakpoints.css         # Media queries for all screen sizes
├── 06-effects/                   # Visual effects
│   └── _skeleton.css            # Loading skeleton screens
└── 08-contexts/                  # Context-specific styles
    └── _print.css               # Print media styles

Layer Descriptions

01-foundation/ - Base Styles (Most Generic)

Purpose: Fundamental styles that affect the entire application.

  • _reset.css: Normalizes browser defaults for consistency
  • _variables.css: CSS custom properties (colors, spacing, z-index)
  • _typography.css: Font families, sizes, line heights
  • _themes.css: Theme-specific variables (light/dark/clean modes)

When to edit: Changing global colors, fonts, or spacing values.

02-layout/ - Structure

Purpose: Page-level layout and positioning systems.

  • _container.css: Main wrapper containers
  • _page.css: Page layout structure (multi-page CV)
  • _grid.css: Grid system for content organization
  • _paper.css: CV paper/document styling (cv-short, cv-long classes)

When to edit: Adjusting page structure, paper sizes, or grid systems.

03-components/ - UI Components

Purpose: Reusable UI components specific to CV sections.

Each file contains styles for a specific CV section:

  • Visual appearance (colors, borders, spacing)
  • Component-specific layouts
  • Section-specific icons and imagery

When to edit: Styling individual CV sections or components.

04-interactive/ - Interactive Elements

Purpose: User interactions, HTMX patterns, and dynamic behaviors.

_toggles.css (5.9 KB)

  • Theme toggles (light/dark/clean)
  • Length toggles (short/long CV)
  • Icon visibility toggles
  • Toggle switch component styles

_navigation.css (8.2 KB)

  • Hamburger button styling
  • Slide-out navigation menu
  • Menu items and submenus
  • Smooth scrolling behavior
  • Pure CSS hover-triggered menus

_scroll-behavior.css (5.0 KB)

  • Header hide/show on scroll direction
  • Back-to-top button
  • Info button (bottom-left)
  • Scroll-based visual changes

_buttons.css (4.7 KB)

  • Fixed action buttons:
    • Download button (PDF export)
    • Print-friendly button
    • Keyboard shortcuts button
    • Zoom toggle button
  • Mobile horizontal layout
  • At-bottom state changes

_modals.css (16 KB)

  • Info Modal: Project details dialog
  • Keyboard Shortcuts Modal: Shortcut reference
  • PDF Download Modal: Interactive thumbnail selection
  • Native <dialog> element styling
  • Glassmorphism effects
  • Accessibility features

_zoom-control.css (6.3 KB)

  • Zoom slider (50%-150%)
  • Reset button
  • Draggable positioning
  • Mobile auto-disable
  • localStorage persistence

When to edit: Adding new interactive features or HTMX swap patterns.

05-responsive/ - Responsive Design

Purpose: Media queries for different screen sizes.

_breakpoints.css (14 KB)

  • Desktop (>1280px): Full layout with sidebars
  • Medium (1024-1280px): Compact fonts, collapsible sidebars
  • Medium (901-1023px): EN/ES labels, icon-only buttons
  • Tablet (≤768px): Centered photo, larger touch targets
  • Mobile (≤540px): Single-column, hamburger menu only
  • Small Mobile (≤480px): Ultra-compact zoom control

When to edit: Adjusting responsive behavior at specific breakpoints.

06-effects/ - Visual Effects

Purpose: Animations, transitions, and loading states.

  • _skeleton.css: Loading skeleton screens for language transitions

When to edit: Adding new animations or loading states.

08-contexts/ - Context-Specific Styles

Purpose: Styles for specific contexts (print, email, etc.)

  • _print.css: Print-optimized styles (@media print)

When to edit: Adjusting print output or adding new contexts.

Import Order (main.css)

The import order follows the ITCSS inverted triangle - from generic to specific:

/* 01 - Foundation (most generic) */
@import './01-foundation/_reset.css';
@import './01-foundation/_variables.css';
@import './01-foundation/_typography.css';
@import './01-foundation/_themes.css';

/* 02 - Layout */
@import './02-layout/_container.css';
@import './02-layout/_page.css';
@import './02-layout/_grid.css';
@import './02-layout/_paper.css';

/* 03 - Components */
@import './03-components/_action-bar.css';
@import './03-components/_sidebar.css';
@import './03-components/_cv-header.css';
@import './03-components/_cv-section.css';
@import './03-components/_experience.css';
@import './03-components/_projects.css';
@import './03-components/_courses.css';
@import './03-components/_education.css';
@import './03-components/_languages.css';

/* 04 - Interactive */
@import './04-interactive/_toggles.css';
@import './04-interactive/_navigation.css';
@import './04-interactive/_scroll-behavior.css';
@import './04-interactive/_buttons.css';
@import './04-interactive/_modals.css';
@import './04-interactive/_zoom-control.css';

/* 05 - Responsive */
@import './05-responsive/_breakpoints.css';

/* 06 - Effects */
@import './06-effects/_skeleton.css';

/* 08 - Contexts (most specific) */
@import './08-contexts/_print.css';

⚠️ IMPORTANT: Do not change the import order. Later imports can override earlier ones based on specificity.

File Naming Conventions

  • Prefix with underscore: _filename.css indicates a partial file (imported by main.css)
  • Lowercase with hyphens: _action-bar.css (not _ActionBar.css or _action_bar.css)
  • Descriptive names: File name should clearly indicate its purpose

HTMX Integration

Interactive Elements Design

The 04-interactive layer is designed to work seamlessly with HTMX patterns:

  1. Atomic Swaps: Each component can be swapped independently
  2. Out-of-Band Updates: Modals and toggles support hx-swap-oob
  3. Loading States: Skeleton screens for async content transitions
  4. Progressive Enhancement: CSS-first approach with JavaScript fallbacks

Common HTMX Patterns

<!-- Toggle with out-of-band swap -->
<div hx-post="/toggle/theme"
     hx-target=".cv-container"
     hx-swap="outerHTML">
  <!-- Content updated by server -->
</div>

<!-- Modal trigger -->
<button onclick="document.getElementById('pdf-modal').showModal()">
  Download PDF
</button>

<!-- Navigation with smooth scroll -->
<a href="#experience" class="menu-item">
  Experience
</a>

Best Practices

1. Single Responsibility Principle

Each CSS file should have one clear purpose. Don't mix concerns.

Good: _buttons.css contains only button styles Bad: _buttons.css contains buttons + modals + forms

2. Component Isolation

Components should be self-contained and not depend on parent context.

Good:

.modal-close {
  position: absolute;
  top: 1rem;
  right: 1rem;
}

Bad:

.modal .close {  /* Requires .modal parent */
  position: absolute;
}

3. Mobile-First Responsive Design

Write mobile styles first, then add desktop enhancements.

Good:

.button { padding: 0.5rem; }

@media (min-width: 768px) {
  .button { padding: 1rem; }
}

4. CSS Custom Properties for Theming

Use variables for theme-specific values.

Good:

.button { background: var(--primary-color); }

Bad:

.button { background: #27ae60; }

5. Avoid Deep Nesting

Keep specificity low for easier overrides.

Good: .menu-item { } Bad: .navigation .menu .item { }

Adding New Styles

Adding a New Component

  1. Create new file in 03-components/:

    touch static/css/03-components/_my-component.css
    
  2. Add import to main.css in the components section:

    @import './03-components/_my-component.css';
    
  3. Write component styles:

    /* My Component - Description */
    .my-component {
      /* Styles here */
    }
    

Adding a New Interactive Pattern

  1. Determine if it fits an existing file or needs a new one

  2. If new file needed, create in 04-interactive/:

    touch static/css/04-interactive/_my-feature.css
    
  3. Add import to main.css after other interactive files

  4. Document HTMX integration patterns if applicable

Adding Responsive Styles

  1. Add media queries to 05-responsive/_breakpoints.css
  2. Group by breakpoint, not by component
  3. Use min-width for mobile-first approach

Performance Considerations

File Sizes

  • Total CSS: ~120 KB uncompressed
  • Main entry point: ~1.2 KB (imports only)
  • Largest files:
    • _modals.css (16 KB)
    • _breakpoints.css (14 KB)
    • _action-bar.css (13 KB)

Optimization Tips

  1. Browser caching: Modular files = better cache granularity
  2. Critical CSS: Consider inlining foundation layer for first paint
  3. Minification: Use CSS minifier in production
  4. HTTP/2: Leverages multiplexing for parallel file loading

Troubleshooting

Styles Not Applying

  1. Check import order: Later imports override earlier ones
  2. Check specificity: Use browser DevTools to see which rule wins
  3. Check file path: Ensure @import path is correct
  4. Clear browser cache: Hard refresh (Cmd+Shift+R / Ctrl+Shift+F5)

Modal Not Showing

  1. Check if <dialog> element is in DOM
  2. Verify .showModal() is called (not .show())
  3. Check z-index conflicts
  4. Inspect ::backdrop styling

Responsive Issues

  1. Check viewport meta tag in HTML:
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    
  2. Test at exact breakpoint values
  3. Use browser DevTools responsive mode
  4. Check for !important overrides

Migration History

v1.0 → v2.0 (Current)

Before (Monolithic):

  • Single _remaining.css file: 2,287 lines
  • Difficult to navigate and maintain
  • High merge conflict risk

After (Modular):

  • 6 focused files: 2,042 lines total
  • Clear separation of concerns
  • Better caching and collaboration
  • 245 lines saved through organization

Breaking Changes: None - CSS is backward compatible

Future Enhancements

Planned Improvements

  • CSS Modules for component scoping
  • CSS Container Queries for responsive components
  • View Transitions API for smooth page changes
  • CSS Nesting (when browser support improves)
  • Tailwind CSS integration (optional)

Considerations

  • Keep HTMX-friendly patterns
  • Maintain progressive enhancement
  • Preserve print stylesheet functionality
  • Ensure accessibility standards (WCAG AA)

References

Contributing

When adding new styles:

  1. Follow the established file structure
  2. Use CSS custom properties for theme values
  3. Write mobile-first responsive styles
  4. Test in multiple browsers
  5. Document complex interactions
  6. Update this documentation for structural changes

Last Updated: November 20, 2025 Version: 2.0 Maintainer: Development Team