Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 38 additions & 5 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -1,21 +1,25 @@
# basic

Minimal black-and-white Hugo theme for text-first blogs. Light/dark/auto, no JS
dependencies. The theme itself lives at repo root; `exampleSite/` is the demo
site used for local dev.
required to read a post — the one exception is the `mailto` shortcode, which
needs a few inline lines to assemble the obfuscated address (see Shortcodes
below). The theme itself lives at repo root; `exampleSite/` is the demo site
used for local dev.

## Commands

- `pnpm dev` — hugo server on `exampleSite/` with drafts, live reload
- `pnpm build` — minified production build of `exampleSite/`
- `node assets/js/console.js` — run the console self-check (asserts at bottom of file)

Hugo min version 0.116.0. Assets go through Hugo Pipes (Minify + Fingerprint),
see `layouts/partials/console.html`.
Hugo min version 0.141.0 (the repo/package card shortcodes use the `try`
keyword, added in that release). Assets go through Hugo Pipes (Minify +
Fingerprint), see `layouts/partials/console.html`.

## Layout

- `layouts/` — templates (`_default/`, `partials/`). `baseof.html` is the shell.
- `layouts/` — templates (`_default/`, `partials/`, `shortcodes/`). `baseof.html`
is the shell.
- `assets/css/main.css` — the core stylesheet (base light/dark, layout, sets).
Colour themes live in `assets/css/themes/*.css`, concatenated in `baseof.html`.
- `assets/js/console.js` — the floating terminal (below).
Expand Down Expand Up @@ -54,6 +58,35 @@ Subcommands:
- Add an `assert` to the self-check block for each new branch, then run
`node assets/js/console.js`.

## Shortcodes

Live in `layouts/shortcodes/`, one file per shortcode. Full syntax + rendered
examples for every one of them: `exampleSite/content/posts/shortcodes.md` —
update that post whenever a shortcode is added, renamed, or reparamaterized.

- **Positional vs named params**: Hugo shortcode calls cannot mix positional
and named params in the same call. Every shortcode here accepts positional
args (`.Get 0`, `.Get 1`, ...) with named overrides (`with .Get "name"`) so
either calling style works alone — but a call can't use both at once. Bit
us twice already (`mailto`, `badge`); if a new shortcode's demo call errors
with "Cannot mix named and positional parameters", this is why.
- **Repo/package cards** (`github`, `gitlab`, `huggingface`, `npm`, `crates`,
`pypi`) all render the shared `.repo-card` component — same markup shape
(icon, name, description, meta stats), so a new registry card should reuse
those classes rather than inventing new ones.
- **Build-time API fetch pattern**: `try (resources.GetRemote url)`, then
`with .Value` / `if .Err`. Hugo removed `resource.Err` in v0.141.0 in favour
of the `try` keyword — don't reach for the old pattern.
- **Fail soft vs fail loud**: the repo/package cards degrade to a bare link
card if the API call fails (the link still works without the decoration).
`gist`, `bluesky`, and `code` hard-error via `errorf` instead — for those,
the fetched content *is* the entire point of the shortcode, so a silent
empty render would be actively misleading.
- **`mailto`** is the one shortcode that ships JS: HTML entity-encoding the
address doesn't survive Hugo's `--minify` pass (it decodes entities back to
plaintext), so the real link is base64'd into data attributes and assembled
by inline JS on load instead.

## Themes

Themes are pure CSS: each named theme is its own file under
Expand Down
51 changes: 43 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@

A minimal, black-and-white Hugo theme for text-first blogs. Pure monochrome
until you hover something clickable — then a single accent colour pops. Ships
with light / dark / auto modes (no flash on load, remembers your choice).
with light / dark / auto modes plus a few colour themes (no flash on load,
remembers your choice), a set of shortcodes for embedding code and repo/package
cards, and a floating console to drive it all.

**Live demo:** https://jjsnack.github.io/basic/ (the `exampleSite/`, built and
deployed on every push).
Expand Down Expand Up @@ -66,8 +68,9 @@ declared in site config:

## Images

Standard markdown images render as captioned `<figure>`s (alt text becomes the
caption), lazy-loaded:
Standard markdown images render as captioned, borderless `<figure>`s (alt text
becomes the caption), lazy-loaded. Click one to zoom via a pure-CSS lightbox
(no JS):

```markdown
![This caption shows under the image.](/img/photo.jpg)
Expand Down Expand Up @@ -101,19 +104,50 @@ load:
A --> B
```

## Theme modes
## Shortcodes

