Covers the full lifecycle: interface, SearchRequest/SearchResponse,
result building, graceful degradation, factory wiring, planner
registration, testing, and RSS parsing example.
Each engine now has a distinctive color accent applied to its result
card (left border) and engine badge (colored left strip + text).
16 engines mapped to brand-appropriate colors:
Google blue, Bing teal, DDG orange-red, Brave red, Qwant blue,
Wikipedia dark, GitHub purple, Reddit orange-red, YouTube red,
Stack Overflow amber, arXiv crimson, Crossref navy blue.
Pure CSS via data-engine attribute — no JavaScript.
Uses the Stack Exchange API v3 (/search/advanced) to find questions
sorted by relevance. No API key required (300 req/day); optionally
configure via STACKOVERFLOW_KEY env var or [engines.stackoverflow].
Results include score, answer count, view count, and tags in the
snippet. Assigned to the 'it' category, triggered by the IT category
tab or explicit engine selection.
6 tests covering parsing, edge cases, and helpers.
The project uses pure Go HTML templates + CSS. The React frontend
(frontend/), SPA handler (internal/spa/), and prebuilt binary (kafka)
were dead weight.
Also removes the frontend replacement plan/spec docs.
- Match .page-current padding to button padding (0 0.75rem)
- Add box-sizing: border-box to buttons
- Add margin/padding reset to pagination forms
- Simplify page-current flex layout
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Match padding and sizing for active page number and next button
to match inactive page buttons.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Simple preferences page with engine selection
- Light/dark theme toggle with localStorage persistence
- Clean form layout without complex JS dependencies
- Add dark theme CSS variables
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Wikipedia returns HTML entities like <span> which were being
double-escaped by Go templates. Now using html.UnescapeString and
template.HTML to render properly.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace React SPA with simple Go templates using search-zen-50
visual style. No JavaScript required - pure HTML/CSS with clean
teal accent color scheme, monospace logo, and minimal design.
- Simplified base.html without HTMX or autocomplete JS
- Clean homepage with centered search box
- Results page with sticky header and category tabs
- Simplified CSS matching search-zen-50 aesthetics
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add internal/spa package for embedding React build
- Wire SPA handler in main.go for non-API routes
- Add gitignore entry for internal/spa/dist
- Add implementation plan
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace template-based handlers (h.Index, h.Preferences) with the new spa
handler. API routes (healthz, search, autocompleter, opensearch.xml) are
registered first as exact matches, followed by the SPA catchall handler
for all other routes. Remove unused views and io/fs imports.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Creates internal/spa package that:
- Embeds React build output from cmd/kafka/dist/
- Provides HTTP handler for static file serving
- Falls back to index.html for SPA client-side routing
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Reverted CSS to the known-working state at 4b0cde9, then re-applied
only the image grid styles. The duplicate .results-layout block is
intentional — it was present in the working version too.
The old 3-column layout block (referencing .left-sidebar/.right-sidebar
classes that don't exist in the HTML) was overriding the correct layout
defined earlier. Removed the stale duplicate.
Three new image search engines:
- bing_images: Bing Images via RSS endpoint
- ddg_images: DuckDuckGo Images via VQD API
- qwant_images: Qwant Images via v3 search API
Frontend:
- Image grid layout with responsive columns
- image_item template with thumbnail, title, and source metadata
- Hover animations and lazy loading
- Grid activates automatically when category=images
Backend:
- category=images routes to image engines via planner
- Image engines registered in factory and engine allowlist
- extractImgSrc helper for parsing thumbnail URLs from HTML
- IsImageSearch flag on PageData for template layout switching
- results-layout: 3-column grid (1fr | min(768px,100%) | 300px) max-width 1400px, centered
- Widen center results column to 768px max
- Right column (formerly sidebar): sticky, contains knowledge panel + related searches
- Knowledge panel: Wikipedia/infobox summary with optional thumbnail
- Related searches: clickable links to refine the query
- Empty left buffer creates balanced whitespace on large screens
- Responsive: 2-col at 1000px, 1-col at 700px
New brave.go: scrapes https://search.brave.com directly.
Extracts title, URL, snippet, and favicon from Brave's HTML.
No API key required.
Rename existing BraveAPIEngine (was BraveEngine) to avoid collision
with the new scraper. API engine stays as 'braveapi', scraper as 'brave'.
The correct vendorHash for current go.mod is:
sha256-8wlKD+33s97oorCJTfHKAgE2Xp1HKXV+bSr6z29KrKM=
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The go.mod was updated with new replace directive for golang.org/x/net.
Need to recompute vendorHash.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Go's regexp package doesn't support Perl lookahead (?=...). Removing
the unnecessary lookahead since each MjjYud div is self-contained.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Wrap sidebar time/type filters in a form with HTMX attributes so
filter changes trigger partial page updates instead of full reload.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add tmplPreferences variable to views.go var block
- Initialize tmplPreferences in init() function
- Add RenderPreferences function to views.go
- Fix step numbering for Task 4
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>