- Remove unreleased Commando project from CV
- Add gotify-commander.png logo from GitHub repo
- "drolosoft" lowercase with link to drolosoft.com in summary
- Replace Certifications chip with Open source chip in chat
- Agent prompt rewritten to first person ("I worked at...", "I built...")
- Bot avatar replaced with dni-thumb.jpeg (2.6KB, 56x56 retina)
- Greeting: "Pregúntame lo que quieras sobre mi currículum"
- Underlined "mi currículum" with floating tooltip disclaimer
- Every response ends with cordial email contact invitation
- Background photos now visible in production (random per load)
- Toggle button remains dev-only
Dev-only toggle button enables/disables photo backgrounds. Photos are
auto-discovered from static/images/backgrounds/ and randomly selected
on each page load. Production is unaffected — no button, no photo.
- Clear phone field in both EN/ES JSON data
- Conditional rendering in footer, plain text, and JSON-LD
- Chat agent already configured to not reveal contact details
Header UX:
- Replace 5 icon buttons with single cog (gear) dropdown menu
- Cog menu shows all layout options with icons + labels
- Help and Close buttons stay visible outside the cog
- Active mode highlighted in green
Mobile fixes:
- Fix viewport overflow (100vw + max-width: 100vw)
- Stronger shadow (0 -4px 20px) for clear CV/chat separation
- Rounded corners (12px) on top for recognizable chat window
- Hide desktop-only modes (side panel, floating, full) from cog on mobile
- max-height: 50vh ensures CV always visible above
Dark mode:
- Cog menu styled for dark backgrounds
Mobile (≤480px):
- Hide Side Panel, Floating, Full Screen buttons
- Show Split button (50vh vertical split, CV visible above)
- Compact mode: 55vh max bottom sheet
- Force desktop modes to compact if somehow activated
- Disable tooltips on mobile (overflow prevention)
- Tighter header padding
Desktop (>480px):
- Split button hidden, all modes available as before
Tests: 85-chat-mobile.test.mjs — 79 assertions across
iPhone SE (320x568), iPhone 14 (393x852), iPhone 14 Pro Max (430x932),
plus desktop sanity check
- Fix side panel and full screen not covering full viewport
- Fix floating mode initial position (near chat button, not top-right)
- Reset width/height inline styles when switching modes
- Add 84-chat-layout-modes.test.mjs: 38 assertions covering
compact, side panel, full screen, floating, drag, rapid switching,
and user avatar rendering
- Add GLM-4.7-Flash as default Ollama model (replaces Mistral)
- Fix WRITE_TIMEOUT (15s→120s) and HTMX timeout (5s→120s) for local LLM
- Auto-warmup model on startup in development mode
- Add /api/chat/status endpoint for model readiness polling
- Show "Initializing AI model..." indicator while model loads
- Add user avatar (mdi:account) on chat messages
- Inject company/project/course sprite icons inline in chat responses
- Replace cramped header icons with 4 icon buttons + tooltips
(Compact, Side panel, Floating, Full screen)
- Add floating/draggable chat mode with smooth drag support
- Chip questions show user bubble instantly and clear input
- Help modal prefills input instead of auto-sending
- User bubble rendered client-side for immediate feedback
Bubbles:
- Teams-style layout: bot avatar (green circle) on left, message beside it
- User messages right-aligned, no avatar (clean, like Teams)
- Rounded bubbles (border-radius: 16px) instead of square
- Distinct corner radii for conversation flow
Navigation:
- Links no longer close the chat — panel stays open for continued navigation
- Added #certifications anchor (alias to courses section)
- Fixed agent instruction to use #courses for certifications references
Theme:
- All colors use CSS variables from _themes.css
- Automatically adapts to light/dark without explicit .theme-clean overrides
- Panel uses --paper-bg (white in light, dark in dark theme)
Size modes:
- 3 discrete toggle buttons: compact, half-screen, fullscreen
- Active state highlighted, direct selection (no confusing cycling)
- Removed chat-half-left (simplified to compact/half/full)
Intelligence:
- React query now returns results (verified: 4 companies + 2 projects + skills)
Avatars:
- Robot icon (green circle) before each agent message
- Person icon (dark circle) before each user message
- New .chat-bubble wrapper with flex layout for avatar + message
Dark theme fixes:
- Panel background: #1e1e1e (not pure black)
- Agent bubbles: #2d2d2d with light text (not dark/invisible)
- Input area: #2d2d2d (not black)
- Header stays green (--accent-green) in both themes
- Chips, suggestions consistent with panel background
Text overflow:
- overflow-wrap + word-break on messages
- min-width: 0 prevents flex overflow
- User bubble properly right-aligned with avatar
4 size modes cycled via expand button in header:
- Compact: 360px (default, bottom-right corner)
- Half-right: 50vw docked to right edge, full height
- Half-left: 50vw docked to left edge, full height
- Full: 100% viewport overlay
Also fixes text overflow in chat messages (overflow-wrap, word-break).
Messages area expands to fill available height in larger modes.
Size button uses mdi icons: arrow-expand, dock-right, dock-left, arrow-collapse.
CSS transitions for smooth size changes.
Agent instruction now requires markdown links to CV anchors:
- Companies: [Olympic Broadcasting](#exp-olympic-broadcasting)
- Projects: [Immich Photo Manager](#proj-immich-photo-manager)
- Sections: [Skills](#skills), [Experience](#experience)
formatResponse converts [text](#anchor) → clickable green links
that close the chat panel, smooth-scroll to the target, and
pulse a green highlight for 2 seconds.
All existing CV anchor IDs used: exp-{companyID}, proj-{projectID},
course-{courseID}, plus section IDs (experience, projects, skills, etc.)
Dual-provider architecture:
- Both Gemini and Ollama initialize at startup (if configured)
- Primary (Gemini) tried first for every request
- On any error (429, 503, timeout), automatically falls back to Ollama
- No manual switching needed — completely transparent to the user
- Log shows: "Primary failed (gemini: ...), falling back to ollama: ..."
Warmup:
- POST /api/chat/warmup called silently when chat panel opens
- Pre-loads Ollama model in background (10-15s) while user reads welcome
- By the time user types, model is ready for instant response
- Warms up fallback provider specifically (Gemini doesn't need it)
Timeout:
- Agent context increased to 60s (Ollama first response can be slow)
- Each request creates a fresh session (stateless for fallback compat)
The Hyperscript trigger/call commands couldn't reliably trigger HTMX
form submissions or call global JS functions. Moved all chat
interactions to plain JavaScript:
- toggleChatPanel(): open/close panel + icon swap
- sendChatQuestion(q): set input + htmx.trigger(form, 'submit')
- closeChatHelpAndAsk(q): close modal + open chat + send question
- htmx:afterRequest listener clears input after submit
Hyperscript kept only for site-wide patterns (closeOnBackdrop) that
work reliably.
Also: better error message for rate-limited API responses (429).
- Replace flat list with <details>/<summary> accordion (5 categories)
- Questions are clickable: close modal → open chat → send question
- closeChatHelpAndAsk() helper bridges modal and chat panel
- Green accent on category icons and question hover
- Chevron arrows for expand/collapse state
- Dark theme support for all accordion elements
- Compact layout with no wasted space
- Move chat-widget outside the floating buttons section in index.html
- Remove fixed-btn class from toggle button (was inheriting left-side
positioning from the button stack's mobile flex layout)
- Chat widget now renders independently just before body-scripts
Position fix:
- Remove _chat.css @import from main.css (was overriding with old
left:2rem cached version). Chat CSS now loaded only via head-styles.
- Button confirmed at right:2rem, bottom:6rem (above back-to-top)
Help modal:
- New chat-help-modal.html using same <dialog> pattern as shortcuts
- 6 organized categories: Experience, Technologies, Projects,
Education, Skills, How it works
- Bilingual EN/ES with example questions per category
- ? button in header opens modal via commandfor/show-modal
- Removed inline help card (modal replaces it)
Intelligence:
- Comprehensive query strategy for 8 question types
- Technology queries always use cross-section search
- Company queries use experience without filter for full listing
- Agent knows CV site is built with Go/HTMX (bonus context)
- Skills report proficiency levels when technology found
CSS:
- Button moved to right: 2rem, above back-to-top (bottom: 6rem)
- Uses CV design tokens: --black-bar, --accent-blue, --paper-bg
- Fonts: Quicksand (header), Source Sans Pro (body)
- Tooltip on the left side (tooltip-left class)
- Dark theme uses CV-consistent grays
Intelligence:
- Agent instruction emphasizes exhaustive reporting of ALL matches
- Cross-section search results must not be truncated
- Mentions CV site itself is built with Go when relevant
Tests:
- Updated positioning assertions (right side, x > viewport/2)
- Added 5 intelligence tests: Go cross-section, company count,
years of experience, React cross-section, Spanish response
- Resilient to API errors (waits for any message, not just user)
- 42 total test assertions
- Mascot identity: robot-happy-outline icon, "CV Assistant" branding
- Help popup: onboarding card explaining what the mascot can do (EN/ES)
- Suggested questions: 5 clickable chips that auto-submit (bilingual)
- Typing indicator: three bouncing dots during agent response
- Icon swap: mascot icon ↔ close icon via Hyperscript class toggle
- Dark theme support for all new elements
- Modular CSS loading in development, chat CSS always loaded separately
- agent.go: add section="search" that queries experience, projects,
skills, and courses simultaneously — fixes missing results when
a technology spans multiple CV sections (e.g. Java at Insa)
- head-styles.html: use modular CSS in development mode and load
chat CSS separately — fixes unstyled page when bundle is stale
Visitors can ask questions about the CV via a floating chat panel.
The agent uses Gemini to answer questions about experience, projects,
skills, and education by querying the cached CV JSON data.
- internal/chat/agent.go: LLM agent with query_cv tool that searches
CV data by section (experience, projects, skills, etc.) with keyword filtering
- internal/chat/handler.go: POST /api/chat endpoint with session management,
graceful degradation when GOOGLE_API_KEY is not set
- chat-widget.html: HTMX-powered floating chat panel with Hyperscript toggle
- _chat.css: Responsive chat UI with dark theme support
- Wired into existing architecture via dependency injection (CVHandler,
routes, main.go) — zero breaking changes, all existing tests pass
Main project URLs now point to drolosoft.com product pages with
language-aware links. GitHub repos are shown via a new badge next
to the existing LIVE badge.
Sprite icons (.icon-sprite.icon-section) had fixed 80px dimensions
while mobile breakpoint set container to 60px, causing overflow.
Added mobile-specific rules to scale sprites to 60px with proper
background-size and positioning calculations.
Replace simple search button with search bar design in action bar:
- Semi-transparent styling integrated with dark action bar
- Keyboard shortcut indicators (⌘ K) shown as individual kbd elements
- Search icon and "Search" text for better discoverability
- Responsive: kbd keys hidden on mobile (<900px)
- Remove unused cmd-k-button.html partial template
Update test to verify new search bar structure (styling, kbd elements, icon).
Reduces HTTP requests from 44+ individual images to 3 sprite sheets
(~93% reduction). Includes Go sprite generator tool, CSS classes,
template integration, and E2E tests.
- Add cmd/sprites/main.go for sprite generation (60x60px + 120x120px @2x)
- Add _sprites.css with responsive sizing and retina support
- Update templates to use sprites with logoIndex fallback
- Add Makefile targets: sprites, sprites-clean
- Add 9-test E2E suite for sprite functionality
- Add doc/22-SPRITES.md with usage documentation
Remove 557-line server-design.md from _go-learning/architecture - content is now covered in updated architecture documentation with real implementation examples and test coverage.
Remove cmd-k-btn (search) from floating action buttons - search now only
lives in the action bar. Recalculated positions for 7-button (desktop)
and 6-button (mobile without shortcuts) layouts using fluid clamp() sizing.
- Use event filtering [key is 'Enter' or key is ' '] on PDF modal cards
- Remove handlePdfCardKey helper function (now inline)
- Use event destructuring on keydown(key, target, ctrlKey, metaKey, altKey)
- Cleaner, more idiomatic hyperscript patterns
Replace verbose document.getElementById() and document.querySelectorAll()
with cleaner hyperscript syntax:
- #id for ID selectors
- .class and the first .class for class selectors
- <selector/> query literals for complex selectors
- #{variable} for dynamic ID interpolation
Files changed:
- utils._hs: scrollHeight, details, footer buttons, scrollToSection
- zoom._hs: all zoom control element selectors (14 changes)
- pdf-modal._hs: modal selector
- keyboard._hs: dynamic toggle and modal selectors
- contact-modal.html: response div and modal close
- index.html: ninja-keys bar selector
Replace 34-line IIFE/MutationObserver with:
- Hyperscript: on toggle if me.open call resetContactForm()
- 11-line resetContactForm() function
Also dispatches 'show' event from openModal() for ninja-keys integration.
All 7 contact form tests pass.
- Add aria-labels to menu action buttons (PDF, Print, Contact)
- Add aria-labelledby to toggle checkboxes (desktop + mobile)
- Add -webkit-user-select prefix for Safari compatibility
- Add DynamicCacheControl middleware for HTML pages
- Add accessibility test suite (60-accessibility.test.mjs)
- Add comprehensive accessibility documentation (21-ACCESSIBILITY.md)
- Update Modern Web Techniques doc to mark audit complete