Skip to content

aethersdr/aetherweb

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

44 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

aetherweb

Marketing / project website for AetherSDR — the cross-platform, open-source client for FlexRadio Systems transceivers. Lives at www.aethersdr.com (Cloudflare-hosted).

Design inspired by armbian.com: dark, technical, and feature-forward, using AetherSDR's own palette (deep navy + electric cyan→teal).

Structure

index.html            The landing page (single page, no build step required)
blog.html             The blog — card index + every post, routed client-side
styles.css            All styling (design tokens at the top)
assets/img/           Optimized screenshots, logo, and 3D-spectrum visuals
assets/js/blog.js     Blog card-index <-> post routing
serve.py              Tiny local static server (python3 serve.py → :4321)
scripts/build.py      Bundles everything into dist/index.html (self-contained)
scripts/gen-blog-art.py  Regenerates the generated SVG post art

Post art that isn't a screenshot is generated SVG — drawn in the site palette and committed alongside the source that produces it:

python3 scripts/gen-blog-art.py   # rewrites assets/img/first-contribution-*.svg

It's deterministic (fixed seed), so re-running produces byte-identical files; tweak the constants at the top rather than editing thousands of <rect>s by hand. Each post needs two crops — a wide hero and a near-square for the card column, which crops to roughly 1.1:1.

Adding a blog post

Everything lives in blog.html — no build step, no separate post files. A post is two blocks that share a slug:

  1. A card in the .blog-grid, linking to #your-slug. The description is clamped to four lines, so write 3–4 lines and don't worry about matching neighbouring card heights. Cards are ordered newest-first by hand — insert yours below the pinned card and above the newest release post.
  2. An <article class="blog-post" data-post="your-slug" ... hidden> further down, holding the hero image and full body. Keep the hidden attribute — it is what keeps the post off the index until it's routed to.

assets/js/blog.js matches the two by slug: clicking a card sets the hash, which swaps the grid out for that post. Post URLs (/blog.html#your-slug) are shareable, and Back/Forward work. Body copy goes inside .blog-body, which styles headings, lists, links, quotes, and code blocks for you.

Note: don't add a display value to .blog-post in CSS — a class rule out-specifies the browser's [hidden] { display: none } and every post would render on the index at once.

The first card carries is-pinned and a Pinned badge, holding it at the top of the index whatever its date. To pin a different post, move the class, the badge markup, and the <!-- PINNED --> comment to that card.

Editing styles.css? Bump the ?v= on the three <link rel="stylesheet"> tags (index.html, blog.html, 404.html). The file is served with max-age=14400, so without a new URL a browser can pair a stale stylesheet with fresh markup for up to four hours.

Cloudflare Pages serves the page extensionless at /blog and 308-redirects /blog.html to it, so canonical and the og:/twitter: URLs point at /blog. Internal links keep the blog.html form on purpose — it resolves under serve.py locally and just costs one redirect hop in production.

Local preview

python3 serve.py           # http://127.0.0.1:4321
# or any static server:
# npx serve .

Self-contained build (for review / Claude Desktop)

python3 scripts/build.py   # writes dist/index.html with CSS + images inlined

Deploy — Cloudflare Pages

Deploys run from GitHub Actions via Wrangler (Direct Upload). Every push to main stages the site files into _site/ and publishes them to the Pages project aetherweb. See .github/workflows/deploy.yml.

One-time setup

  1. Create a Cloudflare API token — Cloudflare dashboard → My Profile → API Tokens → Create Token → Custom token. Permission: Account → Cloudflare Pages → Edit. Scope it to the AetherSDR account.
  2. Grab the Account IDWorkers & Pages overview (right sidebar).
  3. Add two repo secrets — GitHub → Settings → Secrets and variables → Actions:
    • CLOUDFLARE_API_TOKEN
    • CLOUDFLARE_ACCOUNT_ID
  4. Push to main (or run the workflow manually). The first run creates the aetherweb Pages project and publishes it to https://aetherweb.pages.dev.

Domain (www.aethersdr.com)

The zone is already on Cloudflare, so DNS and TLS are automatic:

  1. Pages project → Custom domains → Set up a custom domain → www.aethersdr.com. Cloudflare auto-creates the proxied CNAME and provisions the TLS cert.
  2. Redirect the apexRules → Redirect Rules: when hostname equals aethersdr.com, 301 to https://www.aethersdr.com (preserving path/query). This replaces the current apex → GitHub redirect. (If you still want a GitHub shortcut, point code.aethersdr.com at it instead.)

Local manual deploy (optional)

npx wrangler pages deploy . --project-name=aetherweb --branch=main

AetherSDR is an independent project and is not affiliated with or endorsed by FlexRadio Systems. Content licensed alongside the AetherSDR project (GPL v3).

About

Marketing/project website for AetherSDR — www.aethersdr.com (Cloudflare-hosted)

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages