Skip to main content

max / makenotwork

Take quasi 0.104: a frame's name goes on its placement Five tab strips build their panels in Rust rather than in a declare!, so each moves its label from the panel to the placing: `strip.frame(label, Node::Region(region))` instead of a labelled region added with `with`. Same markup, and the name is now written where the thing that draws it is. The shortcuts modal had a label that had never reached markup. A modal is a screen's own slot, so nothing reveals it and nothing would draw a label; a dialog does want an accessible name, so it is `named` now, which is the field that writes one. Second dead label found in this server after /use-cases' nine card titles, and neither was findable before the type changed. The /fan-plus residual gains two literals and keeps its six branches and its one hole. Its spans were being placed wrongly: a branch straddled the one after it, and the literal it swallowed is now its own. The filling test is what says the new one is right, on every branch.
Co-Authored-By
Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session
https://claude.ai/code/session_01P8ostB2UmZJGj5WjSHRSot
Author: Max Johnson <me@maxj.phd> · 2026-09-08 00:48 UTC
Signed with PGP, not checked
Commit: c554d7ededa358ea54d32d4b3b63fad609f6fddb
Parent: 812dc71
8 files changed, +32 insertions, -25 deletions
@@ -163,7 +163,7 @@
163 163 # through quasi beside its Askama equivalent, so the cost of describing a screen
164 164 # here is measured rather than argued. Not load-bearing for any shipped route.
165 165 # See wiki look-wave-2, tier G.
166 - quasi-router = { git = "https://makenot.work/git/max/quasi.git", version = "0.103" }
166 + quasi-router = { git = "https://makenot.work/git/max/quasi.git", version = "0.104" }
167 167 # The declared form. A screen written as `declare!` is compiled to the same
168 168 # `quasi_router` constructors the hand-written shape called, at build time, so
169 169 # nothing new reaches the binary and the macro is not in the request path.
@@ -183,13 +183,13 @@
183 183 # For the request head the per-viewer state factory reads. axum re-exports it,
184 184 # but the factory's signature is quasi-axum's and names `http::request::Parts`.
185 185 http = "1.3.1"
186 - quasi-axum = { git = "https://makenot.work/git/max/quasi.git", version = "0.103" }
187 - quasi-webview = { git = "https://makenot.work/git/max/quasi.git", version = "0.103" }
186 + quasi-axum = { git = "https://makenot.work/git/max/quasi.git", version = "0.104" }
187 + quasi-webview = { git = "https://makenot.work/git/max/quasi.git", version = "0.104" }
188 188 # The first-party widget set. The carousel was proved here against three pages
189 189 # and then moved there; what is left in `quasi/widgets/carousel.rs` is the
190 190 # Askama glue. Not `makeover-basics`: a widget is an assembly of `Node`s, so it
191 191 # sits above quasi-router rather than inside the description suite.
192 - quasi-basics = { git = "https://makenot.work/git/max/quasi.git", version = "0.103" }
192 + quasi-basics = { git = "https://makenot.work/git/max/quasi.git", version = "0.104" }
193 193
194 194 # Git source browser
195 195 gix = { version = "0.86", default-features = false, features = ["blame", "mailmap", "revision", "sha1", "max-performance-safe"] }
@@ -288,7 +288,7 @@
288 288 # Written from the crate rather than copied into the repo for the reason the
289 289 # constants exist: a stale copy in a static directory is a silently dead bulk
290 290 # bar, and the version has to be the one the emitter agrees with.
291 - quasi-webview = { git = "https://makenot.work/git/max/quasi.git", version = "0.103" }
291 + quasi-webview = { git = "https://makenot.work/git/max/quasi.git", version = "0.104" }
292 292
293 293 [dev-dependencies]
294 294 tower = { version = "0.5.3", features = ["util"] }
@@ -190,7 +190,7 @@
190 190 .showing_one(shown);
191 191
192 192 for (at, tab) in tabs.iter().enumerate() {
193 - let mut region = Slot::handover(tab.panel, "item-panel").label(tab.label);
193 + let mut region = Slot::handover(tab.panel, "item-panel");
194 194 if at != shown {
195 195 // Every panel here is an Askama route, so every one of them needs to
196 196 // be told where its answer goes: a route that names no region leaves
@@ -202,7 +202,7 @@
202 202 .replacing(tab.panel),
203 203 );
204 204 }
205 - strip = strip.with(Node::Region(region));
205 + strip = strip.frame(tab.label, Node::Region(region));
206 206 }
207 207
208 208 use quasi_axum::Serves as _;
@@ -167,7 +167,7 @@
167 167 .showing_one(0);
168 168
169 169 for (at, tab) in shown.iter().enumerate() {
170 - let mut panel = Slot::handover(tab.panel, "library-panel").label(tab.label);
170 + let mut panel = Slot::handover(tab.panel, "library-panel");
171 171 if at > 0 {
172 172 let mut call = Action::get(tab.route).awaiting();
173 173 // Described routes name their own region and must be left to;
@@ -178,7 +178,7 @@
178 178 }
179 179 panel = panel.fed_by(call);
180 180 }
181 - strip = strip.with(Node::Region(panel));
181 + strip = strip.frame(tab.label, Node::Region(panel));
182 182 }
183 183
184 184 use quasi_axum::Serves as _;
@@ -188,7 +188,7 @@
188 188 .showing_one(shown);
189 189
190 190 for (at, tab) in tabs.iter().enumerate() {
191 - let mut region = Slot::handover(tab.panel, "project-panel").label(tab.label);
191 + let mut region = Slot::handover(tab.panel, "project-panel");
192 192 if at != shown {
193 193 // Every panel is an Askama route naming no region, so each is told
194 194 // where its answer goes or htmx swaps it into the pressed button.
@@ -198,7 +198,7 @@
198 198 .replacing(tab.panel),
199 199 );
200 200 }
201 - strip = strip.with(Node::Region(region));
201 + strip = strip.frame(tab.label, Node::Region(region));
202 202 }
203 203
204 204 use quasi_axum::Serves as _;
@@ -259,7 +259,7 @@
259 259 .showing_one(shown);
260 260
261 261 for (at, section) in sections.iter().enumerate() {
262 - let mut region = Slot::handover(section.panel, "settings-panel").label(section.label);
262 + let mut region = Slot::handover(section.panel, "settings-panel");
263 263 if at != shown {
264 264 let mut call = Action::get(section.route).awaiting();
265 265 // A described route names its own region and must be left to. Same
@@ -271,7 +271,7 @@
271 271 }
272 272 region = region.fed_by(call);
273 273 }
274 - strip = strip.with(Node::Region(region));
274 + strip = strip.frame(section.label, Node::Region(region));
275 275 }
276 276
277 277 use quasi_axum::Serves as _;
@@ -79,8 +79,13 @@
79 79
80 80 Ok(Outcome::Over(
81 81 Screen::list_detail("Keyboard shortcuts", false).with(
82 + // `named` and not `label`. A modal is a screen's own slot, so
83 + // nothing reveals it and nothing would have drawn a label: this
84 + // said "Keyboard shortcuts" to no one until `2cdc6761` made that
85 + // unspellable. A dialog does want an accessible name, and `named`
86 + // is the field that writes one.
82 87 Slot::new("shortcuts", RegionKind::Modal)
83 - .label("Keyboard shortcuts")
88 + .named("Keyboard shortcuts")
84 89 .with(Node::from(
85 90 Table::new([Column::new("Key"), Column::new("Does")]).rows(rows),
86 91 )),
@@ -208,7 +208,7 @@
208 208 .showing_one(shown);
209 209
210 210 for (at, tab) in tabs.iter().enumerate() {
211 - let mut region = Slot::handover(tab.panel, "user-panel").label(tab.label);
211 + let mut region = Slot::handover(tab.panel, "user-panel");
212 212 if at != shown {
213 213 let mut call = Action::get(format!("/dashboard/tabs/{}", tab.route)).awaiting();
214 214 // A described route names its own region and must be left to; an
@@ -221,7 +221,7 @@
221 221 }
222 222 region = region.fed_by(call);
223 223 }
224 - strip = strip.with(Node::Region(region));
224 + strip = strip.frame(tab.label, Node::Region(region));
225 225 }
226 226
227 227 use quasi_axum::Serves as _;
@@ -48,33 +48,35 @@
48 48
49 49 pub static FAN_PLUS: ::quasi_router::stage::Residual =
50 50 ::quasi_router::stage::Residual::compiled(&[
51 - ::quasi_router::stage::Op::Lit(::std::borrow::Cow::Borrowed("<div id=\"fan-plus\" class=\"region pane\"><h1 class=\"heading\">Fan+</h1")),
51 + ::quasi_router::stage::Op::Lit(::std::borrow::Cow::Borrowed("<div id=\"fan-plus\" class=\"region pane\"><h1 class=\"heading\">Fan+</h1><")),
52 52 ::quasi_router::stage::Op::Branch(::std::borrow::Cow::Borrowed(&[
53 - ::quasi_router::stage::Op::Lit(::std::borrow::Cow::Borrowed("><div class=\"banner\" data-tone=\"success\" role=\"status\" aria-live=\"polite\">You&#39;re now a Fan+ member. Welcome.</div")),
53 + ::quasi_router::stage::Op::Lit(::std::borrow::Cow::Borrowed("div class=\"banner\" data-tone=\"success\" role=\"status\" aria-live=\"polite\">You&#39;re now a Fan+ member. Welcome.</div><")),
54 54
55 55 ])),
56 56 ::quasi_router::stage::Op::Branch(::std::borrow::Cow::Borrowed(&[
57 - ::quasi_router::stage::Op::Lit(::std::borrow::Cow::Borrowed("><section id=\"fan-plus-membership\" class=\"region group\"><p class=\"text\">Your Fan+ membership is active.")),
57 + ::quasi_router::stage::Op::Lit(::std::borrow::Cow::Borrowed("section id=\"fan-plus-membership\" class=\"region group\"><p class=\"text\">Your Fan+ membership is active.</p><p class=\"text\">")),
58 58 ::quasi_router::stage::Op::Branch(::std::borrow::Cow::Borrowed(&[
59 - ::quasi_router::stage::Op::Lit(::std::borrow::Cow::Borrowed("</p><p class=\"text\">Current period ends: ")),
59 + ::quasi_router::stage::Op::Lit(::std::borrow::Cow::Borrowed("Current period ends: ")),
60 60 ::quasi_router::stage::Op::Hole { scope: 1, id: 0 },
61 + ::quasi_router::stage::Op::Lit(::std::borrow::Cow::Borrowed("</p><p class=\"text\">")),
61 62
62 63 ])),
63 - ::quasi_router::stage::Op::Lit(::std::borrow::Cow::Borrowed("</p><p class=\"text\">You&#39;ll receive a $5 credit code each billing cycle via email.</p><div class=\"anchored\" id=\"fan-plus-membership-anchored\" data-menu=\"anchored\" hidden></div></section")),
64 + ::quasi_router::stage::Op::Lit(::std::borrow::Cow::Borrowed("You&#39;ll receive a $5 credit code each billing cycle via email.</p><div class=\"anchored\" id=\"fan-plus-membership-anchored\" data-menu=\"anchored\" hidden></div></section><")),
64 65
65 66 ])),
66 67 ::quasi_router::stage::Op::Branch(::std::borrow::Cow::Borrowed(&[
67 - ::quasi_router::stage::Op::Lit(::std::borrow::Cow::Borrowed("><section id=\"fan-plus-pitch\" class=\"region group\"><p class=\"text\">Support the platform and get something back every month.</p><h2 class=\"heading\">What you get</h2><ul class=\"list\"><li class=\"row\" data-row><span class=\"row-primary\">$5 monthly credit</span><span class=\"row-secondary\">A promo code delivered by email each billing cycle, usable toward any purchase on the platform</span></li><li class=\"row\" data-row><span class=\"row-primary\">+ badge</span><span class=\"row-secondary\">Displayed next to your name on your forum posts</span></li><li class=\"row\" data-row><span class=\"row-primary\">Forum signatures</span><span class=\"row-secondary\">A signature block rendered under everything you post</span></li><li class=\"row\" data-row><span class=\"row-primary\">Image embeds</span><span class=\"row-secondary\">Post images in forum threads</span></li></ul><div class=\"figures\"><div class=\"figure\" aria-label=\"per month: $8\"><span class=\"figure-value\" aria-hidden=\"true\">$8</span><span class=\"figure-caption\" aria-hidden=\"true\">per month</span></div></div><p class=\"text\">Makenotwork is built on 0% platform fees. Fan+ is how you directly support the platform&#39;s development and operations, while getting real value back each month.</p><div class=\"anchored\" id=\"fan-plus-pitch-anchored\" data-menu=\"anchored\" hidden></div></section")),
68 + ::quasi_router::stage::Op::Lit(::std::borrow::Cow::Borrowed("section id=\"fan-plus-pitch\" class=\"region group\"><p class=\"text\">Support the platform and get something back every month.</p><h2 class=\"heading\">What you get</h2><ul class=\"list\"><li class=\"row\" data-row><span class=\"row-primary\">$5 monthly credit</span><span class=\"row-secondary\">A promo code delivered by email each billing cycle, usable toward any purchase on the platform</span></li><li class=\"row\" data-row><span class=\"row-primary\">+ badge</span><span class=\"row-secondary\">Displayed next to your name on your forum posts</span></li><li class=\"row\" data-row><span class=\"row-primary\">Forum signatures</span><span class=\"row-secondary\">A signature block rendered under everything you post</span></li><li class=\"row\" data-row><span class=\"row-primary\">Image embeds</span><span class=\"row-secondary\">Post images in forum threads</span></li></ul><div class=\"figures\"><div class=\"figure\" aria-label=\"per month: $8\"><span class=\"figure-value\" aria-hidden=\"true\">$8</span><span class=\"figure-caption\" aria-hidden=\"true\">per month</span></div></div><p class=\"text\">Makenotwork is built on 0% platform fees. Fan+ is how you directly support the platform&#39;s development and operations, while getting real value back each month.</p><div class=\"anchored\" id=\"fan-plus-pitch-anchored\" data-menu=\"anchored\" hidden></div></section><")),
68 69
69 70 ])),
70 71 ::quasi_router::stage::Op::Branch(::std::borrow::Cow::Borrowed(&[
71 - ::quasi_router::stage::Op::Lit(::std::borrow::Cow::Borrowed("><button type=\"button\" class=\"button\" data-act hx-post=\"/stripe/fan-plus\" hx-swap=\"outerMorph\" hx-disable=\"this\" data-awaiting=\"indeterminate\">Join Fan+</button")),
72 + ::quasi_router::stage::Op::Lit(::std::borrow::Cow::Borrowed("button type=\"button\" class=\"button\" data-act hx-post=\"/stripe/fan-plus\" hx-swap=\"outerMorph\" hx-disable=\"this\" data-awaiting=\"indeterminate\">Join Fan+</button><")),
72 73
73 74 ])),
75 + ::quasi_router::stage::Op::Lit(::std::borrow::Cow::Borrowed("div class=\"")),
74 76 ::quasi_router::stage::Op::Branch(::std::borrow::Cow::Borrowed(&[
75 - ::quasi_router::stage::Op::Lit(::std::borrow::Cow::Borrowed("><div class=\"rich\" data-disable-scripting><p><a href=\"/join\" rel=\"noopener noreferrer\">Create an account</a> to join, or <a href=\"/login\" rel=\"noopener noreferrer\">log in</a> if you already have one.</p>\n</div")),
77 + ::quasi_router::stage::Op::Lit(::std::borrow::Cow::Borrowed("rich\" data-disable-scripting><p><a href=\"/join\" rel=\"noopener noreferrer\">Create an account</a> to join, or <a href=\"/login\" rel=\"noopener noreferrer\">log in</a> if you already have one.</p>\n</div><div class=\"")),
76 78
77 79 ])),
78 - ::quasi_router::stage::Op::Lit(::std::borrow::Cow::Borrowed("><div class=\"anchored\" id=\"fan-plus-anchored\" data-menu=\"anchored\" hidden></div></div>")),
80 + ::quasi_router::stage::Op::Lit(::std::borrow::Cow::Borrowed("anchored\" id=\"fan-plus-anchored\" data-menu=\"anchored\" hidden></div></div>")),
79 81 ]);
80 82