Skip to main content

max / makenotwork

Answer a served document once, and let it refuse The seam's mount took a closure for the screen and another for the body, so /fan-plus read its subscription from the database twice per request. Worse than the cost: the two reads could disagree, and the page would state one reader in its document while drawing another in its markup. One `answer` closure now returns both, from one read. They were never two jobs: a screen states its title and measure from the same values that fill its holes. It is fallible, which is the other half. A screen here answers no Screen, so it never reaches the adapter and cannot use the adapter's refusal path, and `reading` was swallowing a failed membership lookup into Visitor to have something to return. That shows a paying member the page asking them to subscribe, and a page that quietly tells a reader the opposite of the truth about their own money is worse than one that does not load. The status now comes off the RouteError as quasi_axum takes it, with an empty body for the reason `unresolved` has one: nothing was reached, so there is nothing to say that the status does not. The generated residuals declare themselves unformatted, and that is a real repair rather than a tidy-up. The staleness test compares the committed file with what `generate` produces byte for byte, so `cargo fmt` rewrapping a static fails it against markup nobody touched -- and the obvious repair, regenerate then format, puts it straight back. It had been failing since b4a83103 for exactly that reason: every literal and every op in that file was correct.
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-07 23:19 UTC
Signed with PGP, not checked
Commit: 812dc71ef8845f60332430905ed4a07b53847bee
Parent: 2651823
4 files changed, +145 insertions, -143 deletions
@@ -152,18 +152,17 @@
152 152
153 153 /// The two things this page reads, for the mount that serves it from a residual.
154 154 ///
155 - /// Its own function because both halves of the mount want them: the document, to
156 - /// state the screen, and the body, to fill the branches. A failure to read the
157 - /// membership answers `Visitor`, which is what a reader with no account sees; the
158 - /// alternative is a 500 on a marketing page because Stripe's mirror of a
159 - /// subscription could not be loaded, and the page that says "here is what Fan+
160 - /// is" reads correctly for somebody whose membership is unknown.
161 - #[must_use]
162 - pub(crate) fn reading(viewer: &super::Viewer, carried: &super::Carried) -> (Standing, bool) {
163 - (
164 - standing(viewer).unwrap_or(Standing::Visitor),
165 - carried.says("subscribed", "true"),
166 - )
155 + /// One read, stating the document and deciding which branches are filled.
156 + ///
157 + /// A failure to read the membership refuses, the way it does on every other
158 + /// screen. Answering `Visitor` instead would show a paying member the page that
159 + /// asks them to subscribe, and a page that quietly tells a reader the opposite
160 + /// of the truth about their own money is worse than one that does not load.
161 + pub(crate) fn reading(
162 + viewer: &super::Viewer,
163 + carried: &super::Carried,
164 + ) -> Result<(Standing, bool), RouteError> {
165 + Ok((standing(viewer)?, carried.says("subscribed", "true")))
167 166 }
168 167
169 168 /// Read the reader's membership, if there is a reader.
@@ -666,51 +666,54 @@
666 666 vec![
667 667 (
668 668 team::PATH,
669 - served_document_mount(
670 - app,
671 - team::PATH,
672 - |_, _| team::page_screen(),
673 - team::renderer,
674 - |_, _| residuals::settled(&residuals::TEAM),
675 - ),
669 + served_document_mount(app, team::PATH, team::renderer, |_, _| {
670 + Ok(Served {
671 + screen: team::page_screen(),
672 + markup: residuals::settled(&residuals::TEAM),
673 + })
674 + }),
676 675 ),
677 676 (
678 677 use_cases::PATH,
679 - served_document_mount(
680 - app,
681 - use_cases::PATH,
682 - |viewer, _| use_cases::page_screen(&use_cases::prices(viewer)),
683 - use_cases::renderer,
684 - |viewer, _| {
685 - use_cases::page_region_serve(&residuals::USE_CASES, &use_cases::prices(viewer))
686 - .into()
687 - },
688 - ),
678 + served_document_mount(app, use_cases::PATH, use_cases::renderer, |viewer, _| {
679 + // One read of the prices, stating the document and filling the
680 + // nine holes.
681 + let prices = use_cases::prices(viewer);
682 + Ok(Served {
683 + screen: use_cases::page_screen(&prices),
684 + markup: use_cases::page_region_serve(&residuals::USE_CASES, &prices).into(),
685 + })
686 + }),
689 687 ),
690 688 (
691 689 policy::PATH,
692 - served_document_mount(
693 - app,
694 - policy::PATH,
695 - |_, _| policy::page_screen(),
696 - policy::renderer,
697 - |_, _| residuals::settled(&residuals::POLICY),
698 - ),
690 + served_document_mount(app, policy::PATH, policy::renderer, |_, _| {
691 + Ok(Served {
692 + screen: policy::page_screen(),
693 + markup: residuals::settled(&residuals::POLICY),
694 + })
695 + }),
699 696 ),
700 697 (
701 698 fan_plus::PATH,
702 699 served_document_mount(
703 700 app,
704 701 fan_plus::PATH,
705 - |viewer, carried| {
706 - let (standing, just_subscribed) = fan_plus::reading(viewer, carried);
707 - fan_plus::page_screen(&standing, just_subscribed)
708 - },
709 702 fan_plus::renderer,
710 703 |viewer, carried| {
711 - let (standing, just_subscribed) = fan_plus::reading(viewer, carried);
712 - fan_plus::page_region_serve(&residuals::FAN_PLUS, &standing, just_subscribed)
713 - .into()
704 + // One read of the membership, deciding both the document and
705 + // which branches are filled. Read twice, the two could disagree
706 + // and the page would state one reader and draw another.
707 + let (standing, just_subscribed) = fan_plus::reading(viewer, carried)?;
708 + Ok(Served {
709 + screen: fan_plus::page_screen(&standing, just_subscribed),
710 + markup: fan_plus::page_region_serve(
711 + &residuals::FAN_PLUS,
712 + &standing,
713 + just_subscribed,
714 + )
715 + .into(),
716 + })
714 717 },
715 718 ),
716 719 ),
@@ -823,12 +826,26 @@
823 826 /// builds a `Node`, which is the property the seam exists for; a `Cow` is what
824 827 /// lets the first path stay a borrow while the second returns a `String`.
825 828 ///
826 - /// `screen` and `body` take the viewer because a document is not derivable: the
827 - /// shell carries whoever is looking, and a screen with parameters needs them to
828 - /// state its own title and measure. They take the request's parts as well,
829 - /// because a screen may read the address it was reached at: `/fan-plus` shows a
830 - /// welcome banner only on the way back from checkout, which is `?subscribed=true`
831 - /// and is carried nowhere else.
829 + /// `answer` produces the document and its markup **together, from one read**.
830 + /// They are not two jobs: a screen states its own title and measure from the
831 + /// same values that fill its holes, and `/fan-plus` reads a subscription to
832 + /// decide both. Two closures would read it twice per request and could disagree
833 + /// between the two reads, which is a worse bug than the one this mount exists to
834 + /// avoid.
835 + ///
836 + /// It takes the viewer because a document is not derivable: the shell carries
837 + /// whoever is looking. It takes what the address carried because a screen may
838 + /// read it: `/fan-plus` shows a welcome banner only on the way back from
839 + /// checkout, which is `?subscribed=true` and is carried nowhere else.
840 + ///
841 + /// It is fallible for the reason every other screen is. A screen here answers no
842 + /// `Screen`, so it never reaches the adapter and cannot use the adapter's
843 + /// refusal path; answering something plausible instead would be worse than
844 + /// answering nothing, because a member whose subscription could not be read
845 + /// would be shown the page that asks them to subscribe. The status comes off the
846 + /// `RouteError` exactly as `quasi_axum` takes it, and the body is empty for
847 + /// `quasi_axum::unresolved`'s reason: nothing was reached, so there is nothing to
848 + /// say that the status does not.
832 849 ///
833 850 /// Pairing a body with the wrong screen serves one page's markup inside
834 851 /// another's document, which nothing here can catch; what catches it is
@@ -837,9 +854,8 @@
837 854 fn served_document_mount(
838 855 app: &AppState,
839 856 path: &'static str,
840 - screen: fn(&Viewer, &Carried) -> quasi_router::Screen,
841 857 renderer: fn(&Viewer) -> quasi_webview::Webview,
842 - body: fn(&Viewer, &Carried) -> std::borrow::Cow<'static, str>,
858 + answer: fn(&Viewer, &Carried) -> Result<Served, quasi_router::RouteError>,
843 859 ) -> axum::Router {
844 860 let app = app.clone();
845 861 axum::Router::new().route(
@@ -859,28 +875,35 @@
859 875 };
860 876
861 877 let carried = Carried::of(&parts);
862 - let markup = body(&viewer, &carried);
863 - axum::response::Html(served(&viewer, &carried, screen, renderer, &markup))
864 - .into_response()
878 + match answer(&viewer, &carried) {
879 + Ok(Served { screen, markup }) => {
880 + axum::response::Html(renderer(&viewer).served(&screen, &markup))
881 + .into_response()
882 + }
883 + // `http_status` answers a bare `u16`, and a status this
884 + // server cannot spell is this server being broken rather
885 + // than the reader being refused.
886 + Err(refusal) => axum::http::StatusCode::from_u16(refusal.class.http_status())
887 + .unwrap_or(axum::http::StatusCode::INTERNAL_SERVER_ERROR)
888 + .into_response(),
889 + }
865 890 }
866 891 }),
867 892 )
868 893 }
869 894
870 - /// The document written around markup this renderer already produced.
895 + /// What a screen on the seam answers with: its document, and the markup to draw
896 + /// inside it.
871 897 ///
872 - /// Split out only so [`served_document_mount`] reads as one expression, and
873 - /// because `Webview::served` carries the one caveat worth keeping next to a
874 - /// call: the markup has to have come from this renderer, which is what
875 - /// `residuals::tests` asserts and nothing at this level can.
876 - fn served(
877 - viewer: &Viewer,
878 - carried: &Carried,
879 - screen: fn(&Viewer, &Carried) -> quasi_router::Screen,
880 - renderer: fn(&Viewer) -> quasi_webview::Webview,
881 - markup: &str,
882 - ) -> String {
883 - renderer(viewer).served(&screen(viewer, carried), markup)
898 + /// The pair rather than two returns, because they have to come from one read.
899 + /// `Webview::served` carries the caveat worth keeping next to the call: the
900 + /// markup has to have come from this renderer, which is what `residuals::tests`
901 + /// asserts and nothing at this level can.
902 + pub struct Served {
903 + /// The document: the title, the measure, the shell.
904 + pub screen: quasi_router::Screen,
905 + /// The regions, already written. Borrowed when the screen reads nothing.
906 + pub markup: std::borrow::Cow<'static, str>,
884 907 }
885 908
886 909 /// What the address carried, for a screen on the seam that reads it.
@@ -115,7 +115,14 @@
115 115 //! Every staged screen's markup with the request taken out of it, as a\n\
116 116 //! `static` the compiler builds. See the module above this one for why\n\
117 117 //! this is generated rather than derived at startup, and for the test\n\
118 - //! that fails when it is stale.\n\n",
118 + //! that fails when it is stale.\n\n\
119 + // Not formatted, because the staleness test compares this file with what\n\
120 + // `generate` produces, byte for byte. `cargo fmt` rewrapping a `static`\n\
121 + // here would fail that test against markup nobody had changed, and the\n\
122 + // obvious repair -- regenerate, then format -- puts it straight back.\n\
123 + // Nothing reads this file for pleasure; the markup in it is one line per\n\
124 + // screen whatever the layout.\n\
125 + #![cfg_attr(rustfmt, rustfmt::skip)]\n\n",
119 126 );
120 127 for (name, shape) in roster() {
121 128 out.push_str(&derive(shape).as_rust(name));
@@ -5,103 +5,76 @@
5 5 //! this is generated rather than derived at startup, and for the test
6 6 //! that fails when it is stale.
7 7
8 - pub static POLICY: ::quasi_router::stage::Residual = ::quasi_router::stage::Residual::compiled(&[
9 - ::quasi_router::stage::Op::Lit(::std::borrow::Cow::Borrowed(
10 - "<div id=\"policy\" class=\"region pane\"><h1 class=\"heading\">Content Policy</h1><p class=\"text\">Makenotwork exists so creators can sell their work on fair terms. This policy describes what belongs here, what doesn&#39;t, and how we handle problems.</p><h2 class=\"heading\">What&#39;s Welcome</h2><div class=\"rich\" data-disable-scripting><p>Creative work across all supported types:</p>\n<ul>\n<li>Software, plugins, presets, and templates</li>\n<li>Audio: music, podcasts, samples, sound design</li>\n<li>Writing: articles, guides, courses, fiction</li>\n<li>Visual work: images, photography, design assets</li>\n<li>Video: tutorials, performances, documentaries</li>\n</ul>\n<p>If you made it and it's legal to distribute, it belongs here.</p>\n</div><h2 class=\"heading\">What&#39;s Not Allowed</h2><div class=\"rich\" data-disable-scripting><ul>\n<li>Content that violates applicable law</li>\n<li>Harassment, threats, or doxxing</li>\n<li>Spam, deceptive listings, or bait-and-switch pricing</li>\n<li>Malware, exploits, or tools designed to cause harm</li>\n<li>Impersonation of other creators or organizations</li>\n<li>Content you don't have the rights to distribute</li>\n</ul>\n</div><h2 class=\"heading\">How We Handle Issues</h2><div class=\"rich\" data-disable-scripting><p>During private alpha, every creator has a direct relationship with the admin. If something comes up, we talk about it. No automated takedowns, no faceless tickets.</p>\n<p>Post-alpha, we'll introduce a formal process with written notice of any policy violation, an opportunity to appeal, and continued access to data export throughout.</p>\n</div><h2 class=\"heading\">Your Rights</h2><div class=\"rich\" data-disable-scripting><ul>\n<li>Full data export is always available: your content, metadata, and transaction history</li>\n<li>If we ever moderate content or suspend an account, you'll get a clear explanation of what policy was violated</li>\n<li>You'll have the opportunity to appeal</li>\n<li>You can export your data even while suspended (excluding content we can't legally host)</li>\n</ul>\n<p>These commitments are part of our <a href=\"/docs/guarantees\" rel=\"noopener noreferrer\">creator guarantees</a>.</p>\n</div><h2 class=\"heading\">Software Downloads</h2><div class=\"rich\" data-disable-scripting><p>Makenotwork hosts downloadable software uploaded by creators. While we take steps to make sure downloads are safe:</p>\n<ul>\n<li>Creators are responsible for the safety and integrity of their uploads</li>\n<li>Users should verify downloads with antivirus software before running them</li>\n<li>We do not guarantee that any download is free of malware or other harmful content</li>\n<li>Report suspicious downloads to <strong>reports@makenot.work</strong></li>\n</ul>\n</div><h2 class=\"heading\">Other Policies</h2><ul class=\"list\"><li class=\"row\" data-row><span class=\"row-primary\">Terms of Service</span><span class=\"row-secondary\">What you agree to by using Makenotwork</span><span class=\"row-actions\"><a class=\"button\" data-act href=\"/docs/terms-of-service\">Read</a></span></li><li class=\"row\" data-row><span class=\"row-primary\">Privacy Policy</span><span class=\"row-secondary\">What we collect, why, and how to exercise your rights</span><span class=\"row-actions\"><a class=\"button\" data-act href=\"/docs/privacy-policy\">Read</a></span></li><li class=\"row\" data-row><span class=\"row-primary\">Payments &amp; Refunds</span><span class=\"row-secondary\">Merchant-of-record model, refunds, chargebacks</span><span class=\"row-actions\"><a class=\"button\" data-act href=\"/docs/payments\">Read</a></span></li><li class=\"row\" data-row><span class=\"row-primary\">Acceptable Use</span><span class=\"row-secondary\">Specific behaviour that gets accounts suspended</span><span class=\"row-actions\"><a class=\"button\" data-act href=\"/docs/acceptable-use\">Read</a></span></li><li class=\"row\" data-row><span class=\"row-primary\">Copyright &amp; DMCA</span><span class=\"row-secondary\">How takedowns and counter-notifications work</span><span class=\"row-actions\"><a class=\"button\" data-act href=\"/docs/copyright\">Read</a></span></li><li class=\"row\" data-row><span class=\"row-primary\">Appeals</span><span class=\"row-secondary\">How to challenge a moderation decision</span><span class=\"row-actions\"><a class=\"button\" data-act href=\"/docs/appeals\">Read</a></span></li><li class=\"row\" data-row><span class=\"row-primary\">Mailing List Data Processing</span><span class=\"row-secondary\">Who answers a subscriber&#39;s request about a project mailing list</span><span class=\"row-actions\"><a class=\"button\" data-act href=\"/docs/mailing-list-data-processing\">Read</a></span></li></ul><h2 class=\"heading\">Questions</h2><div class=\"rich\" data-disable-scripting><p>If something's unclear or you want to check before posting, reach out at <strong>policy@makenot.work</strong>.</p>\n</div><div class=\"anchored\" id=\"policy-anchored\" data-menu=\"anchored\" hidden></div></div>",
11 - )),
12 - ]);
8 + // Not formatted, because the staleness test compares this file with what
9 + // `generate` produces, byte for byte. `cargo fmt` rewrapping a `static`
10 + // here would fail that test against markup nobody had changed, and the
11 + // obvious repair -- regenerate, then format -- puts it straight back.
12 + // Nothing reads this file for pleasure; the markup in it is one line per
13 + // screen whatever the layout.
14 + #![cfg_attr(rustfmt, rustfmt::skip)]
13 15
14 - pub static TEAM: ::quasi_router::stage::Residual = ::quasi_router::stage::Residual::compiled(&[
15 - ::quasi_router::stage::Op::Lit(::std::borrow::Cow::Borrowed(
16 - "<div id=\"team\" class=\"region pane\"><h1 class=\"heading\">Team</h1><p class=\"text\">Small by design. The base platform was designed by the founder, who intends to stay as the technical lead through the project&#39;s growth.</p><h2 class=\"heading\">Founder</h2><ul class=\"list\"><li class=\"row\" data-row><span class=\"row-primary\">Max</span><span class=\"row-secondary\">CEO &amp; Tech Lead</span><span class=\"row-meta\">Designed and built the platform.</span><span class=\"row-actions\"><a class=\"button\" data-act href=\"/u/max\">@max</a></span></li></ul><section id=\"founder-bio\" class=\"region group\" data-showing=\"at-most-one\"><button type=\"button\" class=\"button\" data-shows=\"0\" aria-expanded=\"false\" _=\"on click toggle .current on the first &lt;[data-frame=&#39;founder-bio&#39;]/&gt; then if the first &lt;[data-frame=&#39;founder-bio&#39;]/&gt; matches &#39;.current&#39; set @aria-expanded of me to &#39;true&#39; else set @aria-expanded of me to &#39;false&#39; end\">Bio</button><div class=\"showing-frame\" data-frame=\"founder-bio\" data-shown=\"0\"><div id=\"founder-bio-body\" class=\"region pane\"><p class=\"text\">I started in the creator space as a young kid making backgrounds and montages for CoD MW2 players. I picked up programming around the same time, helping Minecraft server owners with whatever they needed. I spent the years after that focused on my education: a BA in mathematics at the University of Chicago, then a PhD in mathematics at UC San Diego. Afterward I decided to start my own business, and here we are.</p><div class=\"anchored\" id=\"founder-bio-body-anchored\" data-menu=\"anchored\" hidden></div></div></div><div class=\"anchored\" id=\"founder-bio-anchored\" data-menu=\"anchored\" hidden></div></section><div class=\"anchored\" id=\"team-anchored\" data-menu=\"anchored\" hidden></div></div>",
17 - )),
18 - ]);
16 + pub static POLICY: ::quasi_router::stage::Residual =
17 + ::quasi_router::stage::Residual::compiled(&[
18 + ::quasi_router::stage::Op::Lit(::std::borrow::Cow::Borrowed("<div id=\"policy\" class=\"region pane\"><h1 class=\"heading\">Content Policy</h1><p class=\"text\">Makenotwork exists so creators can sell their work on fair terms. This policy describes what belongs here, what doesn&#39;t, and how we handle problems.</p><h2 class=\"heading\">What&#39;s Welcome</h2><div class=\"rich\" data-disable-scripting><p>Creative work across all supported types:</p>\n<ul>\n<li>Software, plugins, presets, and templates</li>\n<li>Audio: music, podcasts, samples, sound design</li>\n<li>Writing: articles, guides, courses, fiction</li>\n<li>Visual work: images, photography, design assets</li>\n<li>Video: tutorials, performances, documentaries</li>\n</ul>\n<p>If you made it and it's legal to distribute, it belongs here.</p>\n</div><h2 class=\"heading\">What&#39;s Not Allowed</h2><div class=\"rich\" data-disable-scripting><ul>\n<li>Content that violates applicable law</li>\n<li>Harassment, threats, or doxxing</li>\n<li>Spam, deceptive listings, or bait-and-switch pricing</li>\n<li>Malware, exploits, or tools designed to cause harm</li>\n<li>Impersonation of other creators or organizations</li>\n<li>Content you don't have the rights to distribute</li>\n</ul>\n</div><h2 class=\"heading\">How We Handle Issues</h2><div class=\"rich\" data-disable-scripting><p>During private alpha, every creator has a direct relationship with the admin. If something comes up, we talk about it. No automated takedowns, no faceless tickets.</p>\n<p>Post-alpha, we'll introduce a formal process with written notice of any policy violation, an opportunity to appeal, and continued access to data export throughout.</p>\n</div><h2 class=\"heading\">Your Rights</h2><div class=\"rich\" data-disable-scripting><ul>\n<li>Full data export is always available: your content, metadata, and transaction history</li>\n<li>If we ever moderate content or suspend an account, you'll get a clear explanation of what policy was violated</li>\n<li>You'll have the opportunity to appeal</li>\n<li>You can export your data even while suspended (excluding content we can't legally host)</li>\n</ul>\n<p>These commitments are part of our <a href=\"/docs/guarantees\" rel=\"noopener noreferrer\">creator guarantees</a>.</p>\n</div><h2 class=\"heading\">Software Downloads</h2><div class=\"rich\" data-disable-scripting><p>Makenotwork hosts downloadable software uploaded by creators. While we take steps to make sure downloads are safe:</p>\n<ul>\n<li>Creators are responsible for the safety and integrity of their uploads</li>\n<li>Users should verify downloads with antivirus software before running them</li>\n<li>We do not guarantee that any download is free of malware or other harmful content</li>\n<li>Report suspicious downloads to <strong>reports@makenot.work</strong></li>\n</ul>\n</div><h2 class=\"heading\">Other Policies</h2><ul class=\"list\"><li class=\"row\" data-row><span class=\"row-primary\">Terms of Service</span><span class=\"row-secondary\">What you agree to by using Makenotwork</span><span class=\"row-actions\"><a class=\"button\" data-act href=\"/docs/terms-of-service\">Read</a></span></li><li class=\"row\" data-row><span class=\"row-primary\">Privacy Policy</span><span class=\"row-secondary\">What we collect, why, and how to exercise your rights</span><span class=\"row-actions\"><a class=\"button\" data-act href=\"/docs/privacy-policy\">Read</a></span></li><li class=\"row\" data-row><span class=\"row-primary\">Payments &amp; Refunds</span><span class=\"row-secondary\">Merchant-of-record model, refunds, chargebacks</span><span class=\"row-actions\"><a class=\"button\" data-act href=\"/docs/payments\">Read</a></span></li><li class=\"row\" data-row><span class=\"row-primary\">Acceptable Use</span><span class=\"row-secondary\">Specific behaviour that gets accounts suspended</span><span class=\"row-actions\"><a class=\"button\" data-act href=\"/docs/acceptable-use\">Read</a></span></li><li class=\"row\" data-row><span class=\"row-primary\">Copyright &amp; DMCA</span><span class=\"row-secondary\">How takedowns and counter-notifications work</span><span class=\"row-actions\"><a class=\"button\" data-act href=\"/docs/copyright\">Read</a></span></li><li class=\"row\" data-row><span class=\"row-primary\">Appeals</span><span class=\"row-secondary\">How to challenge a moderation decision</span><span class=\"row-actions\"><a class=\"button\" data-act href=\"/docs/appeals\">Read</a></span></li><li class=\"row\" data-row><span class=\"row-primary\">Mailing List Data Processing</span><span class=\"row-secondary\">Who answers a subscriber&#39;s request about a project mailing list</span><span class=\"row-actions\"><a class=\"button\" data-act href=\"/docs/mailing-list-data-processing\">Read</a></span></li></ul><h2 class=\"heading\">Questions</h2><div class=\"rich\" data-disable-scripting><p>If something's unclear or you want to check before posting, reach out at <strong>policy@makenot.work</strong>.</p>\n</div><div class=\"anchored\" id=\"policy-anchored\" data-menu=\"anchored\" hidden></div></div>")),
19 + ]);
19 20
20 - pub static USE_CASES: ::quasi_router::stage::Residual = ::quasi_router::stage::Residual::compiled(
21 - &[
22 - ::quasi_router::stage::Op::Lit(::std::borrow::Cow::Borrowed(
23 - "<div id=\"use-cases\" class=\"region pane\"><h1 class=\"heading\">Use Cases</h1><p class=\"text\">A flat monthly fee. 0% platform cut. Who it&#39;s built for:</p><h2 class=\"heading\">Available now</h2><section id=\"use-case-profiles\" class=\"region group\"><section id=\"musicians\" class=\"region group\"><h2 class=\"heading\">Musicians</h2><p class=\"text\">Bands, solo artists, producers</p><p class=\"text\">Sell albums, singles, and EPs with in-browser streaming, chapter markers, and cover art.</p><ul class=\"list\"><li class=\"row\" data-row><span class=\"row-primary\">MP3, FLAC, WAV, OGG, AAC, AIFF upload</span></li><li class=\"row\" data-row><span class=\"row-primary\">In-browser audio player with chapters</span></li><li class=\"row\" data-row><span class=\"row-primary\">Cover art and rich metadata</span></li><li class=\"row\" data-row><span class=\"row-primary\">RSS feed per project</span></li><li class=\"row\" data-row><span class=\"row-primary\">Pay-what-you-want pricing</span></li></ul><p class=\"text\">",
24 - )),
21 + pub static TEAM: ::quasi_router::stage::Residual =
22 + ::quasi_router::stage::Residual::compiled(&[
23 + ::quasi_router::stage::Op::Lit(::std::borrow::Cow::Borrowed("<div id=\"team\" class=\"region pane\"><h1 class=\"heading\">Team</h1><p class=\"text\">Small by design. The base platform was designed by the founder, who intends to stay as the technical lead through the project&#39;s growth.</p><h2 class=\"heading\">Founder</h2><ul class=\"list\"><li class=\"row\" data-row><span class=\"row-primary\">Max</span><span class=\"row-secondary\">CEO &amp; Tech Lead</span><span class=\"row-meta\">Designed and built the platform.</span><span class=\"row-actions\"><a class=\"button\" data-act href=\"/u/max\">@max</a></span></li></ul><section id=\"founder-bio\" class=\"region group\" data-showing=\"at-most-one\"><button type=\"button\" class=\"button\" data-shows=\"0\" aria-expanded=\"false\" _=\"on click toggle .current on the first &lt;[data-frame=&#39;founder-bio&#39;]/&gt; then if the first &lt;[data-frame=&#39;founder-bio&#39;]/&gt; matches &#39;.current&#39; set @aria-expanded of me to &#39;true&#39; else set @aria-expanded of me to &#39;false&#39; end\">Bio</button><div class=\"showing-frame\" data-frame=\"founder-bio\" data-shown=\"0\"><div id=\"founder-bio-body\" class=\"region pane\"><p class=\"text\">I started in the creator space as a young kid making backgrounds and montages for CoD MW2 players. I picked up programming around the same time, helping Minecraft server owners with whatever they needed. I spent the years after that focused on my education: a BA in mathematics at the University of Chicago, then a PhD in mathematics at UC San Diego. Afterward I decided to start my own business, and here we are.</p><div class=\"anchored\" id=\"founder-bio-body-anchored\" data-menu=\"anchored\" hidden></div></div></div><div class=\"anchored\" id=\"founder-bio-anchored\" data-menu=\"anchored\" hidden></div></section><div class=\"anchored\" id=\"team-anchored\" data-menu=\"anchored\" hidden></div></div>")),
24 + ]);
25 +
26 + pub static USE_CASES: ::quasi_router::stage::Residual =
27 + ::quasi_router::stage::Residual::compiled(&[
28 + ::quasi_router::stage::Op::Lit(::std::borrow::Cow::Borrowed("<div id=\"use-cases\" class=\"region pane\"><h1 class=\"heading\">Use Cases</h1><p class=\"text\">A flat monthly fee. 0% platform cut. Who it&#39;s built for:</p><h2 class=\"heading\">Available now</h2><section id=\"use-case-profiles\" class=\"region group\"><section id=\"musicians\" class=\"region group\"><h2 class=\"heading\">Musicians</h2><p class=\"text\">Bands, solo artists, producers</p><p class=\"text\">Sell albums, singles, and EPs with in-browser streaming, chapter markers, and cover art.</p><ul class=\"list\"><li class=\"row\" data-row><span class=\"row-primary\">MP3, FLAC, WAV, OGG, AAC, AIFF upload</span></li><li class=\"row\" data-row><span class=\"row-primary\">In-browser audio player with chapters</span></li><li class=\"row\" data-row><span class=\"row-primary\">Cover art and rich metadata</span></li><li class=\"row\" data-row><span class=\"row-primary\">RSS feed per project</span></li><li class=\"row\" data-row><span class=\"row-primary\">Pay-what-you-want pricing</span></li></ul><p class=\"text\">")),
25 29 ::quasi_router::stage::Op::Hole { scope: 0, id: 0 },
26 - ::quasi_router::stage::Op::Lit(::std::borrow::Cow::Borrowed(
27 - "</p><div class=\"anchored\" id=\"musicians-anchored\" data-menu=\"anchored\" hidden></div></section><section id=\"podcasters\" class=\"region group\"><h2 class=\"heading\">Podcasters</h2><p class=\"text\">Independent shows, networks</p><p class=\"text\">Host and distribute your podcast with full RSS support for every major directory.</p><ul class=\"list\"><li class=\"row\" data-row><span class=\"row-primary\">RSS for Apple, Spotify, Pocket Casts</span></li><li class=\"row\" data-row><span class=\"row-primary\">Chapter markers</span></li><li class=\"row\" data-row><span class=\"row-primary\">Subscriber-only feeds</span></li><li class=\"row\" data-row><span class=\"row-primary\">Broadcast emails to followers</span></li></ul><p class=\"text\">",
28 - )),
30 + ::quasi_router::stage::Op::Lit(::std::borrow::Cow::Borrowed("</p><div class=\"anchored\" id=\"musicians-anchored\" data-menu=\"anchored\" hidden></div></section><section id=\"podcasters\" class=\"region group\"><h2 class=\"heading\">Podcasters</h2><p class=\"text\">Independent shows, networks</p><p class=\"text\">Host and distribute your podcast with full RSS support for every major directory.</p><ul class=\"list\"><li class=\"row\" data-row><span class=\"row-primary\">RSS for Apple, Spotify, Pocket Casts</span></li><li class=\"row\" data-row><span class=\"row-primary\">Chapter markers</span></li><li class=\"row\" data-row><span class=\"row-primary\">Subscriber-only feeds</span></li><li class=\"row\" data-row><span class=\"row-primary\">Broadcast emails to followers</span></li></ul><p class=\"text\">")),
29 31 ::quasi_router::stage::Op::Hole { scope: 0, id: 1 },
30 - ::quasi_router::stage::Op::Lit(::std::borrow::Cow::Borrowed(
31 - "</p><div class=\"anchored\" id=\"podcasters-anchored\" data-menu=\"anchored\" hidden></div></section><section id=\"writers\" class=\"region group\"><h2 class=\"heading\">Writers</h2><p class=\"text\">Bloggers, newsletter writers, authors</p><p class=\"text\">Publish long-form writing with Markdown, per-project blogs, and subscriber broadcasts.</p><ul class=\"list\"><li class=\"row\" data-row><span class=\"row-primary\">Markdown editor with formatting</span></li><li class=\"row\" data-row><span class=\"row-primary\">Per-project blog</span></li><li class=\"row\" data-row><span class=\"row-primary\">RSS feed</span></li><li class=\"row\" data-row><span class=\"row-primary\">Scheduled publishing</span></li><li class=\"row\" data-row><span class=\"row-primary\">Broadcast emails</span></li></ul><p class=\"text\">",
32 - )),
32 + ::quasi_router::stage::Op::Lit(::std::borrow::Cow::Borrowed("</p><div class=\"anchored\" id=\"podcasters-anchored\" data-menu=\"anchored\" hidden></div></section><section id=\"writers\" class=\"region group\"><h2 class=\"heading\">Writers</h2><p class=\"text\">Bloggers, newsletter writers, authors</p><p class=\"text\">Publish long-form writing with Markdown, per-project blogs, and subscriber broadcasts.</p><ul class=\"list\"><li class=\"row\" data-row><span class=\"row-primary\">Markdown editor with formatting</span></li><li class=\"row\" data-row><span class=\"row-primary\">Per-project blog</span></li><li class=\"row\" data-row><span class=\"row-primary\">RSS feed</span></li><li class=\"row\" data-row><span class=\"row-primary\">Scheduled publishing</span></li><li class=\"row\" data-row><span class=\"row-primary\">Broadcast emails</span></li></ul><p class=\"text\">")),
33 33 ::quasi_router::stage::Op::Hole { scope: 0, id: 2 },
34 - ::quasi_router::stage::Op::Lit(::std::borrow::Cow::Borrowed(
35 - "</p><div class=\"anchored\" id=\"writers-anchored\" data-menu=\"anchored\" hidden></div></section><section id=\"developers\" class=\"region group\"><h2 class=\"heading\">Software Developers</h2><p class=\"text\">Indie devs, tool makers, plugin authors</p><p class=\"text\">Distribute software with versioned releases, license keys, and a built-in git browser.</p><ul class=\"list\"><li class=\"row\" data-row><span class=\"row-primary\">Versioned releases with changelogs</span></li><li class=\"row\" data-row><span class=\"row-primary\">License keys with activation tracking</span></li><li class=\"row\" data-row><span class=\"row-primary\">Git source browser</span></li><li class=\"row\" data-row><span class=\"row-primary\">Promo codes and discounts</span></li></ul><p class=\"text\">",
36 - )),
34 + ::quasi_router::stage::Op::Lit(::std::borrow::Cow::Borrowed("</p><div class=\"anchored\" id=\"writers-anchored\" data-menu=\"anchored\" hidden></div></section><section id=\"developers\" class=\"region group\"><h2 class=\"heading\">Software Developers</h2><p class=\"text\">Indie devs, tool makers, plugin authors</p><p class=\"text\">Distribute software with versioned releases, license keys, and a built-in git browser.</p><ul class=\"list\"><li class=\"row\" data-row><span class=\"row-primary\">Versioned releases with changelogs</span></li><li class=\"row\" data-row><span class=\"row-primary\">License keys with activation tracking</span></li><li class=\"row\" data-row><span class=\"row-primary\">Git source browser</span></li><li class=\"row\" data-row><span class=\"row-primary\">Promo codes and discounts</span></li></ul><p class=\"text\">")),
37 35 ::quasi_router::stage::Op::Hole { scope: 0, id: 3 },
38 - ::quasi_router::stage::Op::Lit(::std::borrow::Cow::Borrowed(
39 - "</p><div class=\"anchored\" id=\"developers-anchored\" data-menu=\"anchored\" hidden></div></section><section id=\"sample-packs\" class=\"region group\"><h2 class=\"heading\">Sample Packs</h2><p class=\"text\">Sound designers, beat makers, foley artists</p><p class=\"text\">Sell sample packs and sound effects with audio previews and versioned downloads.</p><ul class=\"list\"><li class=\"row\" data-row><span class=\"row-primary\">Audio previews in-browser</span></li><li class=\"row\" data-row><span class=\"row-primary\">Versioned downloads</span></li><li class=\"row\" data-row><span class=\"row-primary\">Hierarchical tags for organization</span></li><li class=\"row\" data-row><span class=\"row-primary\">Pay-what-you-want pricing</span></li><li class=\"row\" data-row><span class=\"row-primary\">Cover art</span></li></ul><p class=\"text\">",
40 - )),
36 + ::quasi_router::stage::Op::Lit(::std::borrow::Cow::Borrowed("</p><div class=\"anchored\" id=\"developers-anchored\" data-menu=\"anchored\" hidden></div></section><section id=\"sample-packs\" class=\"region group\"><h2 class=\"heading\">Sample Packs</h2><p class=\"text\">Sound designers, beat makers, foley artists</p><p class=\"text\">Sell sample packs and sound effects with audio previews and versioned downloads.</p><ul class=\"list\"><li class=\"row\" data-row><span class=\"row-primary\">Audio previews in-browser</span></li><li class=\"row\" data-row><span class=\"row-primary\">Versioned downloads</span></li><li class=\"row\" data-row><span class=\"row-primary\">Hierarchical tags for organization</span></li><li class=\"row\" data-row><span class=\"row-primary\">Pay-what-you-want pricing</span></li><li class=\"row\" data-row><span class=\"row-primary\">Cover art</span></li></ul><p class=\"text\">")),
41 37 ::quasi_router::stage::Op::Hole { scope: 0, id: 4 },
42 - ::quasi_router::stage::Op::Lit(::std::borrow::Cow::Borrowed(
43 - "</p><div class=\"anchored\" id=\"sample-packs-anchored\" data-menu=\"anchored\" hidden></div></section><section id=\"digital-art\" class=\"region group\"><h2 class=\"heading\">Digital Art &amp; Photography</h2><p class=\"text\">Illustrators, photographers, font designers</p><p class=\"text\">Sell digital art, photography, and fonts with versioned releases and subscription tiers.</p><ul class=\"list\"><li class=\"row\" data-row><span class=\"row-primary\">Any file type supported</span></li><li class=\"row\" data-row><span class=\"row-primary\">Versioned releases</span></li><li class=\"row\" data-row><span class=\"row-primary\">Subscription tiers</span></li><li class=\"row\" data-row><span class=\"row-primary\">Cover images</span></li></ul><p class=\"text\">",
44 - )),
38 + ::quasi_router::stage::Op::Lit(::std::borrow::Cow::Borrowed("</p><div class=\"anchored\" id=\"sample-packs-anchored\" data-menu=\"anchored\" hidden></div></section><section id=\"digital-art\" class=\"region group\"><h2 class=\"heading\">Digital Art &amp; Photography</h2><p class=\"text\">Illustrators, photographers, font designers</p><p class=\"text\">Sell digital art, photography, and fonts with versioned releases and subscription tiers.</p><ul class=\"list\"><li class=\"row\" data-row><span class=\"row-primary\">Any file type supported</span></li><li class=\"row\" data-row><span class=\"row-primary\">Versioned releases</span></li><li class=\"row\" data-row><span class=\"row-primary\">Subscription tiers</span></li><li class=\"row\" data-row><span class=\"row-primary\">Cover images</span></li></ul><p class=\"text\">")),
45 39 ::quasi_router::stage::Op::Hole { scope: 0, id: 5 },
46 - ::quasi_router::stage::Op::Lit(::std::borrow::Cow::Borrowed(
47 - "</p><div class=\"anchored\" id=\"digital-art-anchored\" data-menu=\"anchored\" hidden></div></section><section id=\"educators\" class=\"region group\"><h2 class=\"heading\">Educators</h2><p class=\"text\">Course creators, tutors, workshop leaders</p><p class=\"text\">Publish courses and teaching materials with text content, downloads, and subscriptions.</p><ul class=\"list\"><li class=\"row\" data-row><span class=\"row-primary\">Text content with Markdown</span></li><li class=\"row\" data-row><span class=\"row-primary\">Downloadable materials</span></li><li class=\"row\" data-row><span class=\"row-primary\">Subscription tiers</span></li><li class=\"row\" data-row><span class=\"row-primary\">Scheduled publishing</span></li></ul><p class=\"text\">",
48 - )),
40 + ::quasi_router::stage::Op::Lit(::std::borrow::Cow::Borrowed("</p><div class=\"anchored\" id=\"digital-art-anchored\" data-menu=\"anchored\" hidden></div></section><section id=\"educators\" class=\"region group\"><h2 class=\"heading\">Educators</h2><p class=\"text\">Course creators, tutors, workshop leaders</p><p class=\"text\">Publish courses and teaching materials with text content, downloads, and subscriptions.</p><ul class=\"list\"><li class=\"row\" data-row><span class=\"row-primary\">Text content with Markdown</span></li><li class=\"row\" data-row><span class=\"row-primary\">Downloadable materials</span></li><li class=\"row\" data-row><span class=\"row-primary\">Subscription tiers</span></li><li class=\"row\" data-row><span class=\"row-primary\">Scheduled publishing</span></li></ul><p class=\"text\">")),
49 41 ::quasi_router::stage::Op::Hole { scope: 0, id: 6 },
50 - ::quasi_router::stage::Op::Lit(::std::borrow::Cow::Borrowed(
51 - "</p><div class=\"anchored\" id=\"educators-anchored\" data-menu=\"anchored\" hidden></div></section><section id=\"game-devs\" class=\"region group\"><h2 class=\"heading\">Game Developers</h2><p class=\"text\">Indie games, mods, TTRPG content</p><p class=\"text\">Distribute games up to 20GB per file with versioned downloads, license keys, and promo codes. Need more than 20GB? Request a size increase from your dashboard.</p><ul class=\"list\"><li class=\"row\" data-row><span class=\"row-primary\">Up to 20GB per file (increase on request)</span></li><li class=\"row\" data-row><span class=\"row-primary\">Versioned downloads with changelogs</span></li><li class=\"row\" data-row><span class=\"row-primary\">License keys with activation limits</span></li><li class=\"row\" data-row><span class=\"row-primary\">Promo codes</span></li></ul><p class=\"text\">",
52 - )),
42 + ::quasi_router::stage::Op::Lit(::std::borrow::Cow::Borrowed("</p><div class=\"anchored\" id=\"educators-anchored\" data-menu=\"anchored\" hidden></div></section><section id=\"game-devs\" class=\"region group\"><h2 class=\"heading\">Game Developers</h2><p class=\"text\">Indie games, mods, TTRPG content</p><p class=\"text\">Distribute games up to 20GB per file with versioned downloads, license keys, and promo codes. Need more than 20GB? Request a size increase from your dashboard.</p><ul class=\"list\"><li class=\"row\" data-row><span class=\"row-primary\">Up to 20GB per file (increase on request)</span></li><li class=\"row\" data-row><span class=\"row-primary\">Versioned downloads with changelogs</span></li><li class=\"row\" data-row><span class=\"row-primary\">License keys with activation limits</span></li><li class=\"row\" data-row><span class=\"row-primary\">Promo codes</span></li></ul><p class=\"text\">")),
53 43 ::quasi_router::stage::Op::Hole { scope: 0, id: 7 },
54 - ::quasi_router::stage::Op::Lit(::std::borrow::Cow::Borrowed(
55 - "</p><div class=\"anchored\" id=\"game-devs-anchored\" data-menu=\"anchored\" hidden></div></section><section id=\"comic-creators\" class=\"region group\"><h2 class=\"heading\">Comic Creators</h2><p class=\"text\">Webcomic artists, graphic novelists</p><p class=\"text\">Sell digital comics and graphic novels with project organization and scheduled publishing.</p><ul class=\"list\"><li class=\"row\" data-row><span class=\"row-primary\">PDF, CBZ, and any file type</span></li><li class=\"row\" data-row><span class=\"row-primary\">Project organization</span></li><li class=\"row\" data-row><span class=\"row-primary\">Subscriptions</span></li><li class=\"row\" data-row><span class=\"row-primary\">Scheduled publishing</span></li></ul><p class=\"text\">",
56 - )),
44 + ::quasi_router::stage::Op::Lit(::std::borrow::Cow::Borrowed("</p><div class=\"anchored\" id=\"game-devs-anchored\" data-menu=\"anchored\" hidden></div></section><section id=\"comic-creators\" class=\"region group\"><h2 class=\"heading\">Comic Creators</h2><p class=\"text\">Webcomic artists, graphic novelists</p><p class=\"text\">Sell digital comics and graphic novels with project organization and scheduled publishing.</p><ul class=\"list\"><li class=\"row\" data-row><span class=\"row-primary\">PDF, CBZ, and any file type</span></li><li class=\"row\" data-row><span class=\"row-primary\">Project organization</span></li><li class=\"row\" data-row><span class=\"row-primary\">Subscriptions</span></li><li class=\"row\" data-row><span class=\"row-primary\">Scheduled publishing</span></li></ul><p class=\"text\">")),
57 45 ::quasi_router::stage::Op::Hole { scope: 0, id: 8 },
58 - ::quasi_router::stage::Op::Lit(::std::borrow::Cow::Borrowed(
59 - "</p><div class=\"anchored\" id=\"comic-creators-anchored\" data-menu=\"anchored\" hidden></div></section><div class=\"anchored\" id=\"use-case-profiles-anchored\" data-menu=\"anchored\" hidden></div></section><h2 class=\"heading\">Everyone gets</h2><section id=\"everyone-gets\" class=\"region group\"><ul class=\"list\"><li class=\"row\" data-row><span class=\"row-primary\">0% platform fee</span><span class=\"row-secondary\">Only ~3% payment processing. No percentage cuts, no revenue sharing.</span></li><li class=\"row\" data-row><span class=\"row-primary\">Full data export</span><span class=\"row-secondary\">Download everything anytime. Projects, items, sales, contacts: all yours.</span></li><li class=\"row\" data-row><span class=\"row-primary\">No lock-in</span><span class=\"row-secondary\">Month-to-month. Cancel anytime. Take your audience with you.</span></li><li class=\"row\" data-row><span class=\"row-primary\">Source available</span><span class=\"row-secondary\">Read the codebase. Verify every claim about privacy and data handling.</span></li></ul><div class=\"anchored\" id=\"everyone-gets-anchored\" data-menu=\"anchored\" hidden></div></section><a class=\"button\" data-act href=\"/join\">Join the Alpha</a><a class=\"button\" data-act href=\"/pricing\">Pricing Calculator</a><a class=\"button\" data-act href=\"/discover\">Browse as guest</a><a class=\"button\" data-act href=\"/docs/getting-started\">Creator Guide</a><div class=\"anchored\" id=\"use-cases-anchored\" data-menu=\"anchored\" hidden></div></div>",
60 - )),
61 - ],
62 - );
46 + ::quasi_router::stage::Op::Lit(::std::borrow::Cow::Borrowed("</p><div class=\"anchored\" id=\"comic-creators-anchored\" data-menu=\"anchored\" hidden></div></section><div class=\"anchored\" id=\"use-case-profiles-anchored\" data-menu=\"anchored\" hidden></div></section><h2 class=\"heading\">Everyone gets</h2><section id=\"everyone-gets\" class=\"region group\"><ul class=\"list\"><li class=\"row\" data-row><span class=\"row-primary\">0% platform fee</span><span class=\"row-secondary\">Only ~3% payment processing. No percentage cuts, no revenue sharing.</span></li><li class=\"row\" data-row><span class=\"row-primary\">Full data export</span><span class=\"row-secondary\">Download everything anytime. Projects, items, sales, contacts: all yours.</span></li><li class=\"row\" data-row><span class=\"row-primary\">No lock-in</span><span class=\"row-secondary\">Month-to-month. Cancel anytime. Take your audience with you.</span></li><li class=\"row\" data-row><span class=\"row-primary\">Source available</span><span class=\"row-secondary\">Read the codebase. Verify every claim about privacy and data handling.</span></li></ul><div class=\"anchored\" id=\"everyone-gets-anchored\" data-menu=\"anchored\" hidden></div></section><a class=\"button\" data-act href=\"/join\">Join the Alpha</a><a class=\"button\" data-act href=\"/pricing\">Pricing Calculator</a><a class=\"button\" data-act href=\"/discover\">Browse as guest</a><a class=\"button\" data-act href=\"/docs/getting-started\">Creator Guide</a><div class=\"anchored\" id=\"use-cases-anchored\" data-menu=\"anchored\" hidden></div></div>")),
47 + ]);
63 48
64 - pub static FAN_PLUS: ::quasi_router::stage::Residual = ::quasi_router::stage::Residual::compiled(
65 - &[
66 - ::quasi_router::stage::Op::Lit(::std::borrow::Cow::Borrowed(
67 - "<div id=\"fan-plus\" class=\"region pane\"><h1 class=\"heading\">Fan+</h1",
68 - )),
49 + pub static FAN_PLUS: ::quasi_router::stage::Residual =
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")),
69 52 ::quasi_router::stage::Op::Branch(::std::borrow::Cow::Borrowed(&[
70 - ::quasi_router::stage::Op::Lit(::std::borrow::Cow::Borrowed(
71 - "><div class=\"banner\" data-tone=\"success\" role=\"status\" aria-live=\"polite\">You&#39;re now a Fan+ member. Welcome.</div",
72 - )),
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 +
73 55 ])),
74 56 ::quasi_router::stage::Op::Branch(::std::borrow::Cow::Borrowed(&[
75 - ::quasi_router::stage::Op::Lit(::std::borrow::Cow::Borrowed(
76 - "><section id=\"fan-plus-membership\" class=\"region group\"><p class=\"text\">Your Fan+ membership is active.",
77 - )),
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.")),
78 58 ::quasi_router::stage::Op::Branch(::std::borrow::Cow::Borrowed(&[
79 - ::quasi_router::stage::Op::Lit(::std::borrow::Cow::Borrowed(
80 - "</p><p class=\"text\">Current period ends: ",
81 - )),
59 + ::quasi_router::stage::Op::Lit(::std::borrow::Cow::Borrowed("</p><p class=\"text\">Current period ends: ")),
82 60 ::quasi_router::stage::Op::Hole { scope: 1, id: 0 },
61 +
83 62 ])),
84 - ::quasi_router::stage::Op::Lit(::std::borrow::Cow::Borrowed(
85 - "</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",
86 - )),
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 +
87 65 ])),
88 66 ::quasi_router::stage::Op::Branch(::std::borrow::Cow::Borrowed(&[
89 - ::quasi_router::stage::Op::Lit(::std::borrow::Cow::Borrowed(
90 - "><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",
91 - )),
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 +
92 69 ])),
93 70 ::quasi_router::stage::Op::Branch(::std::borrow::Cow::Borrowed(&[
94 - ::quasi_router::stage::Op::Lit(::std::borrow::Cow::Borrowed(
95 - "><button type=\"button\" class=\"button\" data-act hx-post=\"/stripe/fan-plus\" hx-swap=\"outerMorph\" hx-disable=\"this\" data-awaiting=\"indeterminate\">Join Fan+</button",
96 - )),
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 +
97 73 ])),
98 74 ::quasi_router::stage::Op::Branch(::std::borrow::Cow::Borrowed(&[
99 - ::quasi_router::stage::Op::Lit(::std::borrow::Cow::Borrowed(
100 - "><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",
101 - )),
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")),
76 +
102 77 ])),
103 - ::quasi_router::stage::Op::Lit(::std::borrow::Cow::Borrowed(
104 - "><div class=\"anchored\" id=\"fan-plus-anchored\" data-menu=\"anchored\" hidden></div></div>",
105 - )),
106 - ],
107 - );
78 + ::quasi_router::stage::Op::Lit(::std::borrow::Cow::Borrowed("><div class=\"anchored\" id=\"fan-plus-anchored\" data-menu=\"anchored\" hidden></div></div>")),
79 + ]);
80 +