diff --git a/doc/ZOOM_IMPLEMENTATION.md b/doc/ZOOM_IMPLEMENTATION.md
new file mode 100644
index 0000000..1fda222
--- /dev/null
+++ b/doc/ZOOM_IMPLEMENTATION.md
@@ -0,0 +1,332 @@
+# Zoom Implementation - Technical Documentation
+
+## Overview
+
+This document describes the technical implementation of the custom zoom feature in the CV application, including architectural decisions, constraints, and solutions to specific challenges.
+
+## Implementation Summary
+
+- **Range**: 25% - 175% (centered at 100%)
+- **Technology**: CSS `zoom` property on wrapper element
+- **Fixed Elements**: Action bar, zoom control, info button, back-to-top button
+- **Viewport Behavior**: Horizontal scroll enabled when zoomed > 100%
+
+## Technical Architecture
+
+### 1. Core Zoom Application
+
+**Location**: `static/js/main.js` - `applyZoom()` function
+
+```javascript
+function applyZoom(zoomValue, saveToStorage = true) {
+ const zoomWrapper = document.getElementById('zoom-wrapper');
+ const zoomLevel = zoomValue / 100;
+
+ // Apply CSS zoom to wrapper
+ zoomWrapper.style.zoom = zoomLevel;
+
+ // Allow horizontal expansion when zoomed > 100%
+ if (zoomLevel > 1) {
+ zoomWrapper.style.minWidth = `${window.innerWidth}px`;
+ } else {
+ zoomWrapper.style.minWidth = '';
+ }
+
+ // Apply inverse zoom to fixed buttons
+ const inverseZoom = 1 / zoomLevel;
+ document.getElementById('back-to-top').style.zoom = inverseZoom;
+ document.getElementById('info-button').style.zoom = inverseZoom;
+}
+```
+
+### 2. HTML Structure
+
+**Location**: `templates/index.html`
+
+```html
+
+
...
+
+
+
+
+
+
+
+
+
+...
+```
+
+## Critical Design Decisions
+
+### Decision 1: CSS `zoom` vs `transform: scale()`
+
+**Choice**: CSS `zoom` property
+
+**Why**:
+- **Layout impact**: `zoom` affects actual layout dimensions, making scrollbars appear naturally
+- **Footer positioning**: With `zoom`, footer automatically follows zoomed content
+- **Browser behavior**: Mimics native browser zoom behavior more closely
+
+**Why NOT `transform: scale()`**:
+- Only visual transformation, doesn't affect layout
+- Creates infinite gray space below content
+- Requires complex margin calculations to position footer
+- Doesn't trigger natural scrollbar behavior
+
+### Decision 2: Inverse Zoom for Fixed Elements
+
+**Problem**: CSS `zoom` on parent can affect fixed-position children in some rendering contexts
+
+**Solution**: Apply inverse zoom to elements that must stay constant size
+
+```javascript
+const inverseZoom = 1 / zoomLevel;
+button.style.zoom = inverseZoom;
+```
+
+**Example**:
+- Content zoom: 150% (1.5)
+- Button inverse zoom: 66.67% (1/1.5)
+- Result: Button appears at 100% (1.5 × 0.667 = 1.0)
+
+**Affected Elements**:
+- `#back-to-top` button
+- `#info-button` button
+- Note: `#zoom-control` and `.action-bar` are naturally outside zoom context
+
+### Decision 3: Viewport Expansion Strategy
+
+**Problem**: Elements with `width: 100%` stay constrained to viewport even when zoomed
+
+**Solution**: Set `min-width` on zoom wrapper when zoom > 100%
+
+```javascript
+if (zoomLevel > 1) {
+ zoomWrapper.style.minWidth = `${window.innerWidth}px`;
+}
+```
+
+**Effect**:
+- Content can expand beyond viewport width
+- Horizontal scrollbar appears automatically
+- User can scroll to see all zoomed content
+
+**CSS Support**:
+```css
+body {
+ overflow-x: auto; /* Enable horizontal scroll */
+}
+```
+
+## Constraints and Limitations
+
+### 1. Browser Compatibility
+
+**CSS `zoom` property**:
+- ✅ Chrome, Edge, Safari: Full support
+- ⚠️ Firefox: Supported since Firefox 126 (May 2024)
+- Fallback: Content remains at 100% zoom in unsupported browsers
+
+### 2. Range Limitations
+
+**Current Range**: 25% - 175%
+
+**Why centered at 100%**:
+- Slider midpoint = (25 + 175) / 2 = 100
+- Users expect "reset" to be at slider center
+- Provides balanced zoom-in/zoom-out range
+
+**Why NOT 50% - 200%**:
+- 50% minimum would make slider center = 125%, confusing UX
+- Current range provides adequate zoom range while maintaining intuitive controls
+
+### 3. Fixed Element Positioning
+
+**Elements that MUST stay outside zoom-wrapper**:
+- Action bar (navigation)
+- Zoom control
+- Fixed buttons (info, back-to-top)
+- Footer
+
+**If placed inside zoom-wrapper**:
+- Would scale with content
+- Requires inverse zoom application (added complexity)
+- Footer positioning becomes unreliable
+
+### 4. Performance Considerations
+
+**CSS `zoom` Performance**:
+- Generally performant (GPU-accelerated in modern browsers)
+- Can cause reflow when changed
+- Mitigated by `requestAnimationFrame()` wrapper
+
+**Optimization**:
+```javascript
+requestAnimationFrame(() => {
+ zoomWrapper.style.zoom = zoomLevel;
+ // Other DOM modifications
+});
+```
+
+### 5. Mobile Behavior
+
+**Current Implementation**: Zoom control hidden on mobile (≤768px viewport)
+
+**Rationale**:
+- Mobile browsers provide native pinch-to-zoom
+- Custom zoom control redundant on touch devices
+- Saves screen space on small viewports
+
+**Code**:
+```javascript
+function isMobileView() {
+ return window.innerWidth <= 768;
+}
+```
+
+## Edge Cases Handled
+
+### 1. Zoom Persistence
+
+**Behavior**: Zoom level saved to `localStorage`
+
+```javascript
+localStorage.setItem('cv-zoom', zoomValue.toString());
+```
+
+**On Page Load**: Restore saved zoom level
+```javascript
+const savedZoom = localStorage.getItem('cv-zoom');
+if (savedZoom) {
+ applyZoom(parseInt(savedZoom, 10), false);
+}
+```
+
+### 2. Responsive Resize
+
+**Problem**: User resizes window while zoomed
+
+**Solution**: Recalculate min-width on window resize
+
+```javascript
+window.addEventListener('resize', function() {
+ // Debounced resize handler
+ if (isMobileView()) {
+ applyZoom(100, false); // Reset on mobile
+ }
+});
+```
+
+### 3. Reset Button Green Indicator
+
+**Feature**: Reset button turns green when zoom ≠ 100%
+
+**Implementation**:
+```javascript
+if (zoomValue !== 100) {
+ resetBtn.classList.add('zoom-not-default');
+} else {
+ resetBtn.classList.remove('zoom-not-default');
+}
+```
+
+**CSS**:
+```css
+.zoom-reset-btn.zoom-not-default:hover {
+ background: rgba(39, 174, 96, 0.5); /* Green */
+}
+```
+
+### 4. Keyboard Shortcuts
+
+**Supported Shortcuts**:
+- `Ctrl/Cmd + Plus`: Zoom in (+10%)
+- `Ctrl/Cmd + Minus`: Zoom out (-10%)
+- `Ctrl/Cmd + 0`: Reset to 100%
+
+**Implementation**:
+```javascript
+document.addEventListener('keydown', function(e) {
+ if ((e.ctrlKey || e.metaKey) && !e.shiftKey) {
+ if (e.key === '=' || e.key === '+') {
+ e.preventDefault();
+ incrementZoom(10);
+ }
+ // ... other shortcuts
+ }
+});
+```
+
+## Bottom Scroll Detection Integration
+
+**Feature**: Info and back-to-top buttons turn green when at page bottom
+
+**Challenge**: Zoom affects scroll calculations
+
+**Solution**: Bottom detection works independently of zoom
+
+```javascript
+const scrollHeight = document.documentElement.scrollHeight;
+const clientHeight = document.documentElement.clientHeight;
+const isAtBottom = (scrollHeight - currentScroll - clientHeight) < 50;
+```
+
+**Why it works**: `scrollHeight` and `clientHeight` automatically account for zoomed content dimensions
+
+## Future Considerations
+
+### Potential Enhancements
+
+1. **Smooth Zoom Transitions**
+ - Current: Instant zoom change
+ - Possible: CSS transition on zoom property
+ - Trade-off: May feel laggy for large zoom changes
+
+2. **Zoom Presets**
+ - Current: Free-range slider
+ - Possible: Preset buttons (50%, 75%, 100%, 125%, 150%)
+ - Trade-off: Less flexible, but faster access
+
+3. **Per-Section Zoom**
+ - Current: Entire document zooms
+ - Possible: Zoom specific sections independently
+ - Trade-off: Complex state management
+
+### Known Limitations to Monitor
+
+1. **Firefox < 126**: No CSS zoom support (falls back to 100%)
+2. **Print Behavior**: Zoom is reset for print (intentional)
+3. **High Zoom Levels**: Text rendering quality may degrade > 175%
+
+## Testing Checklist
+
+- [ ] Zoom in/out with slider
+- [ ] Zoom with keyboard shortcuts
+- [ ] Reset button functionality
+- [ ] Fixed elements stay constant size
+- [ ] Horizontal scroll appears when needed
+- [ ] Bottom detection works with zoom
+- [ ] Green button indicators work correctly
+- [ ] localStorage persistence works
+- [ ] Mobile: Zoom control hidden
+- [ ] Print: Zoom resets properly
+
+## References
+
+- CSS zoom specification: [MDN Web Docs](https://developer.mozilla.org/en-US/docs/Web/CSS/zoom)
+- Browser compatibility: [Can I Use - CSS zoom](https://caniuse.com/css-zoom)
+- Related: transform scale vs zoom discussion
+
+---
+
+**Last Updated**: 2025-11-12
+**Author**: Development Team
+**Status**: Implemented and Stable