Skip to main content

max / makenotwork

10.5 KB · 163 lines History Blame Raw
1 {% extends "base.html" %}
2
3 {% block title %}Pricing Calculator - Makenotwork{% endblock %}
4
5 {% block body_attrs %} class="{{ crate::shell::measure(crate::shell::Measure::Contained) }}"{% endblock %}
6
7 {% block content %}
8 <div class="landing-hero pricing-page">
9 <h1 class="page-title">Pricing Calculator<span class="dot">.</span></h1>
10 <p class="tagline">See what you keep on every sale<span class="dot">.</span></p>
11
12 {# The calculator recomputes server-side: on any dial change HTMX GETs
13 /pricing/compare and swaps #results-panel. No fee math runs in the
14 browser. It all lives in `fee_calculator.rs`, sourced from
15 `assumptions.toml`. The dials sit outside the swap target so focus
16 and the typed value survive each recompute.
17
18 The right-hand column is the visitor's own description of wherever
19 else they sell. We do not name it, hold a table of rates for it, or
20 pretend to know what it charges. #}
21 <div id="pricing-calculator"
22 hx-get="/pricing/compare"
23 hx-trigger="input changed delay:300ms from:#item_price,
24 input changed delay:300ms from:#sales,
25 input changed delay:300ms from:#other_pct,
26 input changed delay:300ms from:#other_per_sale,
27 change from:input[name='tier']"
28 hx-include="#item_price, #sales, #other_pct, #other_per_sale, input[name='tier']:checked"
29 hx-target="#results-panel"
30 hx-swap="innerHTML">
31
32 <div class="tier-section">
33 <h2 class="section-label">What you sell</h2>
34 <div class="calc-dials">
35 <label class="calc-dial">
36 <span class="calc-dial-label">Price per item</span>
37 <span class="pricing-input-wrap">
38 <span class="pricing-currency">$</span>
39 <input type="number" id="item_price" name="item_price" class="pricing-input"
40 value="{{ inputs.item_price }}" min="0" max="10000" step="1"
41 aria-label="Price per item in dollars">
42 </span>
43 </label>
44 <label class="calc-dial">
45 <span class="calc-dial-label">Sales per month</span>
46 <span class="pricing-input-wrap">
47 <input type="number" id="sales" name="sales" class="pricing-input"
48 value="{{ inputs.sales_per_month }}" min="0" max="100000" step="1"
49 aria-label="Sales per month">
50 <span class="pricing-period">/mo</span>
51 </span>
52 </label>
53 </div>
54 </div>
55
56 {# Founder disclosure. Same wording as the landing tagline
57 (index.html), because it is the same offer and a second phrasing
58 for it would read as a second offer. Both this and the toggle
59 below are gated: with the window shut the page is what it was
60 before either existed. #}
61 {% if founder_window_open %}
62 <p class="founder-tagline">
63 <span class="founder-tagline-mark">Founder pricing open</span>
64 <span class="founder-tagline-detail">Half off creator tiers, <strong>locked for life</strong>. The calculator is using founder prices.</span>
65 </p>
66 {% endif %}
67
68 <div class="tier-section">
69 <h2 class="section-label">Your content tier</h2>
70 <p class="tier-intro">Every tier is the complete platform: profile, project pages, forum, discovery, memberships, analytics, full data export. The tier picks the file-size envelope, not the feature set.</p>
71
72 {# The radio `value` is what hx-include sends, so it is the price
73 the server computes on. While the window is open it opens on
74 the founder price: a visitor who can buy at half price should
75 not be shown their outcome at a price they will not pay.
76 <mnw-price-mode> swaps between the two data-price-* values in
77 the DOM and re-fires the existing recompute. Without JS the
78 toggle is absent and the founder price stands, which is the
79 right default rather than a broken one. #}
80 <mnw-price-mode>
81 {% if founder_window_open %}
82 <div class="price-mode" role="radiogroup" aria-label="Calculate with">
83 <label class="price-mode-option">
84 <input type="radio" name="price-mode" value="founder" checked>
85 <span>Founder price</span>
86 </label>
87 <label class="price-mode-option">
88 <input type="radio" name="price-mode" value="list">
89 <span>List price</span>
90 </label>
91 </div>
92 {% endif %}
93
94 <div class="tier-selector" role="radiogroup" aria-label="Content tier">
95 <label class="card--bordered tier-card tier-option">
96 <input type="radio" name="tier" value="{% if founder_window_open %}{{ tier_prices.basic_founder }}{% else %}{{ tier_prices.basic_std }}{% endif %}" data-price-std="{{ tier_prices.basic_std }}" data-price-founder="{{ tier_prices.basic_founder }}" checked>
97 <div class="tier-name">Basic</div>
98 <div class="tier-price" data-price-display>${% if founder_window_open %}{{ tier_prices.basic_founder }}{% else %}{{ tier_prices.basic_std }}{% endif %}/mo</div>
99 <div class="tier-desc">{{ tier_prices.basic_per_file }}/file, {{ tier_prices.basic_total }} total. Fits text, blogs, newsletters.</div>
100 </label>
101 <label class="card--bordered tier-card tier-option">
102 <input type="radio" name="tier" value="{% if founder_window_open %}{{ tier_prices.small_files_founder }}{% else %}{{ tier_prices.small_files_std }}{% endif %}" data-price-std="{{ tier_prices.small_files_std }}" data-price-founder="{{ tier_prices.small_files_founder }}">
103 <div class="tier-name">Small Files</div>
104 <div class="tier-price" data-price-display>${% if founder_window_open %}{{ tier_prices.small_files_founder }}{% else %}{{ tier_prices.small_files_std }}{% endif %}/mo</div>
105 <div class="tier-desc">{{ tier_prices.small_files_per_file }}/file, {{ tier_prices.small_files_total }} total. Fits audio, plugins, binaries.</div>
106 </label>
107 <label class="card--bordered tier-card tier-option">
108 <input type="radio" name="tier" value="{% if founder_window_open %}{{ tier_prices.big_files_founder }}{% else %}{{ tier_prices.big_files_std }}{% endif %}" data-price-std="{{ tier_prices.big_files_std }}" data-price-founder="{{ tier_prices.big_files_founder }}">
109 <div class="tier-name">Big Files</div>
110 <div class="tier-price" data-price-display>${% if founder_window_open %}{{ tier_prices.big_files_founder }}{% else %}{{ tier_prices.big_files_std }}{% endif %}/mo</div>
111 <div class="tier-desc">{{ tier_prices.big_files_per_file }}/file, {{ tier_prices.big_files_total }} total. Fits video, games, large software.</div>
112 </label>
113 <label class="card--bordered tier-card tier-option">
114 <input type="radio" name="tier" value="{% if founder_window_open %}{{ tier_prices.everything_founder }}{% else %}{{ tier_prices.everything_std }}{% endif %}" data-price-std="{{ tier_prices.everything_std }}" data-price-founder="{{ tier_prices.everything_founder }}">
115 <div class="tier-name">Everything</div>
116 <div class="tier-price" data-price-display>${% if founder_window_open %}{{ tier_prices.everything_founder }}{% else %}{{ tier_prices.everything_std }}{% endif %}/mo</div>
117 <div class="tier-desc">Big Files envelope plus first access to high-cost features as they ship.</div>
118 </label>
119 </div>
120 </mnw-price-mode>
121 </div>
122
123 <div class="tier-section">
124 <h2 class="section-label">Wherever else you sell</h2>
125 <p class="tier-intro">Fill in what the other platform takes. Use its total deduction, its own cut plus any payment processing it adds, which is the figure you can read off a payout. We hold no rates for anyone but ourselves, so nothing here can go stale or be picked to flatter us.</p>
126 <div class="calc-dials">
127 <label class="calc-dial">
128 <span class="calc-dial-label">Their cut</span>
129 <span class="pricing-input-wrap">
130 <input type="number" id="other_pct" name="other_pct" class="pricing-input"
131 value="{{ other_pct_display }}" min="0" max="90" step="0.1"
132 aria-label="Other platform percentage cut">
133 <span class="pricing-period">%</span>
134 </span>
135 </label>
136 <label class="calc-dial">
137 <span class="calc-dial-label">Their fee per sale</span>
138 <span class="pricing-input-wrap">
139 <span class="pricing-currency">$</span>
140 <input type="number" id="other_per_sale" name="other_per_sale" class="pricing-input"
141 value="{{ other_per_sale_display }}" min="0" max="100" step="0.05"
142 aria-label="Other platform flat fee per sale in dollars">
143 </span>
144 </label>
145 </div>
146 </div>
147
148 <div id="results-panel">
149 {% include "partials/fee_calculator.html" %}
150 </div>
151 </div>
152
153 <div class="landing-cta">
154 <a class="btn-primary btn--large" href="/join">Join the Alpha</a>
155 </div>
156
157 <div class="secondary-links">
158 <a href="/">Home</a>
159 <a href="/discover">Browse as guest</a>
160 </div>
161 </div>
162 {% endblock %}
163