Skip to main content

max / makenotwork

v0.6.14: integrate founder pricing into landing page creator card Replaces the standalone founder-pricing alert with a tier grid plus slots counter embedded in the creator card, and tightens the tagline. Adds a DIY-exclusion doc note on mark_user_as_founder to prevent the future DIY checkout path from invoking founder pricing.
Author: Max J. <87768334+MaxJMath@users.noreply.github.com> · 2026-05-21 03:18 UTC
Commit: 39d59986544ad4d42235f637c624ca85ca0e2985
Parent: 9752bf3
5 files changed, +149 insertions, -21 deletions
@@ -3551,7 +3551,7 @@ dependencies = [
3551 3551
3552 3552 [[package]]
3553 3553 name = "makenotwork"
3554 - version = "0.6.11"
3554 + version = "0.6.14"
3555 3555 dependencies = [
3556 3556 "anyhow",
3557 3557 "argon2",
@@ -1,6 +1,6 @@
1 1 [package]
2 2 name = "makenotwork"
3 - version = "0.6.11"
3 + version = "0.6.14"
4 4 edition = "2024"
5 5 license-file = "LICENSE"
6 6
@@ -898,6 +898,11 @@ pub async fn batch_advance_onboarding_step(
898 898 /// window keep their founder status. After the window closes, eligibility
899 899 /// is determined by `founder_locked_at` (stamped only for users with an
900 900 /// active subscription at the close-time snapshot).
901 + ///
902 + /// **DIY exclusion**: DIY-tier accounts are not full members and must not
903 + /// qualify for founder pricing (`project_founder_pricing.md` § decision 5).
904 + /// Only call this from creator-tier (Basic/SmallFiles/BigFiles/Everything)
905 + /// checkout paths. When DIY ships, its checkout path must NOT invoke this.
901 906 #[tracing::instrument(skip_all)]
902 907 pub async fn mark_user_as_founder(pool: &PgPool, user_id: UserId) -> Result<()> {
903 908 sqlx::query(
@@ -5478,6 +5478,107 @@ textarea:focus-visible {
5478 5478 opacity: 1;
5479 5479 }
5480 5480
5481 + .founder-tagline {
5482 + font-family: var(--font-body);
5483 + font-size: 0.95rem;
5484 + line-height: 1.55;
5485 + margin: 1.25rem auto 0;
5486 + max-width: 560px;
5487 + color: var(--text);
5488 + }
5489 +
5490 + .founder-tagline-mark {
5491 + font-family: var(--font-mono);
5492 + font-size: 0.75rem;
5493 + font-weight: 600;
5494 + text-transform: uppercase;
5495 + letter-spacing: 0.08em;
5496 + color: var(--highlight);
5497 + padding: 0.15rem 0.5rem;
5498 + border: 1px solid var(--highlight);
5499 + border-radius: 3px;
5500 + margin-right: 0.4rem;
5501 + white-space: nowrap;
5502 + }
5503 +
5504 + .fork-card--founder {
5505 + border-color: var(--highlight);
5506 + box-shadow: 0 0 0 1px var(--highlight-faint);
5507 + }
5508 +
5509 + .founder-tier-grid {
5510 + display: grid;
5511 + grid-template-columns: 1fr 1fr;
5512 + gap: 0.4rem 0.75rem;
5513 + margin-bottom: 0.85rem;
5514 + padding-bottom: 0.85rem;
5515 + border-bottom: 1px dashed var(--border);
5516 + }
5517 +
5518 + .founder-tier {
5519 + display: flex;
5520 + flex-direction: column;
5521 + gap: 0.1rem;
5522 + }
5523 +
5524 + .founder-tier-name {
5525 + font-family: var(--font-mono);
5526 + font-size: 0.7rem;
5527 + font-weight: 600;
5528 + text-transform: uppercase;
5529 + letter-spacing: 0.05em;
5530 + opacity: 0.7;
5531 + }
5532 +
5533 + .founder-tier-price {
5534 + font-family: var(--font-heading);
5535 + font-size: 1rem;
5536 + line-height: 1.1;
5537 + }
5538 +
5539 + .founder-tier-price del {
5540 + opacity: 0.4;
5541 + margin-right: 0.25rem;
5542 + font-weight: 400;
5543 + }
5544 +
5545 + .founder-tier-price strong {
5546 + color: var(--highlight);
5547 + font-weight: 700;
5548 + }
5549 +
5550 + .founder-tier-unit {
5551 + font-family: var(--font-mono);
5552 + font-size: 0.75rem;
5553 + opacity: 0.6;
5554 + margin-left: 0.1rem;
5555 + }
5556 +
5557 + .founder-slots {
5558 + font-family: var(--font-mono);
5559 + font-size: 0.8rem;
5560 + margin: 0 0 1rem;
5561 + line-height: 1.3;
5562 + }
5563 +
5564 + .founder-slots-number {
5565 + font-family: var(--font-heading);
5566 + font-size: 1.4rem;
5567 + color: var(--highlight);
5568 + font-weight: 700;
5569 + margin-right: 0.25rem;
5570 + }
5571 +
5572 + .founder-slots-cap {
5573 + opacity: 0.55;
5574 + margin-left: 0.25rem;
5575 + }
5576 +
5577 + .founder-slots--cap {
5578 + opacity: 0.7;
5579 + font-size: 0.75rem;
5580 + }
5581 +
5481 5582 .landing-stats-line {
5482 5583 font-family: var(--font-mono);
5483 5584 font-size: 0.85rem;
@@ -22,36 +22,58 @@
22 22 <p class="landing-sub">Audio, video, software, writing, games, and more. 0% platform fee &mdash; just Stripe's ~3% processing.</p>
23 23
24 24 {% if founder_window_open %}
25 - <div class="alert alert-important">
26 - <p class="alert-title">Founder pricing &mdash; open now</p>
27 - <p>
28 - Join while the founder window is open and lock in <strong>half-price creator memberships for the life of your account</strong>.
29 - </p>
30 - <p class="text-sm dimmed">
31 - Window closes at 1,000 creators or when we exit beta, whichever first.
32 - {% if let Some(remaining) = founder_slots_remaining %}
33 - <strong>{{ remaining }} founder slot{% if *remaining != 1u32 %}s{% endif %} left.</strong>
34 - {% endif %}
35 - <a href="/docs/guide/tiers">See founder rates &rarr;</a>
36 - </p>
37 - </div>
25 + <p class="founder-tagline">
26 + <span class="founder-tagline-mark">Founder pricing open</span>
27 + &mdash; half off creator tiers, <strong>locked for life</strong>.
28 + </p>
38 29 {% endif %}
39 30
40 31 <div class="landing-fork">
41 - <div class="fork-card">
32 + <div class="fork-card{% if founder_window_open %} fork-card--founder{% endif %}">
42 33 <h2 class="fork-heading">For creators</h2>
34 +
35 + {% if founder_window_open %}
36 + <div class="founder-tier-grid" aria-label="Founder tier pricing">
37 + <div class="founder-tier">
38 + <span class="founder-tier-name">Basic</span>
39 + <span class="founder-tier-price"><del>$10</del> <strong>$5</strong><span class="founder-tier-unit">/mo</span></span>
40 + </div>
41 + <div class="founder-tier">
42 + <span class="founder-tier-name">Small Files</span>
43 + <span class="founder-tier-price"><del>$20</del> <strong>$10</strong><span class="founder-tier-unit">/mo</span></span>
44 + </div>
45 + <div class="founder-tier">
46 + <span class="founder-tier-name">Big Files</span>
47 + <span class="founder-tier-price"><del>$30</del> <strong>$15</strong><span class="founder-tier-unit">/mo</span></span>
48 + </div>
49 + <div class="founder-tier">
50 + <span class="founder-tier-name">Everything</span>
51 + <span class="founder-tier-price"><del>$60</del> <strong>$30</strong><span class="founder-tier-unit">/mo</span></span>
52 + </div>
53 + </div>
54 + {% if let Some(remaining) = founder_slots_remaining %}
55 + <p class="founder-slots">
56 + <span class="founder-slots-number">{{ remaining }}</span>
57 + founder slot{% if *remaining != 1u32 %}s{% endif %} left
58 + <span class="founder-slots-cap">of 1,000</span>
59 + </p>
60 + {% else %}
61 + <p class="founder-slots founder-slots--cap">
62 + Window closes at 1,000 creators or when we exit beta &mdash; whichever first.
63 + </p>
64 + {% endif %}
65 + {% endif %}
66 +
43 67 <ul class="fork-list">
44 - <li><strong>0% platform fee</strong> &mdash; only ~3% payment processing</li>
45 - {% if founder_window_open %}
46 - <li><strong>Founder pricing</strong> &mdash; from $5/mo, locked for life</li>
47 - {% else %}
68 + {% if !founder_window_open %}
48 69 <li><strong>Flat monthly pricing</strong> &mdash; starts at $10/mo</li>
49 70 {% endif %}
71 + <li><strong>0% platform fee</strong> &mdash; only ~3% payment processing</li>
50 72 <li><strong>Full data export</strong> &mdash; no lock-in, cancel anytime</li>
51 73 <li><strong>Source available</strong> &mdash; read the code, verify every claim</li>
52 74 </ul>
53 75 <div class="fork-actions">
54 - <a class="btn-primary btn--large" href="/join">Join as a creator</a>
76 + <a class="btn-primary btn--large" href="/join">{% if founder_window_open %}Claim founder pricing{% else %}Join as a creator{% endif %}</a>
55 77 <a class="fork-secondary-link" href="/sandbox">Try the dashboard first</a>
56 78 </div>
57 79 </div>