════════════════════════════════════════════════════════════════════════════════
 Node 1  ·  2400 baud  ·  40 msgs in 6 areas  ·  sysop randogoth
════════════════════════════════════════════════════════════════════════════════
════════════════════════════════════════════════════════════════════════════════
 Msg  : mews-profile                                 Area : MINIMAL
 From : randogoth                                    Date : 13 Oct 2026
 Subj : The Quiet Lane Round the Back Keys : mews, smallweb, flutter
 Msg  : mews-profile
 Area : MINIMAL
 From : randogoth
 Date : 13 Oct 2026
 Subj : The Quiet Lane Round the Back
 Keys : mews, smallweb, flutter
════════════════════════════════════════════════════════════════════════════════

The web is a loud place now. Pages track you, shout at you, and weigh magnitudes more than the words they carry.

I already knew a way out of that. itsybitsy, my own generator, has emitted XHTML Mobile Profile 1.2 for a while now, beside gemtext and Nex, and every time I looked at that output I thought the same thing: there is a whole small net hiding in here and nobody is using it. XHTML-MP 1.2 was cut down by the Open Mobile Alliance for WAP 2.0 handsets, and when everybody moved to smartphone apps it stayed exactly where it was. Headings, paragraphs, lists, tables, links, forms. No scripts.

What stopped me calling it a proper small-net format was what happens when you open one. Every browser since the 90s renders an unstyled page the same way: white background, black Times New Roman, links in that sharp blue. Why does everything unstyled need to look like a vanilla Word 5 document? The page isn't plain because the author did nothing. It is plain because somebody picked an ugly default once, around 1994, and nobody has revisited it since.

Which is one of the things I love most about Gemini and Spartan: The author writes structure, the client decides the looks, and most of those clients look fantastic. Reading a capsule in a good one is more pleasant than reading almost any website, and the author had no hand in it at all. That isn't a limitation of those protocols. It is the best feature they have.

So WAP 2.0 was one client and one stylesheet short of being the same kind of thing. A client that recognises a page as mellow small-net content and renders it in its own typography, and a sane default stylesheet for everybody who opens the same page in a browser instead. That is where this project came from.

Mews Profile is a strict subset of that old standard, one shared stylesheet, and a convention for subscriptions borrowed from Gemini. The draft is 0.1, it lives at mews.page/spec/0.1, and the name keeps the MP: Mobile Profile becomes Mews Profile.

A mews is the lane round the back where the stables were: narrow, quiet, not on the way to anywhere. The web needs more mews: small sites, plain words, nothing watching.

Authors provide structure, readers control presentation

Every rule in the spec follows from that one sentence, including the ones that look stingy. No script, no style element and no style attribute, no object, no onclick, no big and no small. Not because any of those are wicked, but because each of them moves a decision from the person reading to the person publishing. A conforming page carries one line in its head:

<meta name="mews-profile" content="0.1" />

That is the conformance marker, and it is the whole handshake. A Mews client may apply its own fonts, colours and spacing to a page that carries it, and must leave a page alone that doesn't.

The part I care about most is what the format doesn't add: no protocol, no proxy, no special server, no client required. A Mews page is served over plain HTTP as a web page and opens in Firefox, and on a real WAP 2.0 handset, because apart from lang and dir (which XHTML-MP lacks, and which browsers and right-to-left scripts genuinely need) every rule in the spec only removes something.

What is actually running

mews.page is the spec, and also the tooling around it. The check page takes an address, validates the page against the self-contained Mews DTD, reads its stylesheet and up to twenty images, and lists every rule it breaks with the section of the spec that explains it. Ask it to check and list and a passing site goes straight into the directory. Nobody reviews it. It takes up to a minute, with no progress bar, because that would want JavaScript. Leave the page open and put the kettle on.

The same checks run on the command line as mewslint, which is quicker while you are still fixing things, and reads local files so you can check a page before publishing it:

uvx --from git+https://code.randogoth.com/randogoth/mews.page.git#subdirectory=validator mewslint https://example.com/

For writing, there is md2mews.py for converting a single Markdown file, and mews-quickstart, which writes a project folder, installs Pelican with the pelican-mews plugin, and leaves you a first post to edit. The pages land in output/ as plain HTML that any web server will serve as valid Mews pages. All of it is on the Get started page.

The code is Apache 2.0 and the spec is CC BY-SA 4.0, which is deliberate: the stylesheet isn't share-alike, because section 5.2 asks every site to host its own copy of it. itsybitsy emits Mews Profile pages now as one more output format beside gemtext and Nex.

The reader

The Mews is a Flutter client for Android and Linux desktop, local-first, with pages, bookmarks, subscriptions and reading settings in a Drift database and the network only ever revalidating a cache. It reads gemini:// and spartan:// alongside the web, because gemtext converts into the same document model a Mews page parses into: a capsule renders through the same presentation, joins the same history and the same back-swipe, and can be bookmarked and subscribed to. A link label that starts with a date counts as a dated entry, so subscriptions work on capsules too.

The rest is the small stuff that makes a reader pleasant. Luciole, Literata and Charis SIL are bundled with a Hebrew fallback face. The interface ships in eight languages with per-language plurals and mirroring. A site gets a colour derived from its own address, so you know where you are before you read a word. Gemini certificates are pinned on first sight, and a certificate that changes while the pinned one is still valid is refused, which is the opposite way round from how it feels like it should work and the right way round.

About that weekend

The spec says, in its own goals, "a format simple enough to write by hand and to implement a client for in a weekend". The first half is true and I have tested it by hand. The second half shouldn't be true, but it is: having ADHD and affordable coding agents a diff worth twenty-seven thousand lines, eight locales and a TOFU pinning table can be just that: one weekend! In fairness to the spec, the app does a lot more than read Mews pages.

There is one place where the spec claims something the code doesn't do yet: Section 9.1 says the project hosts its own copy of the XHTML-MP DTD "so validation never depends on the Open Mobile Alliance's server". The file is there, but it is only the OMA driver: it still pulls about twenty-two modules off w3.org. Mews validation itself is fine, because the Mews DTD is self-contained and the entity set is built in memory, so nothing on the critical path reaches the network.

A week ago this was a note about how much I liked old phone markup. Now there is a draft spec, a validator anyone can point at a page, a directory with sites in it, and a reader on my own phone that treats the small web and the WAP web as the same place. The format took a weekend. Everything that comes now is the real work.

So: write something. Link to a neighbour. Leave the light on.

Repository

mews.page · the-mews

--- RANDOGOTH BBS
 * Origin: randogoth.com (1:1/1)
────────────────────────────────────────────────────────────────────────────────
 [I]ndex   [K]eywords   [F]eed   Main [M]enu   
Command: