diff --git a/app/components/TierPicker.vue b/app/components/TierPicker.vue
index bf32c9d..5cf6318 100644
--- a/app/components/TierPicker.vue
+++ b/app/components/TierPicker.vue
@@ -8,6 +8,7 @@
@click="$emit('update:modelValue', tier.amount)"
>
{{ tier.display }}
+ {{ tier.subtitle }}
@@ -78,6 +79,15 @@ defineEmits(["update:modelValue"]);
color: var(--candle);
}
+.tier-subtitle {
+ display: block;
+ margin-top: 4px;
+ font-size: 11px;
+ color: var(--text-dim);
+ font-family: "Commit Mono", monospace;
+ letter-spacing: 0.02em;
+}
+
@media (max-width: 768px) {
.tier-picker {
flex-wrap: wrap;
diff --git a/app/pages/join.vue b/app/pages/join.vue
index 67d919b..329bbc5 100644
--- a/app/pages/join.vue
+++ b/app/pages/join.vue
@@ -467,14 +467,19 @@ const paymentToken = ref(null);
const circleOptions = getCircleOptions();
// Minimal labels for the dropdown — reactive to cadence.
+// In annual mode, show both monthly and annual price so $50/yr (the $5 tier annual)
+// is visually distinct from $500/yr (the $50 tier annual).
const contributionItems = computed(() => {
return Object.values(CONTRIBUTION_TIERS).map((tier) => {
const base = tier.amount;
if (base === 0) return { value: tier.value, label: "$0" };
- const amt = getTierAmount(tier, cadence.value);
- const suffix = cadence.value === "annual" ? "/yr" : "/mo";
- const hint = tier.value === "15" && cadence.value !== "annual" ? " (suggested)" : "";
- return { value: tier.value, label: `$${amt}${suffix}${hint}` };
+ const monthlyLabel = `$${base}/mo`;
+ const priceLabel =
+ cadence.value === "annual"
+ ? `${monthlyLabel} → $${getTierAmount(tier, "annual")}/yr`
+ : monthlyLabel;
+ const hint = tier.value === "15" ? " (suggested)" : "";
+ return { value: tier.value, label: `${priceLabel}${hint}` };
});
});
diff --git a/app/pages/member/account.vue b/app/pages/member/account.vue
index 0fd4c50..d16ddab 100644
--- a/app/pages/member/account.vue
+++ b/app/pages/member/account.vue
@@ -239,10 +239,15 @@ const BASE_TIERS = [
const tiers = computed(() => {
const cadence = memberData.value?.billingCadence || 'monthly';
- return BASE_TIERS.map((t) => ({
- ...t,
- display: t.amount === 0 ? '$0' : `$${getTierAmount(t, cadence)}`,
- }));
+ return BASE_TIERS.map((t) => {
+ if (t.amount === 0) return { ...t, display: '$0' };
+ const suffix = cadence === 'annual' ? '/yr' : '/mo';
+ return {
+ ...t,
+ display: `$${getTierAmount(t, cadence)}${suffix}`,
+ subtitle: cadence === 'annual' ? `$${t.amount}/mo tier` : null,
+ };
+ });
});
const currentContributionLabel = computed(() => {