- Shipped
- August 31, 2026 at 2:14 AM UTC
- Author
- Kamo
- Commit
- b8b7d12
New prices: Starter $59/$49/$39 and Business $119/$109/$99 per seat per month on monthly, yearly and three-year terms. The rail replaces the monthly/annual pair and its "Save 18%" pill — a percentage was the wrong unit for a flat $10/$20 per seat, so the pill quoted whichever plan `find` happened to return first, and a toggle cannot express three options anyway. Its thumb is a padlock that closes as the term lengthens, which is the caption above it ("Lock in your rate today!") made literal. The offer band states the running promotion once, above the cards, and says it is applied automatically. That is true rather than decorative: the plan CTAs now carry ?code=, which RegisterFlow already reads into sp_checkout_code, and only on plans the offer actually covers — sending AUTUMN into checkout from the Free or Enterprise card would promise a discount the server then decoders. Starter and Business cards show Was / Now / what you save, and the promotion comes off the TERM rate, not the list price — commit first, then take the percentage off the already-reduced number, matching **************** Four surfaces were each doing this arithmetic themselves and disagreeing, so it moves into app/lib/plan-pricing.ts and they all read the same answer. The calculator's percentage promo was charging against add-ons, mailboxes, extensions and storage as well as seats, so its estimate came out below what the server bills; it is now scoped to the plan seats like the server's. /pricing/offer is rebuilt around whatever promotion the catalog carries. It had "18DOFF / $18 off Business" hardcoded in the client AND in its page fallback AND across nine dictionary strings, and the catalog had moved past all three. Also: package-lock.json was out of sync with package.json (@swc/helpers missing), so `npm ci` — which is what the Dockerfile runs — failed at main. The image build was broken independently of this work.