- Fix infinite loop caused by byte-based string slicing on multi-byte chars
- Use rune-based operations for proper Unicode handling
- Add template functions: center, separator, box
- Box function creates rounded corners with dynamic width
- Account for emoji display width (2 chars) in calculations
- Make line width configurable via plainTextLineWidth constant
Plain text endpoint:
- Add /text route for plain text CV (for curl/AI crawlers)
- Use k3a/html2text library for HTML-to-text conversion
- Add Plain Text button to hamburger menu with UI translations
Contact form feature:
- Add ContactHandler with proper email service integration
- Add CSRF protection middleware
- Add rate limiting (5 submissions/hour per IP)
- Add honeypot and timing-based bot protection
- Add input validation with detailed error messages
- Add security logging middleware
- Add browser-only middleware for API protection
Code quality:
- Fix all golangci-lint errcheck warnings for w.Write calls
- Remove duplicate getClientIP functions
- Wire up ContactHandler in routes.Setup