gauth-0001-plans-and-billing-v3 · frontend/src/pages/account/admin/billing
Version 5 · August 2026
| File | What it is |
|---|---|
Plans and Billing V4 - antd.dc.html | The reference design. 22 frames on a canvas: 7 plan pages + 15 modals, built from antd 5 primitives. Every frame carries an id (PAGE 2, MODAL A3), a description of its state, and a code chip naming the source file and the guard that drives it. Also carries a Component map legend at the top left. |
Plans and Billing - Live Prototype.dc.html | The interactive prototype. One screen with a control rail; plan, add-ons, Engagement Suite and over-quota are live state, and the flows are wired end to end. Use it to feel the transitions the static frames cannot show. |
RC_PLANS_ADDONS_SPEC.md | This document. |
github.md | Screen-to-source map against RandomCoffee/randomcoffee@master. |
Frame ids in §6 match the annotations in the V4 file. The prototype covers the same states through its control rail.
Two independent axes, plus one Enterprise-only supplement:
No plan bundles an add-on. A Pro+ or Enterprise customer still unlocks and pays for Mentoring separately. The design states this deliberately: PAGE 4 (Pro+) renders the Mentoring card unpurchased and payable, exactly as PAGE 2 (Pro) does.
Entitlement resolution: plan quotas ∪ add-on capabilities. Quotas are numeric and come only from the plan, or from Engagement Suite on Enterprise. Capabilities are boolean and come only from add-ons. An add-on must never raise a quota; a plan must never grant a program type.
| Free | Pro | Pro+ | Enterprise | |
|---|---|---|---|---|
| Access | Self-serve | Self-serve, card in app | Self-serve, card in app | Contract, via CSM |
| Price in app | $0 | $200/month for 50 users * | $280/month for 50 users * | Never — "Custom Pricing" |
| Coffee Connect programs | 1 | Unlimited | Unlimited | Unlimited |
| Members | up to 20 | Unlimited, tiered | Unlimited, tiered | Per contract |
| Admin licenses | 1 | 3 | 5 | Per contract |
| Audiences | 2 | 2 | Unlimited | 2, or unlimited with Engagement Suite |
| Surveys / Broadcasts / Notes | 2 each | 2 each | Unlimited | 2 each, or unlimited with Engagement Suite |
| Can buy add-ons | No | Yes | Yes | Via CSM only |
\* Placeholders. Pricing is per seat bracket, never "per user/month" — always render the bracket sentence: $200/month · for 50 users · billed annually.
Free and Pro differ only on members and admin licenses. Audiences, engagement caps, matching rules and integrations are identical. Any Free→Pro upsell must therefore claim only real deltas: unlimited Coffee Connect programs, unlimited members and flexible tiers, 3 admin seats instead of 1, customizable sending domains, HRIS integrations, priority support, access to paid add-ons.
Plan card contents (identical wherever the card appears):
Free — 1 Coffee Connect program · 2 Surveys · 2 Broadcasts · 2 Notes · Advanced matching rules · Customizable session schedule · Customizable communications · Slack & Microsoft Teams integrations · Google / Outlook calendar integrations
Pro — Unlimited Coffee Connect programs · Unlimited members · flexible tiers · 3 admin seats · 2 audiences · 2 Surveys · 2 Broadcasts · 2 Notes · Customizable sending domains · HRIS integrations · Priority support
Pro+ — everything in Pro, plus: Unlimited Surveys · Unlimited Broadcasts · Unlimited Notes · Unlimited audiences · 5 admin seats
Enterprise — SAML SSO · 2FA · SCIM & API provisioning · Team permissions · Service Level Agreement · Dedicated Account Manager & Support · Custom reports analysis · Security questionnaire review · Onboarding & training sessions
No plan card mentions add-on availability: add-ons are universally paid, so it differentiates nothing.
Tier icons. Each plan has an illustrated icon at 34px, placed before the plan name, in the plan card and in the current-plan block: Free = coffee beans, Pro = paper cup, Pro+ = coffee pot, Enterprise = espresso machine. They give the tier list a visible sense of progression. Assets: assets/plan-{free,pro,proplus,enterprise}.png.
Adds a second program type alongside Coffee Connect. Feature list, verbatim and identical everywhere it appears:
Price in the mockups: +$100/month for 50 users. The price is never shown on the add-on card — only inside the activation modal (MODAL B1), where the full breakdown makes it meaningful.
Not sellable. Renders with a purple Coming soon badge, no price, no Activate CTA and no explanatory alert — the badge carries it. Announced features: automated welcome journeys · milestone-based onboarding steps · new-joiner check-ins & nudges · onboarding progress analytics.
A supplement on the contract that lifts Surveys, Broadcasts, Notes and audiences to unlimited. It exists because existing Enterprise customers were never billed for those unlimited quotas, and being on Enterprise does not by itself grant them.
It is not an add-on card. It surfaces as a status on the limits block:
✓ Unlimited unlocked with Engagement Suite, and the four quotas read Unlimited.Alert type="info" compact at the top right of the limits block: thunderbolt icon, "Unlock unlimited Surveys, Broadcasts, Notes and audiences with Engagement Suite", and a primary Contact my CSM button. The four quotas read 1/2.Never appears on Free, Pro or Pro+.
Mandatory vocabulary
Writing rules
—) in product copy. Use a comma, a colon or a full stop.Locked add-ons stay visible with a neutral icon tile, a grey status badge naming what is required, and their full feature list. Clicking any locked element opens the matching gate modal.
No modal is a dead end. There is always a secondary action: Not now, Dismiss, or a constructive alternative such as Continue with Coffee Connect.
Hitting a cap blocks creation only. Existing items stay visible and functional. When a cap is introduced retroactively, items created before enforcement are grandfathered with a Legacy · kept badge and the counter reads 4 kept · limit is now 2. Enforcement compares creation date to the enforcement date, never the count.
MODAL B5) before any destructive confirmation.Contract customers may legitimately exceed quota. The over-quota treatment is amber, not red: warm border, amber counter, saturated gauge, a short overage note (142 over your contract) and a **secondary Contact my CSM button inside the affected card**. The action sits on the quota that is actually over, not in a page-level banner. Nothing is blocked, because an Enterprise customer over contract is a conversation with their CSM, not an error.
align-items:stretch, card height:100%).margin-top:auto), whatever it does, so buttons line up across a row.Shared structure: app chrome (top bar, Workspace settings menu with Billing selected) → breadcrumb → title → tabs Subscription / Billing / Invoices history → current-plan block → billing-cycle and currency Segmented → plan grid → Add-ons → Your current limits → Need help.
The Billing tab owns the payment card and invoices; they never appear on Subscription.
| Frame | State | Specifics |
|---|---|---|
PAGE 1 | Free | The Free card is hidden from the grid — you are already on it, so only Pro / Pro+ / Enterprise show, Pro flagged Recommended. Both add-ons locked with a grey Requires a paying plan badge and no disabled button; each carries a primary Upgrade to Pro at the bottom. |
PAGE 2 | Pro | Reference layout. Pro carries Current plan, its button is the disabled Current plan. Mentoring purchasable, Onboarding Coming soon. |
PAGE 3 | Pro + Mentoring | Mentoring card green Active, neutral Manage your add-on. Quotas unchanged: an add-on adds capability, not quota. |
PAGE 4 | Pro+ | Add-ons still unpurchased and payable. Limits: 5 admins, unlimited audiences / Surveys / Broadcasts / Notes. |
PAGE 5 | Enterprise, nothing extra purchased | The common existing-customer case. Plan grid collapses to a single Enterprise block merged with the CSM card; no tabs (showTabs false), no cycle or currency switcher, no invoice block, no price. Contract end date shown. Add-on CTA Contact my CSM to activate. Engagement Suite not purchased, so caps sit at Pro level. |
PAGE 6 | Enterprise + add-ons + Engagement Suite | Mentoring reads Active with no CSM button. Green Engagement Suite tag on the limits header explains why the four quotas read Unlimited. Usage within contract. |
PAGE 7 | Over-quota behaviour only | Same workspace as 6, purely to document the amber treatment on two exceeded quotas (Active users 3,142/3,000 and Admin licenses 12/10), each with its own Contact my CSM button. |
Current-plan block — tier icon, plan name, blue Current plan badge, price bracket, renewal or contract end date, and a neutral Manage plan button on the right (paying plans only). No "Subscription" eyebrow: the name and icon are enough.
Your current limits — two groups. Plan & seats: Active users (continuous gauge), Admin licenses (segmented gauge, one cell per licence), Audiences. Engagement features: Surveys, Broadcasts, Notes. Values must match §2 exactly for the plan shown; this was the most frequent inconsistency during design.
| Frame | Trigger | Rules |
|---|---|---|
MODAL A1 | Free user clicks any add-on CTA | Sells the plan. No add-on price. Only genuine Free→Pro deltas (§2). Primary Upgrade to Pro. |
MODAL A2 | Pro user creates a 3rd Survey / Broadcast / Note | Cap is 2, so the block fires on the third. Existing items untouched. Upsell is Pro+, not an add-on. Secondary Not now. |
MODAL A3 | Mentoring picked in the program-type selector without the add-on | Plan-agnostic wording. Lists the five Mentoring features and the bracket price. Secondary Continue with Coffee Connect. |
MODAL A4 | Same gates, Enterprise workspace | Replaces A1 and A3. No price, no pay button. CSM card with photo. Only exit Contact my CSM. |
MODAL A5 | Creation attempt after a retroactive cap | Grandfathering: Legacy · kept badges, counter 4 kept · limit is now 2, soft paywall on create. Background list must match the numbers in the copy. |
MODAL A6 | ~30 days before a cap takes effect | Three points: nothing is deleted, the new limit and its date, how to stay unlimited. Secondary defers without dismissing permanently. |
MODAL A7 | Any Upgrade to Pro+, or the upsell in A2 / A5 | Self-serve tier change. Lists the six unlocks, shows the price delta ($200 → +$80 → $280/mo) and the card on file, prorated. Footnote: Pro+ raises quotas, Mentoring stays separately payable. |
MODAL A8 | Unlock unlimited alert on Page 5, or a quota gate on Enterprise | The Enterprise counterpart of A7. A Today → With suite table shows the four caps going 2 → Unlimited, then the CSM card. No price, no pay button. Exit Contact my CSM. |
| Frame | Trigger | Rules |
|---|---|---|
MODAL B1 | Activate <add-on> on a self-serve plan | Full breakdown: current plan + add-on = new monthly total. Card on file, charged prorated. Collect a card first if none. |
MODAL B2 | Payment succeeded | Recap what was unlocked, then push to the first useful action (Create a Mentoring program), not back to billing. |
MODAL B3 | Manage plan | Positive actions as large rows: change plan, update seats, change billing cycle, update payment method. Cancel or downgrade demoted to a text link. |
MODAL B4 | Manage your add-on → deactivate | Lists what access is lost, then reassures: existing Mentoring programs are paused, not deleted; effective end of period; reactivate anytime. |
MODAL B5 | Cancel or downgrade | Retention step before any destructive confirmation. Three lighter options: switch to Free, pause 3 months, 20% off. Primary Keep my plan. |
MODAL B6 | Continue to cancel | Final confirmation. Exact end date, what is lost, 90-day retention window. Only red button in the product. Ok stays disabled until a reason is given. |
MODAL C1 | Next login of an admin without Mentoring | Launch announcement: video plus the five-item feature list. Maybe later dismisses without penalty. Shown once. |
Both design files are built on antd 5 with the theme already in the codebase — layouts/config.tsx:
<ConfigProvider
prefixCls="rc"
componentSize="large"
theme={{ cssVar: { prefix: 'rc' }, token: { colorPrimary: '#4451EA', borderRadius: 6, /* … */ } }}
>
Nothing in the design is bespoke UI: every element maps to an antd component, and the class names in the files are the ones antd emits, so a developer can read a frame and know the component.
| Component | Where it is used |
|---|---|
Card (+ size="small") | plan cards, add-on cards, limits, usage cards, CSM card |
Button (type="primary" / "default" / "link", danger, disabled, block) | every action; danger only on the final cancel and add-on deactivation |
Tag (color="purple" / "green" / "gold" / "blue") | status badges, Coming soon, Legacy · kept, Current plan |
Segmented | billing cycle (Monthly / Annually), currency (EUR / GBP / USD) |
Tabs | Subscription / Billing / Invoices history |
Alert (type="info" / "warning") | Engagement Suite offer, over-quota note, retention warnings |
Modal (width, okText, okButtonProps, destroyOnClose) | all 15 modals |
Typography (Title 3/4/5, Text secondary/tertiary/strong, Link, Paragraph) | all copy |
Divider, Row / Col, Space (incl. direction="vertical") | layout |
Menu, Breadcrumb, Avatar (+ Avatar.Group) | app chrome and the expert block |
plan-card.less classes | .planCard, .currentPlanCard, .planName, .planPrice — reused as authored in the repo |
Icons. @ant-design/icons, rendered as antd renders them: <span role="img" class="anticon anticon-check" data-icon="CheckOutlined">. 27 of the 29 glyphs are native antd components. **All feature-list checkmarks are CheckOutlined in --rc-color-primary**, uniformly.
Two glyphs are not in antd and come from Lucide (MIT): a graduation cap for Mentoring and a waving hand (tilted +18°) for Onboarding. Both must be added to components/icons/index.tsx, alongside the existing custom icons such as MagicWandIcon.
Add-on icon tiles are neutral — white fill, 1px --rc-color-border, glyph in --rc-color-text-secondary — with no per-add-on accent colour, so the two cards read as siblings rather than as competing brands.
| Token | Value | Use |
|---|---|---|
--rc-color-primary | #4451EA | primary buttons, links, current-plan border, all feature checkmarks, gauges |
--rc-color-primary-bg | #E2ECFF | selected rows, blue badges |
--rc-color-text / -secondary / -tertiary | rgba(6,10,11,.88 / .65 / .45) | titles / body / meta |
--rc-color-border / -secondary | #d9d9d9 / #f0f0f0 | controls / card borders, icon tiles |
--rc-color-bg-container / -layout | #ffffff / #fbfbfb | cards / page background |
--rc-color-success | #17b26a on #ecfdf3 | Active and Engagement Suite badges |
--rc-color-warning | #f79009 on #fffbe6 | over-quota treatment, grandfathering tags |
--rc-color-error | #f04438 | lost-feature crosses, the single final-cancel button |
--rc-color-purple | #722ed1 on #f9f0ff | **reserved for Coming soon** and the repo's Upgrade tag |
--rc-color-orange | #d46b08 on #fff7e6 | antd orange-7/1/3; the Just launched tag |
Radius 6px controls, 8px cards, 4px tags. Type: Roobert. No gradients in functional UI.
Pro+ needs a fourth tier. classes/plans.tsx models three plan types (0 Free, 1 Pro, 2 Enterprise). Plan.type and getAllFeatures() must gain Pro+ between Pro and Enterprise. PAGE 4 and MODAL A7 depend on it.
Engagement Suite needs a contract flag. A boolean on the Enterprise subscription that switches the four quotas to unlimited and drives the limits-header status. It must not exist on self-serve plans.
Grandfathering. Enforcement compares creation date to the enforcement date, not the count. Items created before remain editable and sendable forever; the counter reports them separately.
Deactivation. End of billing period. Mentoring programs move to paused; over-quota engagement items become read-only. Reactivation restores everything with no migration.
Cancellation. 90-day retention window before deletion. The UI promises it, so the backend must honour it.
Enterprise. Never expose self-serve purchase endpoints. Every add-on and quota action routes to the CSM contact channel (billing/sendEnterpriseNote).
MODAL B5 is granted automatically or needs approval.PAGE 6 that the unlimited tier was paid for, beyond the limits-header tag.