Marketing site for Station Manager — free, open-source Linux station-management software for amateur radio. A static Hugo site, deployed to https://station-manager.org.
It is deliberately a single landing page, not a documentation site — the operator manual ships with the app itself.
hugo server # live preview at http://localhost:1313
hugo # build the static site into ./publicRequires Hugo extended (0.16x+).
hugo.toml— site config.content/_index.md— home page front matter (title / description).layouts/index.html— the landing page, in one file.layouts/_partials/screenshot.html— renders one app screenshot: dark bezel, 1x/2x WebPsrcset, intrinsicwidth/heightso nothing reflows on load.layouts/_partials/analytics.html— GoatCounter, the site's only script.assets/screenshots/— screenshot sources; Hugo resizes and converts these at build time, so they are never served as-is.static/— files served verbatim (logo.svg,CNAME).
Drop a PNG into assets/screenshots/ and reference it from a screenshot.html
partial call in layouts/index.html. Sources should be at least 2304 px wide
— twice the 1152 px display width — and cropped to the app viewport, with no
browser chrome. Hide the bookmarks bar (Ctrl+Shift+B) before capturing; it is
easy to leak personal bookmarks into a marketing shot.
The app's operate and map views are dark-only, so screenshots are dark by design and the bezel is dark to match. Don't mix in light-theme shots.
A figure whose source PNG is absent is skipped at build time with a warning,
so a slot can be wired up before the screenshot exists. operate-phone.png (the
phone/CW tile board) is currently such a slot.
Visitor counts come from GoatCounter; the dashboard is at https://station-manager.goatcounter.com. It is the only third-party script on the site.
It sets no cookies and keeps no persistent identifier — unique visitors are counted by a hash that is rotated daily — so there is nothing here that needs a consent banner. Each hit sends the page path, title, referrer, screen size and query string, and nothing else.
Set params.goatcounter in hugo.toml to '' to leave it out of the build
entirely. It is production-only in any case: hugo server never counts, so
local previews stay out of the stats.
Read the numbers as a floor, not a census. GoatCounter is on the common
ad-block filter lists, so an appreciable share of visits never reports; the
<noscript> pixel recovers some of them but not all.
Live at https://station-manager.org, on GitHub Pages. Every push to
master (or main) runs .github/workflows/deploy.yml, which builds the site
and publishes public/; the workflow can also be started by hand from the
Actions tab. Deploys are serialised — a queued run waits rather than cancelling
one already in flight.
The workflow installs Node 22 and runs npm ci before hugo, because
Tailwind v4 is driven through Hugo's css.TailwindCSS pipe, which shells out to
the @tailwindcss/cli binary in node_modules. A build without that step
produces a page with no CSS. Hugo itself is pinned by HUGO_VERSION in the
workflow — bump it there, and keep your local hugo roughly in step.
Two things that bite if you forget them:
baseURLis overridden at build time. The workflow passes--baseURLfrom the Pages API, so the value inhugo.tomlis what local builds use, not what ships.static/CNAMEis what holds the custom domain. Pages reads it from the published output on every deploy, so if that file leavesstatic/the site reverts tocolonelblimp.github.ioon the next push.
DNS lives at the registrar, not with GitHub: the apex has A records to
GitHub's four Pages addresses (185.199.108–111.153), and www is a CNAME to
colonelblimp.github.io that redirects to the apex. HTTPS is enforced, so
http:// answers 301.
Site templates and CSS, like the Station Manager software, are GPL-3.0-only. Prose and screenshots are © the author; reuse under CC-BY-4.0 unless noted otherwise.