Header button cycles **auto → light → dark** (`◐ ○ ●`). Auto follows the OS;
an explicit pick is saved to `localStorage`.
| Shortcode | What it does |
|---|---|
| `github`, `gitlab`, `huggingface`, `npm`, `crates`, `pypi` | Repo/package cards. Fetch live description/stats from the relevant API at build time, fall back to a bare link card if the fetch fails. Override with `desc=`/etc. to skip the network call. |
| `code` | Imports a local file or remote URL instead of pasting code inline, so it can't drift out of sync. `lines="12-34"` for a range, `lang=` to override the guessed language. |
| `gist` | Renders a GitHub gist with the theme's own syntax highlighting (Hugo's built-in `gist` shortcode was removed in v0.156). |
| `bluesky` | Renders a Bluesky post via its public API. No `tweet` equivalent — X/Twitter dropped unauthenticated read access. |
| `youtube` | Hugo's built-in shortcode; the theme just themes its corners. |
| `swatches` | A row of labelled colour chips. |
| `admonition` | A themed callout: `type="note\|tip\|warning\|danger"`. |
| `details` | Wraps native `<details>`/`<summary>` — no JS. |
| `badge` | An inline pill, optionally coloured from the pop palette. |
| `mailto` | An obfuscated mail link. Base64 + a few lines of inline JS assemble the real `mailto:` on load — the one shortcode here that needs JS, since HTML-entity encoding doesn't survive Hugo's `--minify` pass. |

## Change the accent colour
Full syntax and live examples for each: `exampleSite/content/posts/shortcodes.md`.

## The console

A floating terminal (bottom-right launcher, `$`), progressively enhanced —
the page works fully with JS off. Type `help` inside it for the full command
list; the two with real content:

- `theme set <name>` — switch theme. Modes: `light`, `dark`, `auto`, plus any
colour theme file under `assets/css/themes/*.css` (ships with `paper`,
`dracula`, `valentine`). Persisted to `localStorage`, no flash on reload.
- `music play` / `music stop` / `music volume <0-10>` — an 8-bit soundtrack
synthesised live with WebAudio (no audio files), one tune per theme,
keeps playing across page navigation.

### Change the accent colour

One line in `assets/css/main.css`:

```css
--accent: #ff2d55;
```

### Add a colour theme

Drop a new `assets/css/themes/<name>.css` with a `:root[data-theme="<name>"]`
block (see the existing ones for the variable list), then add `<name>` to the
`modes` array in `assets/js/console.js`'s `theme` command.

## Demo deployment

`.github/workflows/pages.yml` builds `exampleSite/` with Hugo extended and
Expand All @@ -123,4 +157,5 @@ The workflow injects the correct `baseURL` for project pages automatically.

## Requirements

Hugo extended ≥ 0.116 (uses the asset pipeline for CSS).
Hugo extended ≥ 0.141 (asset pipeline for CSS; the repo/package card
shortcodes use the `try` keyword, added in that release).
71 changes: 2 additions & 69 deletions exampleSite/content/posts/hello-world.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,18 +18,6 @@ pop of colour. Inline `code` looks like this.

> A blockquote sits quietly to one side.

## A repo

{{< github "gohugoio/hugo" >}}

{{< gitlab "gitlab-org/gitlab" >}}

{{< huggingface "bert-base-uncased" >}}

## Swatches

{{< swatches "#64748b" "#3b82f6" "#06b6d4" >}}

## A diagram

```mermaid
Expand All @@ -52,60 +40,5 @@ Inline, like $E = mc^2$, sits in the sentence. Display math gets its own line:

$$\int_{-\infty}^{\infty} e^{-x^2}\,dx = \sqrt{\pi}$$

That's it.

## Imported code

{{< code file="assets/js/console.js" lines="1-8" >}}

## A gist

{{< gist "octocat" "6cad326836d38bd3a7ae" >}}

## A video

{{< youtube dQw4w9WgXcQ >}}

## Contact

Questions? {{< mailto "hello@example.org" "Hello from the blog" "say hi" >}}.

Default text: {{< mailto "hello@example.org" >}}

## Admonitions

{{< admonition >}}A plain note, no title override.{{< /admonition >}}

{{< admonition type="tip" title="Pro tip" >}}Use `pnpm dev` for live reload while writing.{{< /admonition >}}

{{< admonition type="warning" title="Careful" >}}This regenerates the fingerprinted bundle.{{< /admonition >}}

{{< admonition type="danger" title="Don't" >}}Never commit `.env` files.{{< /admonition >}}

## Details

{{< details summary="Click to expand" >}}
Hidden content with **markdown** support, revealed via the native `<details>` element.
{{< /details >}}

## Badges

{{< badge "MIT" >}} {{< badge "v1.2.0" "blue" >}} {{< badge "beta" "orange" >}}

## Package cards

{{< npm "left-pad" >}}

{{< crates "serde" >}}

{{< pypi "requests" >}}

## A Bluesky post

{{< bluesky "https://bsky.app/profile/bsky.app/post/3mqcp5qjdfs26" >}}

## A footnote

Here's a claim that needs backing up.[^1]

[^1]: This is the footnote content, rendered by goldmark natively.
That's it. See [the shortcode reference](/posts/shortcodes/) for repo cards,
code embeds, admonitions, and everything else the theme ships.