Replaces the generated placeholder copy with language that better reflects
the site owner's values — deliberate in practice, restless in curiosity.
Adds the 'engineer errant' nod as a quiet eyebrow descriptor.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The desktop runner's ~/.docker/config.json uses credsStore: pass, which isn't
initialised, so docker login failed to store creds. Use a throwaway
DOCKER_CONFIG under RUNNER_TEMP (outside the build context) for the job.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Refactor the site container from a TLS-owning, port-binding proxy into an
internal plaintext static server that sits behind a dedicated edge reverse
proxy, and add an automated build/deploy pipeline.
- Caddyfile: single :80 listener (auto_https off), Host-matcher routing for
apex/blog/art/code with /_astro+/assets re-root and www->apex redirect
- Dockerfile: EXPOSE 80 only (TLS now handled by the edge proxy)
- compose.yml: pull registry image, join external 'edge' network, declare
routing via caddy-docker-proxy labels; drop build/ports/cert volumes
- compose.dev.yml: local container preview on :8080
- .forgejo/workflows/deploy.yml: push-to-main -> desktop runner builds, pushes
to the Forgejo registry, SSH-deploys to the VPS
- docs + .dockerignore updated for the new topology
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The featured article previously hid whenever a query was active,
regardless of whether it matched. Treat it as a normal [data-search]
row instead: visible iff it matches the query, and counted toward
visibleCount so a featured-only match no longer triggers the
"no entries match" message.
Closes the follow-up at
docs/superpowers/follow-ups/2026-06-02-blog-search-featured-match.md
and updates the design spec to match.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Adds light client-side keyword filter to /blog. Data-search attributes
on each post row (and the featured article) drive a small inline script
that hides non-matches as the reader types, collapses empty year heads,
and shows a no-results message. Keyboard shortcuts: / focuses, Esc
clears.
Known follow-up: featured article currently hides on any query; should
respect match state instead. See
docs/superpowers/follow-ups/2026-06-02-blog-search-featured-match.md.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- @astrojs/check + typescript bump are needed to run `npx astro check`,
which is the type-verification command used throughout this branch.
- docs/superpowers/plans/ pairs with the existing spec under specs/.
- docs/superpowers/follow-ups/ records the featured-match behaviour
change surfaced during manual test; addresses in a later branch.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Final-review findings:
- .is-hidden was scoped to blog/index.astro, so it didn't match PostRow
or YearHead roots (which carry their own component scope hashes). Net
effect: the filter visibly only hid the featured article, while all
archive rows + year heads stayed on screen. Wrap in :global() so the
runtime-toggled class actually fires its display rule everywhere.
- buildSearchText regex stripped > but not <, so inline HTML open-tags
like <span class="leadin"> leaked into data-search. Add < to the
character class so the haystack stays plain text.
- Add role="search" landmark to the BlogSearch wrapper so screen-reader
users can navigate to it directly.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Code review forward-proofing:
- Early-return on event.isComposing so the / shortcut doesn't disrupt
IME composition (multi-keystroke input methods).
- Treat <select> as editable so / doesn't steal focus while a dropdown
is open and the user is typing to seek.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Code review nits:
- .bsearch border-bottom + .feature border-top rendered a doubled
hairline; removed the bottom border (feature's top is sufficient).
- Renamed bsearch__input / bsearch__hint to binput / bhint to match
the project's flat single-class convention (postrow, pdate, yr, ln).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Code review nit: searchText (required) was appended after the optional
deck/tag, breaking the required-then-optional convention used by the
rest of the interface.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Tiny client-side filter on /blog using data-search attributes on each
row. No new deps, no JSON index, no React island. Filters in place
within the year-grouped archive.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>