Skip to content

Commit d73ac72

Browse files
anuveyatsuclaude
andcommitted
feat(pricing): redesign — Government tier, TCO section, Arc/Cloud strip (po-xv5)
- 5-tier grid: add Government ($1,499/mo annual-only, public-sector badge), data-driven price/CTA rendering replaces index-based branching - Remove all 'coming soon' bullets; Institution links to VISION.md roadmap - Foundation: drop custom domain (moved to Institution), add subdomain bullet, single 'Explore add-ons' link; Arc-first rebadge (Managed CKAN incl. Institution+) - New ProductLines strip: PortalJS / Arc / Cloud disambiguation above tiers - New TcoComparison section: anonymized competitor rows + sourced footnote - AddOns: Data API 'Included in Institution+' chip, new Research Pack card - FAQ: 4 pricing Q&As (sustainability, price, migration, RFPs) + roadmap link - SEO: Arc-first meta; footer drops Cloud-as-product framing - PostHog events: pricing_tier_cta_click, pricing_toggle_annual, pricing_tco_table_view, pricing_addon_click Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent 69e88f1 commit d73ac72

6 files changed

Lines changed: 586 additions & 309 deletions

File tree

site/components/AddOns.tsx

Lines changed: 49 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
import {
22
ChatBubbleBottomCenterIcon,
33
CloudIcon,
4-
UserIcon,
54
ArrowPathIcon,
65
CodeBracketSquareIcon,
76
PresentationChartBarIcon,
7+
AcademicCapIcon,
88
} from '@heroicons/react/24/solid'
99
import { FaInfoCircle } from 'react-icons/fa'
10+
import posthog from 'posthog-js'
1011

1112
const addOns = [
1213
{
@@ -18,6 +19,8 @@ const addOns = [
1819
icon: CloudIcon,
1920
iconForeground: 'text-blue-500',
2021
iconBackground: 'bg-blue-50 dark:bg-blue-900/20',
22+
// Included from Institution up; remains a paid add-on for Foundation only (po-xv5 §4).
23+
chip: 'Included in Institution and above',
2124
useCase:
2225
'Example use case: A government agency allows developers to build apps using open data.',
2326
},
@@ -56,37 +59,67 @@ const addOns = [
5659
useCase:
5760
'Example use case: A research organization gathers and updates datasets from multiple open data portals.',
5861
},
62+
{
63+
title: 'Research Pack',
64+
subtitle: 'Make your datasets citable and FAIR.',
65+
description:
66+
'DOI/DataCite minting, ORCID integration, citation metadata, and data-access requests — everything a research institution needs to publish citable, FAIR datasets.',
67+
href: 'https://calendar.app.google/sn2PU7ZvzjCPo1ok6',
68+
icon: AcademicCapIcon,
69+
iconForeground: 'text-rose-500',
70+
iconBackground: 'bg-rose-50 dark:bg-rose-900/20',
71+
useCase:
72+
'Example use case: A university mints DOIs for its research datasets so they can be cited in publications.',
73+
},
5974
{
6075
title: 'Request Your Own Add-on',
6176
subtitle: 'Get exactly what your project requires.',
62-
description:
63-
<p>Need a specific feature or tailored support? <a className='underline' href='https://calendar.app.google/sn2PU7ZvzjCPo1ok6' target='_blank'>Schedule a quick call with us</a> to describe your requirements.</p>,
77+
description: (
78+
<p>
79+
Need a specific feature or tailored support?{' '}
80+
<a
81+
className="underline"
82+
href="https://calendar.app.google/sn2PU7ZvzjCPo1ok6"
83+
target="_blank"
84+
rel="noopener noreferrer"
85+
>
86+
Schedule a quick call with us
87+
</a>{' '}
88+
to describe your requirements.
89+
</p>
90+
),
6491
href: 'https://calendar.app.google/sn2PU7ZvzjCPo1ok6',
6592
icon: ChatBubbleBottomCenterIcon,
6693
iconForeground: 'text-sky-500',
6794
iconBackground: 'bg-sky-50 dark:bg-sky-900/20',
68-
style: 'col-span-2',
6995
},
7096
]
7197

7298
function classNames(...classes) {
7399
return classes.filter(Boolean).join(' ')
74100
}
75101

76-
export default function Example() {
102+
function trackAddonClick(title: string) {
103+
try {
104+
posthog.capture('pricing_addon_click', { addon: title })
105+
} catch (_) {
106+
/* never let analytics break the page */
107+
}
108+
}
109+
110+
export default function AddOns() {
77111
return (
78112
<div className="divide-y divide-gray-200 rounded-lg bg-gray-200 dark:bg-slate-800 shadow sm:grid sm:grid-cols-2 sm:gap-px sm:divide-y-0 shadow-lg mb-8 mx-1 dark:mx-0">
79113
{addOns.map((addOn, actionIdx) => (
80114
<div
81115
key={addOn.title}
116+
onClick={() => trackAddonClick(addOn.title)}
82117
className={classNames(
83-
actionIdx === 0
84-
? 'rounded-tl-lg rounded-tr-lg sm:rounded-tr-none'
85-
: '',
118+
actionIdx === 0 ? 'rounded-tl-lg rounded-tr-lg sm:rounded-tr-none' : '',
86119
actionIdx === 1 ? 'sm:rounded-tr-lg' : '',
87-
actionIdx === addOns.length - 2 ? '' : '',
120+
actionIdx === addOns.length - 2 ? 'sm:rounded-bl-lg' : '',
88121
actionIdx === addOns.length - 1
89-
? '!rounded-bl-lg !rounded-br-lg sm:rounded-bl-none col-span-2'
122+
? '!rounded-bl-lg !rounded-br-lg sm:!rounded-bl-none sm:!rounded-br-lg'
90123
: '',
91124
'relative bg-[#f5f5f5] hover:bg-slate-100 dark:bg-slate-900 dark:hover:bg-slate-800 p-6 focus-within:ring-2 focus-within:ring-inset focus-within:ring-indigo-500'
92125
)}
@@ -105,12 +138,17 @@ export default function Example() {
105138
</div>
106139
</div>
107140
<div className="mt-8 z-50">
108-
<div className="flex items-center gap-2">
141+
<div className="flex items-center gap-2 flex-wrap">
109142
<h3 className="text-base font-semibold leading-6 hover:underline">
110143
<div title={addOn.title} className="focus:outline-hidden">
111144
{addOn.title}
112145
</div>
113146
</h3>
147+
{addOn.chip && (
148+
<span className="bg-blue-50 dark:bg-blue-900/30 text-blue-600 dark:text-blue-400 px-2 py-0.5 text-[11px] font-semibold rounded-full">
149+
{addOn.chip}
150+
</span>
151+
)}
114152
{addOn.useCase && (
115153
<div className="relative group">
116154
<FaInfoCircle className="text-gray-500 hover:text-blue-500 transition-colors duration-300 cursor-pointer" />

0 commit comments

Comments
 (0)