The old "Why Choose EZSCALE VPS?" grid was duplicating the Included With All Plans card right below it (RAID 10, ZFS Snapshots, VirtFusion Panel, Full Root Access appeared in both). Replaced with 6 actual differentiators that answer "why us, not Linode/Hetzner/ Vultr": real US humans, ZFS-backed reliability, predictable billing, optional Pilot tier, 14-day money-back, owner-operated. Other improvements bundled in this pass: - Hero subtitle rewritten from feature dump to identity-first one-liner. - Plans table → responsive PlanCard grid with a "Most popular" badge on VPS-4 and a separate "Storage-focused" subgrid for stor-500/1tb. Each card carries Order Now + Estimate-this-plan link to the estimator (still wired to the prefillEstimator handler). - Added a 5-row "EZSCALE vs typical big-cloud" comparison table — honest differences only, no specific competitor names to avoid liability. - Added an 8-question FAQ section (provisioning time, OS list, upgrades, refunds, DDoS roadmap, rDNS, location, migrations) using a new reusable Faq accordion component. - Bottom CTA copy fixed (it was still mentioning DDoS protection as current; it's coming-soon upstream): now reads "Real humans on support. 14-day money-back if it's not the right fit." Heading flipped to "Ready to spin one up?" / "Talk to a Human." New shared components: Components/Marketing/PlanCard.vue, Components/Marketing/Faq.vue, Components/Marketing/ComparisonTable.vue. All three are reusable for the dedicated/web/game pages later. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
395 lines
14 KiB
Vue
395 lines
14 KiB
Vue
<script lang="ts" setup>
|
||
import { Head, usePage } from '@inertiajs/vue3'
|
||
import { computed } from 'vue'
|
||
import MarketingLayout from '@/Layouts/MarketingLayout.vue'
|
||
import SectionHeader from '@/Components/Marketing/SectionHeader.vue'
|
||
import HeroSection from '@/Components/Marketing/HeroSection.vue'
|
||
import VpsHero from '@/Components/Marketing/VpsHero.vue'
|
||
import EstimatorSection from '@/Components/Marketing/Estimator/EstimatorSection.vue'
|
||
import PlanCard from '@/Components/Marketing/PlanCard.vue'
|
||
import ComparisonTable from '@/Components/Marketing/ComparisonTable.vue'
|
||
import Faq from '@/Components/Marketing/Faq.vue'
|
||
import { useEstimatorStore, type EstimatorPlan, type EstimatorAddOnGroup, type WorkloadEntry, type AppExample } from '@/stores/estimator'
|
||
import { crossDomainUrl } from '@/utils/resolvers'
|
||
|
||
defineOptions({ layout: MarketingLayout })
|
||
|
||
interface PageProps {
|
||
plans: EstimatorPlan[]
|
||
addOns: EstimatorAddOnGroup[]
|
||
workloadMap: Record<string, WorkloadEntry>
|
||
appExamples: AppExample[]
|
||
domains: { marketing: string; account: string; admin: string }
|
||
}
|
||
|
||
interface Differentiator {
|
||
icon: string
|
||
title: string
|
||
description: string
|
||
}
|
||
|
||
interface IncludedItem {
|
||
text: string
|
||
comingSoon?: boolean
|
||
}
|
||
|
||
const page = usePage()
|
||
const props = computed(() => page.props as unknown as PageProps)
|
||
const accountUrl = computed<string>(() => crossDomainUrl(props.value.domains?.account))
|
||
const plans = computed<EstimatorPlan[]>(() => props.value.plans || [])
|
||
const addOns = computed<EstimatorAddOnGroup[]>(() => props.value.addOns || [])
|
||
const workloadMap = computed<Record<string, WorkloadEntry>>(() => props.value.workloadMap || {})
|
||
const appExamples = computed<AppExample[]>(() => props.value.appExamples || [])
|
||
|
||
const estimator = useEstimatorStore()
|
||
|
||
const startingPrice = computed<string>(() => {
|
||
if (plans.value.length === 0) return '5.00'
|
||
const lowest = Math.min(...plans.value.map(p => parseFloat(p.price)))
|
||
return lowest % 1 === 0 ? lowest.toString() : lowest.toFixed(2)
|
||
})
|
||
|
||
// Slug of the plan we want to flag as "Most popular" in the plan grid.
|
||
const popularSlug = 'vps-4'
|
||
|
||
// Plans split into standard VPS (1-32) and storage-focused tiers, so the grid
|
||
// reads as a clean ladder of one shape rather than a jumble.
|
||
const standardPlans = computed<EstimatorPlan[]>(() =>
|
||
plans.value.filter(p => !p.slug.startsWith('stor-')),
|
||
)
|
||
const storagePlans = computed<EstimatorPlan[]>(() =>
|
||
plans.value.filter(p => p.slug.startsWith('stor-')),
|
||
)
|
||
|
||
// Differentiators answer "why pick EZSCALE over Linode/Hetzner/Vultr" — distinct
|
||
// from the Included With All Plans card below which lists *what's in the box*.
|
||
const differentiators: Differentiator[] = [
|
||
{
|
||
icon: 'tabler-headset',
|
||
title: 'Real US-based humans',
|
||
description: 'Atlanta-based ops team. Tickets answered by engineers, not chatbots. Same hands fix the server and reply to your ticket.',
|
||
},
|
||
{
|
||
icon: 'tabler-history',
|
||
title: 'ZFS-backed reliability',
|
||
description: 'Free snapshots and instant rollbacks built into the storage layer — no bolt-on services to wire up or pay extra for.',
|
||
},
|
||
{
|
||
icon: 'tabler-receipt-2',
|
||
title: 'Predictable billing',
|
||
description: 'No surprise egress fees on fair-use traffic. Monthly, quarterly, or annual — your call. The price you see is the price you pay.',
|
||
},
|
||
{
|
||
icon: 'tabler-plane-tilt',
|
||
title: 'Optional Pilot tier',
|
||
description: 'Hand off the ops work at $99/mo. We run patching, monitoring, and deploys; you keep root access on a co-admin model.',
|
||
},
|
||
{
|
||
icon: 'tabler-shield-check',
|
||
title: '14-day money-back',
|
||
description: 'Try it for two weeks. If it isn’t the right fit, we refund the first cycle, no questions asked.',
|
||
},
|
||
{
|
||
icon: 'tabler-users',
|
||
title: 'Owner-operated',
|
||
description: 'Small US team. No 3-tier outsourced support maze. Direct line to the people who built it and run it.',
|
||
},
|
||
]
|
||
|
||
const includedFeatures: IncludedItem[] = [
|
||
{ text: '1 free IPv4 + 1 /64 IPv6 block' },
|
||
{ text: 'IPv4 rDNS / PTR control' },
|
||
{ text: '10 Gbps shared uplink (fair-use per AUP)' },
|
||
{ text: 'RAID 10 SSD storage' },
|
||
{ text: 'ZFS storage snapshots (free)' },
|
||
{ text: 'KVM virtualization' },
|
||
{ text: 'Full root access' },
|
||
{ text: 'Linux included; Windows supported (bring your own license)' },
|
||
{ text: 'VirtFusion control panel' },
|
||
{ text: 'Out-of-band console / VNC access' },
|
||
{ text: 'Near-instant provisioning' },
|
||
{ text: '99.9% uptime SLA' },
|
||
{ text: '14-day money-back guarantee' },
|
||
{ text: 'DDoS protection', comingSoon: true },
|
||
]
|
||
|
||
const comparisonRows = [
|
||
{
|
||
feature: 'Free snapshots & rollbacks',
|
||
ours: 'ZFS-backed, included',
|
||
theirs: '$0.05/GB add-on',
|
||
},
|
||
{
|
||
feature: 'Talk to engineers, not chatbots',
|
||
ours: 'Direct line to ops team',
|
||
theirs: 'Tier-1 outsourced',
|
||
},
|
||
{
|
||
feature: 'Predictable monthly bill',
|
||
ours: 'No egress fees on fair-use',
|
||
theirs: 'Per-GB egress overages',
|
||
},
|
||
{
|
||
feature: 'Optional managed (you keep root)',
|
||
ours: 'Pilot tier at $99/mo',
|
||
theirs: 'Often $200+/mo or unavailable',
|
||
},
|
||
{
|
||
feature: 'Money-back guarantee',
|
||
ours: '14 days, no questions',
|
||
theirs: '7 days or none',
|
||
},
|
||
]
|
||
|
||
const faqs = [
|
||
{
|
||
question: 'How quickly is my VPS provisioned?',
|
||
answer: 'Within seconds of completing checkout. You’ll get the root password (or your SSH key gets installed) on the same screen, and the VPS is bootable immediately. No queue, no manual approval.',
|
||
},
|
||
{
|
||
question: 'Which operating systems can I install?',
|
||
answer: 'Ubuntu (20.04, 22.04, 24.04), Debian (11, 12), Rocky Linux 9, AlmaLinux 9, CentOS Stream, and Windows Server 2019/2022 with your own license. Custom ISO uploads are supported via the VirtFusion panel.',
|
||
},
|
||
{
|
||
question: 'Can I upgrade or downgrade my plan later?',
|
||
answer: 'Yes. Upgrades resize on the next reboot; downgrades happen at the next billing cycle. Resizes preserve your data and IP. <a href="/contact">Contact us</a> if you need a custom build between tiers.',
|
||
},
|
||
{
|
||
question: 'What’s your refund policy?',
|
||
answer: '14-day money-back guarantee on the first cycle, no questions asked. After that, refunds are pro-rated against unused time on annual plans.',
|
||
},
|
||
{
|
||
question: 'Do you offer DDoS protection?',
|
||
answer: 'Volumetric DDoS protection is on the roadmap and will be free for all VPS plans when it ships. In the meantime, the network has standard upstream filtering and you can request null-routing of attack targets via support.',
|
||
},
|
||
{
|
||
question: 'Can I get rDNS / PTR control on my IPv4?',
|
||
answer: 'Yes — every VPS plan includes self-service rDNS / PTR record control through the VirtFusion panel. Useful if you’re running a mail server or anything that needs forward-confirmed DNS.',
|
||
},
|
||
{
|
||
question: 'Where are the servers physically located?',
|
||
answer: 'All VPS plans are hosted in our Atlanta, GA datacenter. EU and West Coast regions are on the roadmap.',
|
||
},
|
||
{
|
||
question: 'Do you help with migrations from another provider?',
|
||
answer: 'Yes. <a href="/contact">Open a ticket before you order</a> and we’ll help size the right plan and transfer your existing setup. Pilot-tier customers get migration assistance included; Self/Basic/Pro plans get free guidance, paid hands-on labor.',
|
||
},
|
||
]
|
||
|
||
function prefillEstimator(planId: number): void {
|
||
estimator.setPlan(planId)
|
||
if (typeof window !== 'undefined') {
|
||
const url = estimator.shareUrl
|
||
window.history.replaceState({}, '', url)
|
||
const el = document.querySelector('.estimator-section')
|
||
if (el) el.scrollIntoView({ behavior: 'smooth', block: 'start' })
|
||
}
|
||
}
|
||
</script>
|
||
|
||
<template>
|
||
<Head title="VPS Hosting | EZSCALE" />
|
||
<div>
|
||
<!-- Hero -->
|
||
<HeroSection>
|
||
<template #content>
|
||
<VChip color="primary" variant="tonal" class="mb-4">VPS Hosting</VChip>
|
||
<h1 class="text-h3 font-weight-bold mb-3">
|
||
Virtual Private <span class="hero-gradient-text">Servers</span>
|
||
</h1>
|
||
<p class="text-h6 text-medium-emphasis font-weight-regular mb-4" style="max-width: 600px;">
|
||
Atlanta-based VPS hosting from a small team that picks up the phone. ZFS-backed reliability, predictable billing, and real root access.
|
||
</p>
|
||
<p class="text-body-1 text-medium-emphasis mb-8">
|
||
Starting at just <span class="text-primary font-weight-bold">${{ startingPrice }}/mo</span>
|
||
</p>
|
||
<a :href="plans.length ? accountUrl + '/checkout/' + plans[0].id : '/pricing'" class="text-decoration-none">
|
||
<VBtn color="primary" size="large" rounded="lg">
|
||
Get Started
|
||
<VIcon icon="tabler-arrow-right" end />
|
||
</VBtn>
|
||
</a>
|
||
</template>
|
||
|
||
<template #visual>
|
||
<VpsHero />
|
||
</template>
|
||
</HeroSection>
|
||
|
||
<!-- Estimator -->
|
||
<EstimatorSection
|
||
:plans="plans"
|
||
:add-ons="addOns"
|
||
:workload-map="workloadMap"
|
||
:app-examples="appExamples"
|
||
:account-url="accountUrl"
|
||
/>
|
||
|
||
<!-- Differentiators -->
|
||
<VContainer class="marketing-section">
|
||
<SectionHeader
|
||
label="Why EZSCALE"
|
||
title="Built different on purpose"
|
||
highlight-word="different"
|
||
subtitle="Six things that separate us from the multi-region mega-clouds — and from the race-to-the-bottom budget hosts."
|
||
/>
|
||
<VRow>
|
||
<VCol
|
||
v-for="(item, index) in differentiators"
|
||
:key="item.title"
|
||
cols="12"
|
||
sm="6"
|
||
md="4"
|
||
>
|
||
<div :class="['d-flex ga-3 mb-4 feature-card-hover pa-3 rounded-lg', `fade-in-up stagger-${index + 1}`]">
|
||
<VAvatar color="primary" variant="tonal" size="44">
|
||
<VIcon :icon="item.icon" size="22" />
|
||
</VAvatar>
|
||
<div>
|
||
<h3 class="text-subtitle-1 font-weight-bold">{{ item.title }}</h3>
|
||
<p class="text-body-2 text-medium-emphasis mb-0">{{ item.description }}</p>
|
||
</div>
|
||
</div>
|
||
</VCol>
|
||
</VRow>
|
||
</VContainer>
|
||
|
||
<!-- Plans grid -->
|
||
<div class="section-alt-bg marketing-section">
|
||
<VContainer>
|
||
<SectionHeader
|
||
label="Pricing"
|
||
title="VPS Plans"
|
||
highlight-word="Plans"
|
||
subtitle="All plans hosted in our Atlanta, GA datacenter. Free ZFS snapshots, full root access, and the VirtFusion panel are included on every tier."
|
||
/>
|
||
|
||
<h3 class="text-h6 font-weight-bold mb-4 plan-grid-heading">Standard VPS</h3>
|
||
<VRow class="mb-8">
|
||
<VCol
|
||
v-for="plan in standardPlans"
|
||
:key="plan.id"
|
||
cols="12"
|
||
sm="6"
|
||
md="4"
|
||
lg="3"
|
||
>
|
||
<PlanCard
|
||
:plan="plan"
|
||
:popular="plan.slug === popularSlug"
|
||
:order-url="accountUrl + '/checkout/' + plan.id"
|
||
@estimate="prefillEstimator"
|
||
/>
|
||
</VCol>
|
||
</VRow>
|
||
|
||
<h3 v-if="storagePlans.length" class="text-h6 font-weight-bold mb-4 plan-grid-heading">Storage-focused</h3>
|
||
<VRow v-if="storagePlans.length" class="mb-4">
|
||
<VCol
|
||
v-for="plan in storagePlans"
|
||
:key="plan.id"
|
||
cols="12"
|
||
sm="6"
|
||
md="4"
|
||
lg="3"
|
||
>
|
||
<PlanCard
|
||
:plan="plan"
|
||
:order-url="accountUrl + '/checkout/' + plan.id"
|
||
variant="storage"
|
||
@estimate="prefillEstimator"
|
||
/>
|
||
</VCol>
|
||
</VRow>
|
||
|
||
<!-- Included with all plans -->
|
||
<VCard class="mt-8 pa-6 feature-card-hover">
|
||
<h3 class="text-h5 font-weight-bold mb-4 text-center">Included With All Plans</h3>
|
||
<VRow>
|
||
<VCol
|
||
v-for="item in includedFeatures"
|
||
:key="item.text"
|
||
cols="12"
|
||
sm="6"
|
||
md="4"
|
||
>
|
||
<div class="d-flex align-center ga-2 mb-2">
|
||
<VIcon
|
||
:icon="item.comingSoon ? 'tabler-clock' : 'tabler-circle-check'"
|
||
:color="item.comingSoon ? 'warning' : 'success'"
|
||
size="20"
|
||
/>
|
||
<span class="text-body-1">{{ item.text }}</span>
|
||
<VChip
|
||
v-if="item.comingSoon"
|
||
size="x-small"
|
||
color="warning"
|
||
variant="tonal"
|
||
density="compact"
|
||
class="ms-1"
|
||
>
|
||
Coming soon
|
||
</VChip>
|
||
</div>
|
||
</VCol>
|
||
</VRow>
|
||
</VCard>
|
||
</VContainer>
|
||
</div>
|
||
|
||
<!-- Comparison -->
|
||
<VContainer class="marketing-section">
|
||
<SectionHeader
|
||
label="Comparison"
|
||
title="EZSCALE vs the big-cloud playbook"
|
||
highlight-word="EZSCALE"
|
||
subtitle="A few honest differences — the kind that show up on a bill at the end of the month."
|
||
/>
|
||
<ComparisonTable :rows="comparisonRows" />
|
||
</VContainer>
|
||
|
||
<!-- FAQ -->
|
||
<div class="section-alt-bg marketing-section">
|
||
<VContainer>
|
||
<SectionHeader
|
||
label="FAQ"
|
||
title="Common questions"
|
||
highlight-word="questions"
|
||
subtitle="The stuff people ask before signing up. Don't see yours? Hit us at /contact."
|
||
/>
|
||
<Faq :items="faqs" />
|
||
</VContainer>
|
||
</div>
|
||
|
||
<!-- CTA -->
|
||
<div class="marketing-section" style="background: linear-gradient(135deg, rgb(var(--v-theme-primary), 0.12), rgb(var(--v-theme-surface)));">
|
||
<VContainer class="text-center">
|
||
<h2 class="text-h4 font-weight-bold mb-3">Ready to spin one up?</h2>
|
||
<p class="text-body-1 text-medium-emphasis mb-6">
|
||
Deploy in seconds. Real humans on support. 14-day money-back if it's not the right fit.
|
||
</p>
|
||
<div class="d-flex ga-3 justify-center flex-wrap">
|
||
<a :href="plans.length ? accountUrl + '/checkout/' + plans[0].id : '/pricing'" class="text-decoration-none">
|
||
<VBtn color="primary" size="large" rounded="lg">
|
||
Get Started
|
||
<VIcon icon="tabler-arrow-right" end />
|
||
</VBtn>
|
||
</a>
|
||
<a href="/contact" class="text-decoration-none">
|
||
<VBtn color="primary" variant="outlined" size="large" rounded="lg">
|
||
Talk to a Human
|
||
</VBtn>
|
||
</a>
|
||
</div>
|
||
</VContainer>
|
||
</div>
|
||
</div>
|
||
</template>
|
||
|
||
<style lang="scss" scoped>
|
||
.plan-grid-heading {
|
||
letter-spacing: -0.01em;
|
||
color: rgba(var(--v-theme-on-surface), 0.85);
|
||
}
|
||
</style>
|