A fourth About page, `Join Discord`, sitting between the author and the ask:
what is this, who made it, where is everyone, how do I help. Like its three
siblings it is written markdown under assets/pages, reads nothing and
transmits nothing, and keeps a CLI face — `meshterm discord`.
It is short on purpose. The invite link, and the code for it in a `qr` fence,
because on a PicoCalc there is no clipboard and the code is how a link leaves
the screen at all.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Two rows renamed, and the rename carried into the screens they open —
the config editor's table title and its staged-count header, the support
page's own title (it comes from the tool, so it followed on its own).
"Support this project" never said which project; the menu is MeshTerm's
and the section above it is already About MeshTerm, so the name is the
useful half of that phrase. "Device configuration" was the longest label
in the list and set the width of the whole name column: at 19 cells
instead of 23, every description now gets 51 and the widest row is 68.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The three sections were placeholders holding a shape. This writes the
first one: what MeshTerm is (one screen for what the radio can tell you,
the five menu sections as a list, and the standing promise that nothing
transmits unasked), where it came from (June 2026, a few serial scripts,
grown by the recording; the mesh's scarce airtime is why it listens more
than it speaks; later the PicoCalc), and the licence — MIT, as the
package metadata declares, with the credit MeshCore and OpenStreetMap
are owed, the ODbL by name.
The layout is unchanged: title, standfirst, three sections, rule,
colophon. It just runs longer than a screenful now, which is what the
sticky headings and the section jumps were for.
Link targets also drop a leading www., so the OSM copyright URL reads as
the host it is rather than a subdomain nobody types.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The three About pages were scaffolding built out of Text() calls, which
made writing them a Python edit and capped what they could ever say. They
are markdown now — meshterm/assets/pages/*.md, drawn by ui/markdown.py
into the app's own language rather than markdown's: # the page's name in
brand, ## a section in the body accent (with the muted · aside), ###
indented with its prose, paragraphs and lists hanging as blocks, quotes
and fences behind a rail that survives wrapping, tables through Rich, and
links that say where they go — nothing is clickable on a framebuffer
console. Two paragraphs are page frame rather than body and sit flush and
muted: the standfirst under the title, the colophon under the closing
rule, which is where the copyright lands.
The pages stay scaffolded on purpose — the placeholders are unchanged —
but filling one in is now editing its .md, and the live package facts
arrive as {version}/{author}/{copyright} so a page still can't drift from
the build it describes.
Being a document earns the screen two things a block never had: its ##
headings are landmarks, so a heading pins while its own prose scrolls
under it and ^PgUp/^PgDn step by them, and the console lane claims
Sect ↑/Sect ↓ on the free F1/F2 pair once a page has more than one
section — dimmed while the whole page fits, since the lane never
advertises a dead key.
Parsing is markdown-it-py (already under Rich, now declared): a real
CommonMark parser, so an author writes ordinary markdown. The md.* styles
are defined in both themes; the new test renders the whole vocabulary at
53 cells and asserts it stays inside the console font and the 16 slots.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The menu asks "What would you like to do?" and its five sections each
name a doing. "What is this thing, and who made it" is not one, and had
nowhere to go — so it gets the sixth section, the one that names a
subject, sorted last where a reader who has run out of things to do finds
it. Three pages, in the order a stranger asks:
About MeshTerm what this is, where it came from, its terms
About the author the person behind it, on the mesh and off it
Support this project what keeps it going, and the ways to help
Every page is scaffolding: the headings are the settled part, and each
section carries one lowercase muted "placeholder — …" line where its
prose will go. That is the app's own empty-state voice, so an unwritten
page reads as deliberately unwritten rather than as a screen that failed
to load, and filling one in means replacing its placeholder — the screen,
the menu rows and the CLI faces all follow unchanged. What is not a
placeholder is the version, the author and the copyright span: they come
from the package itself, so the About page can never describe a build it
isn't running inside.
The pages act on nothing — no radio, no database, no device — so each
opens straight to its screen with no prompt first, and each keeps a CLI
face (meshterm about / about-author / support) printing the same page to
a shell.
Two new icons, both funnelled for the console: 📖 read/about becomes ¶,
the page-of-prose mark, and 💰 support/donate becomes $.
ScrollScreen earns a derived footer hint on the way through. A read-only
body has only two keys to name, the pager and Esc, so passing "↑↓ PgUp/
PgDn scroll · Esc close" at every call site was both repetition and a lie
on a body that fits — the standing rule is that a footer never advertises
a key that would do nothing. Left unset, it now names the pager only
while the content actually overflows, and takes its Esc verb from the
surface: a floating view closes, a full screen goes back. Every existing
caller passes its hint explicitly and is untouched.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>