diff --git a/PlotLine/Views/Pricing/Index.cshtml b/PlotLine/Views/Pricing/Index.cshtml index 73f88c5..bba29b5 100644 --- a/PlotLine/Views/Pricing/Index.cshtml +++ b/PlotLine/Views/Pricing/Index.cshtml @@ -1,4 +1,5 @@ @model PricingViewModel +@using Microsoft.AspNetCore.Html @{ ViewData["Title"] = "Pricing"; ViewData["ShellClass"] = "marketing-shell"; @@ -60,11 +61,11 @@
@if (plan.RequiresStripeSubscription) { - @FormatMoney(plan.MonthlyPricePence, plan.CurrencyCode) + @PriceMarkup(plan.MonthlyPricePence, plan.CurrencyCode) per month @if (plan.AnnualPricePence.HasValue) { - @FormatMoney(plan.AnnualPricePence, plan.CurrencyCode) billed annually + @FormatAnnualPrice(plan.AnnualPricePence, plan.CurrencyCode) billed annually } } else @@ -192,16 +193,28 @@ ? "Unlimited" : StorageUsage.FormatBytes(megabytes * 1024L * 1024L); - private static string FormatMoney(int? pence, string? currencyCode) + private static IHtmlContent PriceMarkup(int? pence, string? currencyCode) + { + if (!pence.HasValue) + { + return new HtmlString("Contact us"); + } + + var code = string.IsNullOrWhiteSpace(currencyCode) ? "GBP" : currencyCode.ToUpperInvariant(); + var symbol = string.Equals(code, "GBP", StringComparison.OrdinalIgnoreCase) ? "£" : string.Empty; + return new HtmlString($"{symbol}{pence.Value / 100m:0.00} {code}"); + } + + private static string FormatAnnualPrice(int? pence, string? currencyCode) { if (!pence.HasValue) { return "Contact us"; } - return string.Equals(currencyCode, "GBP", StringComparison.OrdinalIgnoreCase) - ? $"GBP {pence.Value / 100m:0.00}" - : $"{pence.Value / 100m:0.00} {(string.IsNullOrWhiteSpace(currencyCode) ? "GBP" : currencyCode.ToUpperInvariant())}"; + var code = string.IsNullOrWhiteSpace(currencyCode) ? "GBP" : currencyCode.ToUpperInvariant(); + var symbol = string.Equals(code, "GBP", StringComparison.OrdinalIgnoreCase) ? "£" : string.Empty; + return $"{symbol}{pence.Value / 100m:0.00}"; } private static string PlanTagline(SubscriptionLevel plan) => diff --git a/PlotLine/wwwroot/css/plotline-theme.css b/PlotLine/wwwroot/css/plotline-theme.css index ab6b13d..41f6ee3 100644 --- a/PlotLine/wwwroot/css/plotline-theme.css +++ b/PlotLine/wwwroot/css/plotline-theme.css @@ -2913,7 +2913,7 @@ a:focus-visible { } .pricing-hero { - padding: clamp(4rem, 8vw, 7rem) 0 clamp(2.5rem, 6vw, 4.5rem); + padding: clamp(2rem, 5vw, 3.75rem) 0 clamp(2.5rem, 6vw, 4.5rem); background: radial-gradient(circle at 18% 20%, rgba(212, 165, 116, 0.2), transparent 24rem), linear-gradient(180deg, var(--marketing-cream), var(--marketing-offwhite)); @@ -3003,12 +3003,21 @@ a:focus-visible { box-shadow: 0 18px 42px rgba(31, 42, 68, 0.08); } +.pricing-card::before { + content: ""; + display: block; + height: 1.9rem; +} + .pricing-card--featured { border-color: rgba(212, 165, 116, 0.7); box-shadow: 0 26px 58px rgba(31, 42, 68, 0.13); } .pricing-badge { + position: absolute; + top: clamp(1.2rem, 2.4vw, 1.65rem); + right: clamp(1.2rem, 2.4vw, 1.65rem); width: fit-content; margin: 0; border: 1px solid rgba(212, 165, 116, 0.55); @@ -3025,6 +3034,8 @@ a:focus-visible { .pricing-card__heading { display: grid; gap: 0.5rem; + min-height: 6.85rem; + align-content: start; } .pricing-card h3, @@ -3052,10 +3063,15 @@ a:focus-visible { } .pricing-price strong { + display: inline-flex; + gap: 0.35rem; + align-items: baseline; + width: fit-content; color: var(--marketing-navy); font-family: Georgia, "Times New Roman", serif; font-size: clamp(2.15rem, 4vw, 3rem); line-height: 1; + white-space: nowrap; } .pricing-price span, @@ -3068,6 +3084,24 @@ a:focus-visible { font-size: 0.88rem; } +.pricing-price strong small { + color: var(--marketing-muted); + font-family: "Segoe UI", "Aptos", system-ui, -apple-system, BlinkMacSystemFont, sans-serif; + font-size: 0.88rem; + font-weight: 800; + line-height: 1; + white-space: nowrap; +} + +.pricing-price .pricing-price__value { + color: var(--marketing-navy); + white-space: nowrap; +} + +.pricing-price > small { + white-space: nowrap; +} + .pricing-feature-list { display: grid; gap: 0.65rem; @@ -3312,7 +3346,7 @@ a:focus-visible { } .pricing-hero { - padding-top: 3rem; + padding-top: 1.8rem; } .pricing-card-grid {