1+ < div class ="bg-gray-100 overflow-x-hidden " id ="pricing ">
2+ < div class ="pt-12 sm:pt-16 lg:pt-20 ">
3+ < div class ="px-4 mx-auto max-w-screen-xl sm:px-6 lg:px-8 ">
4+ < div class ="text-center ">
5+ < h2
6+ class ="text-3xl font-extrabold text-gray-900 leading-9 sm:text-4xl sm:leading-10 lg:text-5xl lg:leading-none ">
7+ Traffic based plans that match your growth
8+ </ h2 >
9+ < p class ="mt-4 text-xl text-gray-600 leading-7 ">
10+ Sign up for 30-day free trial. No credit card required.
11+ </ p >
12+ </ div >
13+ </ div >
14+ </ div >
15+
16+ < script >
17+ const volumesWithPrices = [
18+ { volume : "10k" , starter : 9 , growth : 14 , business : 19 } ,
19+ { volume : "100k" , starter : 19 , growth : 29 , business : 39 } ,
20+ { volume : "200k" , starter : 29 , growth : 44 , business : 59 } ,
21+ { volume : "500k" , starter : 49 , growth : 74 , business : 99 } ,
22+ { volume : "1M" , starter : 69 , growth : 104 , business : 139 } ,
23+ { volume : "2M" , starter : 89 , growth : 134 , business : 179 } ,
24+ { volume : "5M" , starter : 129 , growth : 194 , business : 259 } ,
25+ { volume : "10M" , starter : 169 , growth : 254 , business : 339 } ,
26+ ]
27+
28+ function volume ( index ) {
29+ index = parseInt ( index )
30+ if ( index === volumesWithPrices . length ) {
31+ return "10M+"
32+ } else {
33+ return volumesWithPrices [ index ] . volume
34+ }
35+ }
36+
37+ function price ( currency , index , tier , billingInterval , withDiscount = false ) {
38+ index = parseInt ( index )
39+ if ( index === volumesWithPrices . length ) {
40+ return "Custom"
41+ }
42+
43+ let price
44+
45+ if ( billingInterval === 'yearly' ) {
46+ price = volumesWithPrices [ index ] [ tier ] * 10
47+ } else if ( billingInterval === 'monthly' && withDiscount ) {
48+ price = ( volumesWithPrices [ index ] [ tier ] * 10 / 12 ) . toFixed ( 2 )
49+ } else {
50+ price = volumesWithPrices [ index ] [ tier ]
51+ }
52+
53+ return currency + price . toLocaleString ( "en-US" )
54+ }
55+
56+ function calculateBubblePosition ( volumeIndex ) {
57+ const range = document . getElementById ( "volume" )
58+ const newVal = Number ( ( volumeIndex / range . max ) * 100 )
59+ return `left: calc(${ newVal } % + (${ 13.87 - newVal * 0.26 } px))`
60+ }
61+ </ script >
62+ < div class ="mx-auto max-w-screen-xl mt-12 p-4 " x-data ="{yearlyBilling: false, volumeIndex: 0, currency: '$'} "
63+ x-init ="fetch('/api/paddle/currency').then(response => response.json()).then(data => currency = data.currency) ">
64+ < div class ="flex flex-col gap-4 lg:flex-row lg:gap-8 items-center lg:items-baseline ">
65+ < div class ="lg:flex-1 lg:order-3 lg:justify-end flex ">
66+ < div class ="relative ">
67+ < span
68+ class ="absolute whitespace-no-wrap w-max px-2.5 py-0.5 rounded-full text-xs font-medium leading-4 bg-yellow-100 border border-yellow-300 text-yellow-700 "
69+ style ="right: -20px; top: -15px; ">
70+ 2 months free
71+ </ span >
72+ < div
73+ class ="grid grid-cols-2 gap-x-1 rounded-full bg-white p-1 text-center text-sm font-semibold leading-5 border border-gray-200 ">
74+ < label class ="cursor-pointer rounded-full px-2.5 py-1 transition-colors ease-in-out duration-200 "
75+ :class ="yearlyBilling ? 'text-gray-900 bg-white' : 'text-white bg-indigo-600' "
76+ @click ="yearlyBilling = false ">
77+ < input type ="radio " name ="frequency " value ="monthly " class ="sr-only " />
78+ < span > Monthly</ span >
79+ </ label >
80+ < label class ="cursor-pointer rounded-full px-2.5 py-1 transition-colors ease-in-out duration-200 "
81+ :class ="yearlyBilling ? 'text-white bg-indigo-600' : 'text-gray-900 bg-white' "
82+ @click ="yearlyBilling = true ">
83+ < input type ="radio " name ="frequency " value ="yearly " class ="sr-only " />
84+ < span > Yearly</ span >
85+ </ label >
86+ </ div >
87+ </ div >
88+ </ div >
89+ < p class ="lg:w-1/4 lg:order-1 font-medium text-gray-600 ">
90+ < span x-show ="volumeIndex < volumesWithPrices.length "> Up to</ span >
91+ < b class ="text-gray-900 " x-text ="volume(volumeIndex) "> 10k</ b >
92+ < span > monthly pageviews</ span >
93+ </ p >
94+ < div class ="max-w-md lg:max-w-none w-full mt-6 lg:w-1/2 lg:order-2 flex items-baseline space-x-2 ">
95+ < span class ="text-xs font-medium text-gray-600 "> 10k</ span >
96+ < div class ="flex-1 relative ">
97+ < input id ="volume " class ="shadow w-full " type ="range " min ="0 " max ="8 " step ="1 " value ="0 "
98+ x-model ="volumeIndex " />
99+ < output class ="bubble text-xs font-medium " style ="left: 13.87px; " x-text ="volume(volumeIndex) "
100+ x-bind:style ="`${calculateBubblePosition(volumeIndex)}` ">
101+ 10k
102+ </ output >
103+ </ div >
104+ < span class ="text-xs font-medium text-gray-600 "> 10M+</ span >
105+ </ div >
106+ </ div >
107+ < div class ="mt-6 overflow isolate mx-auto grid max-w-md grid-cols-1 gap-4 lg:mx-0 lg:max-w-none lg:grid-cols-4 ">
108+ {% for plan in site.data.plans %}
109+ < div
110+ class ="rounded-xl px-4 py-4 shadow-md {{ plan.style.main | default: 'bg-white text-gray-900 border border-gray-200' }} ">
111+ < h3 class ="text-lg font-semibold leading-8 "> {{ plan.title }}</ h3 >
112+ < div class ="h-20 max-h-20 pt-4 ">
113+ {% if plan.tier == "enterprise" %}
114+ < div class ="text-3xl font-bold tracking-tight leading-8 "> Custom</ div >
115+ {% else %}
116+ < div x-cloak x-show ="yearlyBilling && volumeIndex < volumesWithPrices.length " class ="flex ">
117+ < div class ="flex flex-col ">
118+ < span class ="h-8 leading-8 text-3xl font-bold tracking-tight "
119+ x-text ="price(currency, volumeIndex, '{{ plan.tier }}', 'yearly') ">
120+ </ span >
121+ < span class ="h-6 leading-6 font-bold tracking-tight text-sm ">
122+ < span class ="line-through tracking-tight text-gray-600 "
123+ x-text ="price(currency, volumeIndex, '{{ plan.tier }}', 'monthly') ">
124+ </ span >
125+ < span class ="ml-1 "
126+ x-text ="price(currency, volumeIndex, '{{ plan.tier }}', 'monthly', withDiscount = true) ">
127+ </ span >
128+ </ span >
129+ </ div >
130+ < div class ="flex flex-col text-sm text-gray-600 pl-1 leading-6 font-semibold ">
131+ < span class ="h-8 flex items-end "> /year</ span >
132+ < span class ="h-6 "> /month</ span >
133+ </ div >
134+ </ div >
135+ < div x-show ="!yearlyBilling && volumeIndex < volumesWithPrices.length "
136+ class ="flex items-baseline gap-x-1 ">
137+ < span class ="text-3xl font-bold tracking-tight leading-8 "
138+ x-text ="price(currency, volumeIndex, '{{ plan.tier }}', 'monthly') ">
139+ {{ plan.first_paint_price }}
140+ </ span >
141+ < span class ="text-sm font-semibold leading-6 text-gray-600 pl-1 self-end "> /month</ span >
142+ </ div >
143+ < div x-cloak x-show ="volumeIndex == volumesWithPrices.length "
144+ class ="text-3xl font-bold tracking-tight leading-8 ">
145+ Custom</ div >
146+ {% endif %}
147+ </ div >
148+ {% if plan.tier == "enterprise" %}
149+ < a href ="/contact "
150+ class ="mt-4 block rounded-md py-2 px-3 text-center text-sm font-semibold leading-6 transition duration-150 ease-in-out bg-gray-800 hover:bg-gray-700 text-white ">
151+ Contact us
152+ </ a >
153+ {% else %}
154+ < a :href ="volumeIndex < volumesWithPrices.length && '/register' || '/contact' "
155+ x-text ="volumeIndex < volumesWithPrices.length && 'Start your free trial' || 'Contact us' "
156+ class ="mt-4 block rounded-md py-2 px-3 text-center text-sm font-semibold leading-6 transition duration-150 ease-in-out bg-indigo-600 hover:bg-indigo-500 text-white ">
157+ Start your free trial
158+ </ a >
159+ {% endif %}
160+ < ul class ="mt-6 space-y-1 text-sm {{ plan.style.benefits_list | default: 'text-gray-600' }} ">
161+ {% for benefit in plan.benefits %}
162+ < li class ="flex gap-x-3 ">
163+ < svg class ="h-6 w-5 flex-none text-indigo-600 " viewBox ="0 0 20 20 " fill ="currentColor " aria-hidden ="true ">
164+ < path fill-rule ="evenodd " clip-rule ="evenodd "
165+ d ="M16.704 4.153a.75.75 0 01.143 1.052l-8 10.5a.75.75 0 01-1.127.075l-4.5-4.5a.75.75 0 011.06-1.06l3.894 3.893 7.48-9.817a.75.75 0 011.05-.143z " />
166+ </ svg >
167+ {{ benefit }}
168+ </ li >
169+ {% endfor %}
170+ </ ul >
171+ </ div >
172+ {% endfor %}
173+ </ div >
174+ </ div >
175+ </ div >
0 commit comments