Add About, Services, Pricing pages with quote form
- /about: company story, differentiators, values, founder bio, industries, company details - /services: 6 service cards with pricing, assurance pack, process steps, tech stack - /pricing: pricing table, retainer tiers, training, payment terms, discounts, comparison, FAQ, inline quote form - QuoteForm component with service dropdown + project description textarea - POST /api/quote endpoint via Resend for quote requests - Nav updated: About Us, Services, Pricing now route to standalone pages - SEO: JSON-LD schemas, sitemap.xml, llms.txt updated - Founder photo added Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
7c8276da17
commit
af26ccd2b7
14 changed files with 2716 additions and 13 deletions
|
|
@ -46,4 +46,50 @@ app.post('/api/contact', async (req, res) => {
|
|||
}
|
||||
});
|
||||
|
||||
app.post('/api/quote', async (req, res) => {
|
||||
const { fullName, workEmail, companyName, jobTitle, phoneNumber, service, projectDescription } = req.body;
|
||||
|
||||
if (!fullName || !workEmail || !service || !projectDescription) {
|
||||
return res.status(400).json({ error: 'Missing required fields' });
|
||||
}
|
||||
|
||||
try {
|
||||
const response = await fetch('https://api.resend.com/emails', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Authorization': `Bearer ${process.env.RESEND_API_KEY}`,
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify({
|
||||
from: 'AImpress Website <noreply@ai-impress.com>',
|
||||
to: ['hello@ai-impress.com'],
|
||||
subject: `Quote request: ${fullName} — ${service}`,
|
||||
html: `
|
||||
<h2>New Quote Request</h2>
|
||||
<p><strong>Name:</strong> ${fullName}</p>
|
||||
<p><strong>Email:</strong> ${workEmail}</p>
|
||||
<p><strong>Company:</strong> ${companyName || 'N/A'}</p>
|
||||
<p><strong>Job Title:</strong> ${jobTitle || 'N/A'}</p>
|
||||
<p><strong>Phone:</strong> ${phoneNumber || 'N/A'}</p>
|
||||
<hr>
|
||||
<p><strong>Service:</strong> ${service}</p>
|
||||
<p><strong>Project Description:</strong></p>
|
||||
<p>${projectDescription.replace(/\n/g, '<br>')}</p>
|
||||
`,
|
||||
}),
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
const err = await response.text();
|
||||
console.error('Resend error:', err);
|
||||
return res.status(502).json({ error: 'Email delivery failed' });
|
||||
}
|
||||
|
||||
res.json({ ok: true });
|
||||
} catch (err) {
|
||||
console.error('Email error:', err);
|
||||
res.status(500).json({ error: 'Internal error' });
|
||||
}
|
||||
});
|
||||
|
||||
app.listen(3001, () => console.log('Email API listening on :3001'));
|
||||
|
|
|
|||
16
public/founder-danylo.jpeg
Normal file
16
public/founder-danylo.jpeg
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
|
||||
<html><head>
|
||||
<meta http-equiv="content-type" content="text/html;charset=utf-8">
|
||||
<title>413 Request Entity Too Large</title>
|
||||
</head>
|
||||
<body text=#000000 bgcolor=#ffffff>
|
||||
<h1>Error: Request Entity Too Large</h1>
|
||||
<h2>Your client issued a request that was too large.
|
||||
</h2>
|
||||
<h2><script>
|
||||
(function() { var c=function(a,d,b){a=a+"=deleted; path="+d;b!=null&&(a+="; domain="+b);document.cookie=a+"; expires=Thu, 01 Jan 1970 00:00:00 GMT"};var g=function(a){var d=e,b=location.hostname;c(d,a,null);c(d,a,b);for(var f=0;;){f=b.indexOf(".",f+1);if(f<0)break;c(d,a,b.substring(f+1))}};var h;if(unescape(encodeURI(document.cookie)).length>4E3){for(var k=document.cookie.split(";"),l=[],m=0;m<k.length;m++){var n=k[m].match(/^\s*([^=]+)/);n&&l.push(n[1])}for(var p=0;p<l.length;p++){var e=l[p];g("/");for(var q=location.pathname,r=0;;){r=q.indexOf("/",r+1);if(r<0)break;var t=q.substring(0,r);g(t);g(t+"/")}q.charAt(q.length-1)!="/"&&(g(q),g(q+"/"))}h=!0}else h=!1;
|
||||
h&&setTimeout(function(){if(history.replaceState){var a=location.href;history.replaceState(null,"","/");location.replace(a)}},1E3); })();
|
||||
|
||||
</script>
|
||||
</h2>
|
||||
</body></html>
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
# AImpress Ltd
|
||||
|
||||
## About
|
||||
AImpress is an AI and automation consulting company based in London, UK. We help small and medium-sized enterprises (SMEs) adopt AI-powered solutions to automate operations, reduce costs, and accelerate growth.
|
||||
AImpress is an AI and automation consulting company based in London, UK. Founded in 2024, we help small and medium-sized enterprises (SMEs), charities, and public sector organisations adopt AI-powered solutions to automate operations, reduce costs, and accelerate growth. We specialise in client-owned infrastructure with no vendor lock-in, full documentation, and team training included in every project.
|
||||
|
||||
## Company Details
|
||||
- Legal Name: AImpress Ltd
|
||||
|
|
@ -12,18 +12,38 @@ AImpress is an AI and automation consulting company based in London, UK. We help
|
|||
- Website: https://ai-impress.com
|
||||
- Email: hello@ai-impress.com
|
||||
|
||||
## Services
|
||||
- AI Chatbots & Virtual Assistants — custom chatbots for customer support, lead qualification, and appointment booking
|
||||
- Business Process Automation — workflow automation using Make.com, Zapier, and custom integrations
|
||||
- Content Automation (Content Farms) — automated content generation for blogs, social media, and marketing
|
||||
- Marketing Automation — lead nurturing, email campaigns, CRM integration, and conversion optimisation
|
||||
- AI Strategy Consulting — roadmap development, tool selection, and implementation planning for SMEs
|
||||
## Services & Pricing
|
||||
- Workflow Automation Implementation (£3,500–£12,000) — end-to-end process automation using n8n, Make.com, and custom integrations
|
||||
- System Integration & Synchronisation (£2,500–£10,000+) — API integrations, bi-directional data sync, webhook triggers
|
||||
- CRM Workflow Optimisation (£3,000–£6,500) — pipeline restructure, automated lead scoring, email sequences
|
||||
- Marketing Automation Setup (£3,500–£8,000) — drip campaigns, lead capture, audience segmentation, analytics
|
||||
- AI Integration & Enhancement (£4,000–£12,000) — chatbots, content generation, document processing, prompt engineering
|
||||
- Infrastructure Setup & Configuration (£1,500–£4,000) — server provisioning, automation platform deployment, security hardening
|
||||
|
||||
## Support Retainers
|
||||
- Essential: £1,000/month (10 hours, 48h SLA)
|
||||
- Professional: £2,000/month (22 hours, 24h SLA)
|
||||
- Enterprise: £3,500/month (40 hours, 4h SLA)
|
||||
|
||||
## Impact Grant Programme
|
||||
- Charities & Non-Profits: up to 50% discount
|
||||
- Startups (< 2 years): up to 50% discount
|
||||
- Education: up to 50% discount
|
||||
- Public Sector: 25% discount + free pilot project
|
||||
- Ukrainian Businesses: up to 50% discount
|
||||
|
||||
## Technologies
|
||||
Make.com, Zapier, OpenAI, Anthropic Claude, Google AI, HubSpot, Salesforce, WordPress, Shopify, custom API integrations
|
||||
n8n, Make.com, Zapier, Power Automate, OpenAI, Anthropic Claude, Google AI, LangChain, HubSpot, Salesforce, Pipedrive, Zoho, Mailchimp, ActiveCampaign, Brevo, AWS, Hetzner, Docker, Nginx, Cloudflare, Power BI, Mixpanel, Slack, Teams, Twilio
|
||||
|
||||
## Industries Served
|
||||
Professional services, healthcare, hospitality, retail, e-commerce, property management, education, fitness, food & beverage
|
||||
E-commerce, professional services, SaaS, charities, education, healthcare, public sector
|
||||
|
||||
## Pages
|
||||
- Home: https://ai-impress.com/
|
||||
- About: https://ai-impress.com/about
|
||||
- Services: https://ai-impress.com/services
|
||||
- Pricing: https://ai-impress.com/pricing
|
||||
- Blog: https://ai-impress.com/blog
|
||||
|
||||
## Social Media
|
||||
- LinkedIn: https://www.linkedin.com/company/aimpress-ltd/
|
||||
|
|
|
|||
|
|
@ -5,6 +5,21 @@
|
|||
<changefreq>weekly</changefreq>
|
||||
<priority>1.0</priority>
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://ai-impress.com/about</loc>
|
||||
<changefreq>monthly</changefreq>
|
||||
<priority>0.8</priority>
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://ai-impress.com/services</loc>
|
||||
<changefreq>monthly</changefreq>
|
||||
<priority>0.8</priority>
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://ai-impress.com/pricing</loc>
|
||||
<changefreq>monthly</changefreq>
|
||||
<priority>0.8</priority>
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://ai-impress.com/blog</loc>
|
||||
<changefreq>weekly</changefreq>
|
||||
|
|
|
|||
|
|
@ -9,6 +9,9 @@ import BlogPage from './pages/BlogPage';
|
|||
import BlogPostPage from './pages/BlogPostPage';
|
||||
import PrivacyPolicyPage from './pages/PrivacyPolicyPage';
|
||||
import TermsOfUsePage from './pages/TermsOfUsePage';
|
||||
import AboutPage from './pages/AboutPage';
|
||||
import ServicesPage from './pages/ServicesPage';
|
||||
import PricingPage from './pages/PricingPage';
|
||||
import './App.css';
|
||||
|
||||
function App() {
|
||||
|
|
@ -18,6 +21,9 @@ function App() {
|
|||
<Header />
|
||||
<Routes>
|
||||
<Route path="/" element={<HomePage />} />
|
||||
<Route path="/about" element={<AboutPage />} />
|
||||
<Route path="/services" element={<ServicesPage />} />
|
||||
<Route path="/pricing" element={<PricingPage />} />
|
||||
<Route path="/blog" element={<BlogPage />} />
|
||||
<Route path="/blog/:slug" element={<BlogPostPage />} />
|
||||
<Route path="/privacy-policy" element={<PrivacyPolicyPage />} />
|
||||
|
|
|
|||
|
|
@ -5,11 +5,11 @@ import Modal from './Modal';
|
|||
import './Header.css';
|
||||
|
||||
const navItems = [
|
||||
{ name: 'Home', link: '#hero' },
|
||||
{ name: 'About Us', link: '#benefits' },
|
||||
{ name: 'Services', link: '#timeline' },
|
||||
{ name: 'Home', link: '/' },
|
||||
{ name: 'About Us', link: '/about' },
|
||||
{ name: 'Services', link: '/services' },
|
||||
{ name: 'Cases', link: '#testimonials' },
|
||||
{ name: 'Pricing', link: '#comparison' },
|
||||
{ name: 'Pricing', link: '/pricing' },
|
||||
{ name: 'Blog', link: '/blog' },
|
||||
{ name: 'Contacts', link: '#contact' },
|
||||
];
|
||||
|
|
|
|||
72
src/components/QuoteForm.css
Normal file
72
src/components/QuoteForm.css
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
.quote-form-container {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.quote-form {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 1.5rem;
|
||||
}
|
||||
|
||||
/* Select styling */
|
||||
.quote-form-container .form-group select {
|
||||
background: rgba(255, 255, 255, 0.04);
|
||||
border: 1px solid rgba(255, 255, 255, 0.08);
|
||||
border-radius: 12px;
|
||||
padding: 0.9rem 1.2rem;
|
||||
color: #fff;
|
||||
font-family: inherit;
|
||||
font-size: 0.95rem;
|
||||
transition: border-color 0.25s, background 0.25s, box-shadow 0.25s;
|
||||
appearance: none;
|
||||
-webkit-appearance: none;
|
||||
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8' fill='none'%3E%3Cpath d='M1 1.5L6 6.5L11 1.5' stroke='%23D3DDDE' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
|
||||
background-repeat: no-repeat;
|
||||
background-position: right 1.2rem center;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.quote-form-container .form-group select option {
|
||||
background: var(--dark-grey-100);
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.quote-form-container .form-group select:focus {
|
||||
outline: none;
|
||||
border-color: var(--orange-100);
|
||||
background-color: rgba(255, 255, 255, 0.06);
|
||||
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8' fill='none'%3E%3Cpath d='M1 1.5L6 6.5L11 1.5' stroke='%23FF5B04' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
|
||||
background-repeat: no-repeat;
|
||||
background-position: right 1.2rem center;
|
||||
box-shadow: 0 0 0 3px rgba(255, 91, 4, 0.1);
|
||||
}
|
||||
|
||||
/* Textarea styling */
|
||||
.quote-form-container .form-group textarea {
|
||||
background: rgba(255, 255, 255, 0.04);
|
||||
border: 1px solid rgba(255, 255, 255, 0.08);
|
||||
border-radius: 12px;
|
||||
padding: 0.9rem 1.2rem;
|
||||
color: #fff;
|
||||
font-family: inherit;
|
||||
font-size: 0.95rem;
|
||||
resize: vertical;
|
||||
min-height: 100px;
|
||||
transition: border-color 0.25s, background 0.25s, box-shadow 0.25s;
|
||||
}
|
||||
|
||||
.quote-form-container .form-group textarea::placeholder {
|
||||
color: rgba(211, 221, 222, 0.25);
|
||||
}
|
||||
|
||||
.quote-form-container .form-group textarea:focus {
|
||||
outline: none;
|
||||
border-color: var(--orange-100);
|
||||
background: rgba(255, 255, 255, 0.06);
|
||||
box-shadow: 0 0 0 3px rgba(255, 91, 4, 0.1);
|
||||
}
|
||||
|
||||
/* Full-width field */
|
||||
.form-group--full {
|
||||
grid-column: 1 / -1;
|
||||
}
|
||||
202
src/components/QuoteForm.tsx
Normal file
202
src/components/QuoteForm.tsx
Normal file
|
|
@ -0,0 +1,202 @@
|
|||
import React, { useState, type ChangeEvent, type FormEvent } from 'react';
|
||||
import { motion } from 'framer-motion';
|
||||
import mixpanel from 'mixpanel-browser';
|
||||
import './QuoteForm.css';
|
||||
|
||||
interface QuoteData {
|
||||
fullName: string;
|
||||
workEmail: string;
|
||||
companyName: string;
|
||||
jobTitle: string;
|
||||
phoneNumber: string;
|
||||
service: string;
|
||||
projectDescription: string;
|
||||
}
|
||||
|
||||
const serviceOptions = [
|
||||
'Workflow Automation Implementation',
|
||||
'System Integration & Synchronisation',
|
||||
'CRM Workflow Optimisation',
|
||||
'Marketing Automation Setup',
|
||||
'AI Integration & Enhancement',
|
||||
'Infrastructure Setup & Configuration',
|
||||
'Support Retainer',
|
||||
'Training & Workshop',
|
||||
'Other / Not sure yet',
|
||||
];
|
||||
|
||||
interface QuoteFormProps {
|
||||
onClose?: () => void;
|
||||
}
|
||||
|
||||
const QuoteForm: React.FC<QuoteFormProps> = () => {
|
||||
const [formData, setFormData] = useState<QuoteData>({
|
||||
fullName: '',
|
||||
workEmail: '',
|
||||
companyName: '',
|
||||
jobTitle: '',
|
||||
phoneNumber: '',
|
||||
service: '',
|
||||
projectDescription: '',
|
||||
});
|
||||
|
||||
const [status, setStatus] = useState<'idle' | 'submitting' | 'success' | 'error'>('idle');
|
||||
const [focusedField, setFocusedField] = useState<string | null>(null);
|
||||
|
||||
const handleChange = (e: ChangeEvent<HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement>) => {
|
||||
const { name, value } = e.target;
|
||||
setFormData((prev) => ({ ...prev, [name]: value }));
|
||||
};
|
||||
|
||||
const handleSubmit = async (e: FormEvent) => {
|
||||
e.preventDefault();
|
||||
setStatus('submitting');
|
||||
|
||||
try {
|
||||
const res = await fetch('/api/quote', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify(formData),
|
||||
});
|
||||
if (!res.ok) throw new Error('Failed');
|
||||
|
||||
mixpanel.track('Conversion', {
|
||||
'Conversion Type': 'Quote Request',
|
||||
'company_name': formData.companyName,
|
||||
'job_title': formData.jobTitle,
|
||||
'service': formData.service,
|
||||
});
|
||||
setStatus('success');
|
||||
setFormData({
|
||||
fullName: '',
|
||||
workEmail: '',
|
||||
companyName: '',
|
||||
jobTitle: '',
|
||||
phoneNumber: '',
|
||||
service: '',
|
||||
projectDescription: '',
|
||||
});
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
mixpanel.track('Error', {
|
||||
'error_type': 'quote_form_submission',
|
||||
'error_message': String(error),
|
||||
'page_url': window.location.href,
|
||||
});
|
||||
setStatus('error');
|
||||
}
|
||||
};
|
||||
|
||||
const inputFields = [
|
||||
{ label: 'Full Name', name: 'fullName', type: 'text', placeholder: 'John Doe' },
|
||||
{ label: 'Job Title / Role', name: 'jobTitle', type: 'text', placeholder: 'Project Manager' },
|
||||
{ label: 'Work Email', name: 'workEmail', type: 'email', placeholder: 'john@company.com' },
|
||||
{ label: 'Phone Number', name: 'phoneNumber', type: 'tel', placeholder: '+44...' },
|
||||
{ label: 'Company Name', name: 'companyName', type: 'text', placeholder: 'Tech Solutions Ltd' },
|
||||
];
|
||||
|
||||
return (
|
||||
<div className="quote-form-container">
|
||||
<h2 className="form-title">Get Your Quote</h2>
|
||||
|
||||
{status === 'success' ? (
|
||||
<div className="success-message">
|
||||
<h3>Thank you!</h3>
|
||||
<p>We've received your quote request. We'll review your requirements and get back to you within 24 hours with a detailed proposal.</p>
|
||||
<button onClick={() => setStatus('idle')} className="reset-btn">Submit another request</button>
|
||||
</div>
|
||||
) : (
|
||||
<form onSubmit={handleSubmit} className="quote-form">
|
||||
<div className="form-grid">
|
||||
{inputFields.map((field, i) => (
|
||||
<motion.div
|
||||
key={field.name}
|
||||
className={`form-group ${focusedField === field.name ? 'form-group--focused' : ''}`}
|
||||
initial={{ opacity: 0, y: 20 }}
|
||||
whileInView={{ opacity: 1, y: 0 }}
|
||||
viewport={{ once: true }}
|
||||
transition={{ duration: 0.3, delay: i * 0.08 }}
|
||||
>
|
||||
<label>{field.label}*</label>
|
||||
<input
|
||||
type={field.type}
|
||||
name={field.name}
|
||||
required
|
||||
value={formData[field.name as keyof QuoteData]}
|
||||
onChange={handleChange}
|
||||
onFocus={() => setFocusedField(field.name)}
|
||||
onBlur={() => setFocusedField(null)}
|
||||
placeholder={field.placeholder}
|
||||
/>
|
||||
</motion.div>
|
||||
))}
|
||||
|
||||
<motion.div
|
||||
className={`form-group ${focusedField === 'service' ? 'form-group--focused' : ''}`}
|
||||
initial={{ opacity: 0, y: 20 }}
|
||||
whileInView={{ opacity: 1, y: 0 }}
|
||||
viewport={{ once: true }}
|
||||
transition={{ duration: 0.3, delay: 0.4 }}
|
||||
>
|
||||
<label>Service*</label>
|
||||
<select
|
||||
name="service"
|
||||
required
|
||||
value={formData.service}
|
||||
onChange={handleChange}
|
||||
onFocus={() => setFocusedField('service')}
|
||||
onBlur={() => setFocusedField(null)}
|
||||
>
|
||||
<option value="" disabled>Select a service...</option>
|
||||
{serviceOptions.map((opt) => (
|
||||
<option key={opt} value={opt}>{opt}</option>
|
||||
))}
|
||||
</select>
|
||||
</motion.div>
|
||||
</div>
|
||||
|
||||
<motion.div
|
||||
className={`form-group form-group--full ${focusedField === 'projectDescription' ? 'form-group--focused' : ''}`}
|
||||
initial={{ opacity: 0, y: 20 }}
|
||||
whileInView={{ opacity: 1, y: 0 }}
|
||||
viewport={{ once: true }}
|
||||
transition={{ duration: 0.3, delay: 0.5 }}
|
||||
>
|
||||
<label>Project Description*</label>
|
||||
<textarea
|
||||
name="projectDescription"
|
||||
required
|
||||
value={formData.projectDescription}
|
||||
onChange={handleChange}
|
||||
onFocus={() => setFocusedField('projectDescription')}
|
||||
onBlur={() => setFocusedField(null)}
|
||||
placeholder="Describe your automation needs, current challenges, and desired outcomes..."
|
||||
rows={4}
|
||||
/>
|
||||
</motion.div>
|
||||
|
||||
<motion.div
|
||||
className="form-actions"
|
||||
initial={{ opacity: 0, y: 20 }}
|
||||
whileInView={{ opacity: 1, y: 0 }}
|
||||
viewport={{ once: true }}
|
||||
transition={{ duration: 0.3, delay: 0.6 }}
|
||||
>
|
||||
<motion.button
|
||||
type="submit"
|
||||
className="submit-btn"
|
||||
disabled={status === 'submitting'}
|
||||
whileHover={{ scale: 1.03 }}
|
||||
whileTap={{ scale: 0.97 }}
|
||||
>
|
||||
{status === 'submitting' ? 'Sending...' : 'Get Your Quote'}
|
||||
</motion.button>
|
||||
{status === 'error' && <p className="error-text">Something went wrong. Please try again.</p>}
|
||||
</motion.div>
|
||||
</form>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default QuoteForm;
|
||||
375
src/pages/AboutPage.css
Normal file
375
src/pages/AboutPage.css
Normal file
|
|
@ -0,0 +1,375 @@
|
|||
.about-page {
|
||||
padding-top: 8rem;
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
/* Hero */
|
||||
.about-hero {
|
||||
padding: 4rem 2rem 3rem;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.about-hero h1 {
|
||||
font-size: 3.2rem;
|
||||
font-weight: 800;
|
||||
color: #fff;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
.about-hero-sub {
|
||||
font-size: 1.2rem;
|
||||
color: var(--light-grey-100);
|
||||
opacity: 0.8;
|
||||
max-width: 600px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
/* Sections */
|
||||
.about-section {
|
||||
padding: 4rem 2rem;
|
||||
}
|
||||
|
||||
.about-section .section-title {
|
||||
text-align: center;
|
||||
font-size: 2rem;
|
||||
font-weight: 800;
|
||||
color: #fff;
|
||||
margin-bottom: 2.5rem;
|
||||
}
|
||||
|
||||
/* Story */
|
||||
.about-story-text {
|
||||
max-width: 800px;
|
||||
margin: 0 auto;
|
||||
color: var(--light-grey-100);
|
||||
font-size: 1.05rem;
|
||||
line-height: 1.8;
|
||||
}
|
||||
|
||||
.about-story-text p {
|
||||
margin-bottom: 1.2rem;
|
||||
}
|
||||
|
||||
/* Differentiator Cards */
|
||||
.about-diff-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
gap: 1.5rem;
|
||||
max-width: 1000px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.about-glass-card {
|
||||
background: rgba(255, 255, 255, 0.05);
|
||||
backdrop-filter: blur(12px);
|
||||
border: 1px solid rgba(255, 255, 255, 0.1);
|
||||
border-radius: 16px;
|
||||
padding: 2rem;
|
||||
transition: border-color 0.3s;
|
||||
}
|
||||
|
||||
.about-glass-card:hover {
|
||||
border-color: var(--orange-100);
|
||||
}
|
||||
|
||||
.about-card-icon {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
color: var(--orange-100);
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
.about-card-icon svg {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.about-glass-card h3 {
|
||||
font-size: 1.15rem;
|
||||
font-weight: 700;
|
||||
color: #fff;
|
||||
margin-bottom: 0.6rem;
|
||||
}
|
||||
|
||||
.about-glass-card p {
|
||||
color: var(--light-grey-100);
|
||||
font-size: 0.95rem;
|
||||
line-height: 1.6;
|
||||
opacity: 0.85;
|
||||
}
|
||||
|
||||
/* Values */
|
||||
.about-values-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(5, 1fr);
|
||||
gap: 1.25rem;
|
||||
max-width: 1100px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.about-value-item {
|
||||
background: rgba(255, 255, 255, 0.04);
|
||||
border: 1px solid rgba(255, 255, 255, 0.08);
|
||||
border-radius: 12px;
|
||||
padding: 1.5rem;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.about-value-item h3 {
|
||||
font-size: 1rem;
|
||||
font-weight: 700;
|
||||
color: var(--orange-100);
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
.about-value-item p {
|
||||
color: var(--light-grey-100);
|
||||
font-size: 0.85rem;
|
||||
line-height: 1.5;
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
/* Founder */
|
||||
.about-founder-card {
|
||||
display: flex;
|
||||
gap: 2.5rem;
|
||||
align-items: flex-start;
|
||||
max-width: 900px;
|
||||
margin: 0 auto;
|
||||
background: rgba(255, 255, 255, 0.05);
|
||||
backdrop-filter: blur(12px);
|
||||
border: 1px solid rgba(255, 255, 255, 0.1);
|
||||
border-left: 3px solid var(--orange-100);
|
||||
border-radius: 16px;
|
||||
padding: 2.5rem;
|
||||
}
|
||||
|
||||
.about-founder-photo {
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.about-founder-img {
|
||||
width: 140px;
|
||||
height: 140px;
|
||||
border-radius: 50%;
|
||||
object-fit: cover;
|
||||
border: 3px solid rgba(255, 255, 255, 0.15);
|
||||
}
|
||||
|
||||
.about-founder-info h3 {
|
||||
font-size: 1.5rem;
|
||||
font-weight: 800;
|
||||
color: #fff;
|
||||
margin-bottom: 0.25rem;
|
||||
}
|
||||
|
||||
.about-founder-role {
|
||||
display: block;
|
||||
color: var(--orange-100);
|
||||
font-weight: 600;
|
||||
font-size: 0.95rem;
|
||||
margin-bottom: 1.25rem;
|
||||
}
|
||||
|
||||
.about-founder-details {
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.about-founder-details li {
|
||||
color: var(--light-grey-100);
|
||||
font-size: 0.95rem;
|
||||
line-height: 1.6;
|
||||
margin-bottom: 0.75rem;
|
||||
padding-left: 1rem;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.about-founder-details li::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0.55em;
|
||||
width: 5px;
|
||||
height: 5px;
|
||||
border-radius: 50%;
|
||||
background: var(--orange-100);
|
||||
}
|
||||
|
||||
.about-founder-details li strong {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
/* Industries */
|
||||
.about-industries {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 1rem;
|
||||
justify-content: center;
|
||||
max-width: 800px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.about-industry-badge {
|
||||
background: rgba(255, 255, 255, 0.06);
|
||||
border: 1px solid rgba(255, 255, 255, 0.12);
|
||||
border-radius: 100px;
|
||||
padding: 0.6rem 1.5rem;
|
||||
color: var(--light-grey-100);
|
||||
font-size: 0.95rem;
|
||||
font-weight: 500;
|
||||
transition: border-color 0.3s, color 0.3s;
|
||||
}
|
||||
|
||||
.about-industry-badge:hover {
|
||||
border-color: var(--orange-100);
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
/* Company Details */
|
||||
.about-company-details {
|
||||
max-width: 700px;
|
||||
margin: 0 auto;
|
||||
background: rgba(255, 255, 255, 0.04);
|
||||
border: 1px solid rgba(255, 255, 255, 0.08);
|
||||
border-radius: 12px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.about-detail-row {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
padding: 1rem 1.5rem;
|
||||
border-bottom: 1px solid rgba(255, 255, 255, 0.06);
|
||||
}
|
||||
|
||||
.about-detail-row:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.about-detail-row span:first-child {
|
||||
color: var(--light-grey-100);
|
||||
opacity: 0.7;
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
|
||||
.about-detail-row span:last-child {
|
||||
color: #fff;
|
||||
font-weight: 500;
|
||||
font-size: 0.95rem;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.about-detail-row a {
|
||||
color: var(--orange-100);
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.about-detail-row a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
/* CTA */
|
||||
.about-cta-section {
|
||||
padding-bottom: 6rem;
|
||||
}
|
||||
|
||||
.about-cta {
|
||||
text-align: center;
|
||||
background: rgba(255, 91, 4, 0.08);
|
||||
border: 1px solid rgba(255, 91, 4, 0.2);
|
||||
border-radius: 20px;
|
||||
padding: 3.5rem 2rem;
|
||||
max-width: 700px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.about-cta h2 {
|
||||
font-size: 1.8rem;
|
||||
font-weight: 800;
|
||||
color: #fff;
|
||||
margin-bottom: 0.75rem;
|
||||
}
|
||||
|
||||
.about-cta p {
|
||||
color: var(--light-grey-100);
|
||||
font-size: 1.05rem;
|
||||
margin-bottom: 2rem;
|
||||
opacity: 0.85;
|
||||
}
|
||||
|
||||
.about-cta-btn {
|
||||
background: var(--orange-100);
|
||||
color: #fff;
|
||||
border: none;
|
||||
padding: 0.9rem 2.5rem;
|
||||
border-radius: 100px;
|
||||
font-size: 1rem;
|
||||
font-weight: 600;
|
||||
cursor: pointer;
|
||||
font-family: var(--font-primary);
|
||||
}
|
||||
|
||||
/* Responsive */
|
||||
@media (max-width: 900px) {
|
||||
.about-diff-grid {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
.about-values-grid {
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
}
|
||||
|
||||
.about-founder-card {
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.about-founder-details li {
|
||||
text-align: left;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 600px) {
|
||||
.about-page {
|
||||
padding-top: 6rem;
|
||||
}
|
||||
|
||||
.about-hero h1 {
|
||||
font-size: 2.2rem;
|
||||
}
|
||||
|
||||
.about-hero-sub {
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
.about-section {
|
||||
padding: 3rem 1rem;
|
||||
}
|
||||
|
||||
.about-values-grid {
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
}
|
||||
|
||||
.about-founder-card {
|
||||
padding: 1.5rem;
|
||||
}
|
||||
|
||||
.about-detail-row {
|
||||
flex-direction: column;
|
||||
gap: 0.25rem;
|
||||
}
|
||||
|
||||
.about-detail-row span:last-child {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.about-cta {
|
||||
padding: 2.5rem 1.5rem;
|
||||
}
|
||||
|
||||
.about-cta h2 {
|
||||
font-size: 1.4rem;
|
||||
}
|
||||
}
|
||||
275
src/pages/AboutPage.tsx
Normal file
275
src/pages/AboutPage.tsx
Normal file
|
|
@ -0,0 +1,275 @@
|
|||
import { useEffect, useState } from 'react';
|
||||
import { motion } from 'framer-motion';
|
||||
import { Helmet } from 'react-helmet-async';
|
||||
import SEO from '../components/SEO';
|
||||
import Modal from '../components/Modal';
|
||||
import ContactForm from '../components/ContactForm';
|
||||
import './AboutPage.css';
|
||||
|
||||
const fadeUp = {
|
||||
initial: { opacity: 0, y: 40 },
|
||||
whileInView: { opacity: 1, y: 0 },
|
||||
viewport: { once: true, margin: '-80px' },
|
||||
transition: { duration: 0.5 },
|
||||
};
|
||||
|
||||
const differentiators = [
|
||||
{
|
||||
icon: (
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round">
|
||||
<circle cx="12" cy="10" r="3"/><path d="M12 2a8 8 0 0 0-8 8c0 5.4 7 12 8 12s8-6.6 8-12a8 8 0 0 0-8-8z"/>
|
||||
</svg>
|
||||
),
|
||||
title: 'UK-Based, London Standards',
|
||||
desc: 'Competitive rates of £90–120/hr. UK business hours, GDPR-compliant by default, full accountability under English law.',
|
||||
},
|
||||
{
|
||||
icon: (
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round">
|
||||
<rect x="2" y="7" width="20" height="14" rx="2" ry="2"/><path d="M16 7V5a4 4 0 0 0-8 0v2"/>
|
||||
</svg>
|
||||
),
|
||||
title: 'SME Specialisation',
|
||||
desc: 'We focus on CRM, marketing, finance, and e-commerce automation — the workflows that matter most to growing businesses.',
|
||||
},
|
||||
{
|
||||
icon: (
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round">
|
||||
<rect x="3" y="11" width="18" height="11" rx="2" ry="2"/><path d="M7 11V7a5 5 0 0 1 10 0v4"/>
|
||||
</svg>
|
||||
),
|
||||
title: 'Client-Owned Infrastructure',
|
||||
desc: 'Your servers, your data, your accounts. We build on infrastructure you own — no vendor lock-in, no hostage situations.',
|
||||
},
|
||||
{
|
||||
icon: (
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round">
|
||||
<path d="M2 3h6a4 4 0 0 1 4 4v14a3 3 0 0 0-3-3H2z"/><path d="M22 3h-6a4 4 0 0 0-4 4v14a3 3 0 0 1 3-3h7z"/>
|
||||
</svg>
|
||||
),
|
||||
title: 'Knowledge Transfer, Not Dependency',
|
||||
desc: 'Every project includes full documentation and team training. We teach your people to maintain what we build.',
|
||||
},
|
||||
];
|
||||
|
||||
const values = [
|
||||
{ name: 'Transparency', desc: 'Fixed prices, clear scope, no hidden fees' },
|
||||
{ name: 'Client Ownership', desc: 'You own everything we build — code, data, infrastructure' },
|
||||
{ name: 'Excellence', desc: 'Enterprise-grade quality at SME-friendly prices' },
|
||||
{ name: 'Impact Over Profit', desc: 'Discounted rates for charities, startups, and public sector' },
|
||||
{ name: 'Pragmatism', desc: 'We recommend what works, not what costs more' },
|
||||
];
|
||||
|
||||
const industries = [
|
||||
'E-commerce', 'Professional Services', 'SaaS', 'Charities',
|
||||
'Education', 'Healthcare', 'Public Sector',
|
||||
];
|
||||
|
||||
const AboutPage = () => {
|
||||
useEffect(() => { window.scrollTo(0, 0); }, []);
|
||||
const [isModalOpen, setIsModalOpen] = useState(false);
|
||||
|
||||
return (
|
||||
<div className="about-page">
|
||||
<SEO
|
||||
title="About Us | AImpress — AI & Automation Consulting, London"
|
||||
description="AImpress Ltd is a London-based automation consultancy for SMEs, charities, and public sector. Founded 2024. Client-owned infrastructure, no vendor lock-in."
|
||||
url="https://ai-impress.com/about"
|
||||
/>
|
||||
<Helmet>
|
||||
<script type="application/ld+json">{JSON.stringify({
|
||||
'@context': 'https://schema.org',
|
||||
'@type': 'AboutPage',
|
||||
mainEntity: {
|
||||
'@type': 'Organization',
|
||||
name: 'AImpress Ltd',
|
||||
url: 'https://ai-impress.com',
|
||||
foundingDate: '2024',
|
||||
address: {
|
||||
'@type': 'PostalAddress',
|
||||
streetAddress: 'Suite 6065 Unit 3a, 34-35 Hatton Garden',
|
||||
addressLocality: 'London',
|
||||
postalCode: 'EC1N 8DX',
|
||||
addressCountry: 'GB',
|
||||
},
|
||||
},
|
||||
})}</script>
|
||||
</Helmet>
|
||||
|
||||
{/* Hero */}
|
||||
<section className="about-hero">
|
||||
<div className="container">
|
||||
<motion.h1 {...fadeUp}>About AImpress</motion.h1>
|
||||
<motion.p className="about-hero-sub" {...fadeUp} transition={{ duration: 0.5, delay: 0.1 }}>
|
||||
Making professional automation accessible to impact-driven organisations.
|
||||
</motion.p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Our Story */}
|
||||
<section className="about-section">
|
||||
<div className="container">
|
||||
<motion.div className="about-story" {...fadeUp}>
|
||||
<h2 className="section-title">Our Story</h2>
|
||||
<div className="about-story-text">
|
||||
<p>
|
||||
Automation is no longer optional — it's the difference between growing and getting left behind.
|
||||
Yet for most SMEs, the options have been limited: offshore teams that are cheap but unreliable,
|
||||
or UK agencies that charge enterprise prices for basic work.
|
||||
</p>
|
||||
<p>
|
||||
AImpress was founded to fill that gap. We're a London-based consultancy that brings
|
||||
enterprise-grade automation to small and medium businesses, charities, and public sector
|
||||
organisations — at prices that actually make sense.
|
||||
</p>
|
||||
<p>
|
||||
We don't believe in black-box solutions or vendor lock-in. Every system we build runs on
|
||||
infrastructure you own, with documentation your team can follow. When we leave, you keep
|
||||
everything — and you know how it works.
|
||||
</p>
|
||||
</div>
|
||||
</motion.div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* What Makes Us Different */}
|
||||
<section className="about-section">
|
||||
<div className="container">
|
||||
<motion.h2 className="section-title" {...fadeUp}>What Makes Us Different</motion.h2>
|
||||
<div className="about-diff-grid">
|
||||
{differentiators.map((d, i) => (
|
||||
<motion.div
|
||||
key={d.title}
|
||||
className="about-glass-card"
|
||||
initial={{ opacity: 0, y: 40 }}
|
||||
whileInView={{ opacity: 1, y: 0 }}
|
||||
viewport={{ once: true, margin: '-80px' }}
|
||||
transition={{ duration: 0.5, delay: i * 0.1 }}
|
||||
>
|
||||
<div className="about-card-icon">{d.icon}</div>
|
||||
<h3>{d.title}</h3>
|
||||
<p>{d.desc}</p>
|
||||
</motion.div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Our Values */}
|
||||
<section className="about-section">
|
||||
<div className="container">
|
||||
<motion.h2 className="section-title" {...fadeUp}>Our Values</motion.h2>
|
||||
<div className="about-values-grid">
|
||||
{values.map((v, i) => (
|
||||
<motion.div
|
||||
key={v.name}
|
||||
className="about-value-item"
|
||||
initial={{ opacity: 0, y: 30 }}
|
||||
whileInView={{ opacity: 1, y: 0 }}
|
||||
viewport={{ once: true, margin: '-60px' }}
|
||||
transition={{ duration: 0.4, delay: i * 0.08 }}
|
||||
>
|
||||
<h3>{v.name}</h3>
|
||||
<p>{v.desc}</p>
|
||||
</motion.div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Meet the Founder */}
|
||||
<section className="about-section">
|
||||
<div className="container">
|
||||
<motion.h2 className="section-title" {...fadeUp}>Meet the Founder</motion.h2>
|
||||
<motion.div className="about-founder-card" {...fadeUp}>
|
||||
<div className="about-founder-photo">
|
||||
<img src="/founder-danylo.jpeg" alt="Danylo — CEO & Founder of AImpress" className="about-founder-img" />
|
||||
</div>
|
||||
<div className="about-founder-info">
|
||||
<h3>Danylo</h3>
|
||||
<span className="about-founder-role">CEO & Founder of AImpress Ltd</span>
|
||||
<ul className="about-founder-details">
|
||||
<li>
|
||||
<strong>Background:</strong> 3+ years leading automation at OLIVER Agency (WPP),
|
||||
building enterprise-grade workflows for global brands
|
||||
</li>
|
||||
<li>
|
||||
<strong>Certifications:</strong> Microsoft Power BI Data Analyst, Laba Business Analytics
|
||||
& Marketing Analytics
|
||||
</li>
|
||||
<li>
|
||||
<strong>Education:</strong> Master's in Economic Cybernetics — systems modelling,
|
||||
data analysis, process optimisation
|
||||
</li>
|
||||
<li>
|
||||
<strong>Vision:</strong> Founded AImpress to bring enterprise-level automation to SMEs
|
||||
at accessible price points
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</motion.div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Industries We Serve */}
|
||||
<section className="about-section">
|
||||
<div className="container">
|
||||
<motion.h2 className="section-title" {...fadeUp}>Industries We Serve</motion.h2>
|
||||
<div className="about-industries">
|
||||
{industries.map((ind, i) => (
|
||||
<motion.span
|
||||
key={ind}
|
||||
className="about-industry-badge"
|
||||
initial={{ opacity: 0, scale: 0.9 }}
|
||||
whileInView={{ opacity: 1, scale: 1 }}
|
||||
viewport={{ once: true }}
|
||||
transition={{ duration: 0.3, delay: i * 0.06 }}
|
||||
>
|
||||
{ind}
|
||||
</motion.span>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Company Details */}
|
||||
<section className="about-section">
|
||||
<div className="container">
|
||||
<motion.h2 className="section-title" {...fadeUp}>Company Details</motion.h2>
|
||||
<motion.div className="about-company-details" {...fadeUp}>
|
||||
<div className="about-detail-row"><span>Legal Name</span><span>AImpress Ltd</span></div>
|
||||
<div className="about-detail-row"><span>Company Number</span><span>16417799 (England & Wales)</span></div>
|
||||
<div className="about-detail-row"><span>VAT Number</span><span>492173381</span></div>
|
||||
<div className="about-detail-row"><span>ICO Registration</span><span>ZB979660</span></div>
|
||||
<div className="about-detail-row"><span>Address</span><span>Suite 6065 Unit 3a, 34-35 Hatton Garden, London, EC1N 8DX</span></div>
|
||||
<div className="about-detail-row"><span>Email</span><span><a href="mailto:hello@ai-impress.com">hello@ai-impress.com</a></span></div>
|
||||
</motion.div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* CTA */}
|
||||
<section className="about-section about-cta-section">
|
||||
<div className="container">
|
||||
<motion.div className="about-cta" {...fadeUp}>
|
||||
<h2>Ready to Transform Your Operations?</h2>
|
||||
<p>Book a free discovery call and find out how automation can work for your business.</p>
|
||||
<motion.button
|
||||
className="about-cta-btn"
|
||||
onClick={() => setIsModalOpen(true)}
|
||||
whileHover={{ scale: 1.03 }}
|
||||
whileTap={{ scale: 0.97 }}
|
||||
>
|
||||
Book a Free Discovery Call
|
||||
</motion.button>
|
||||
</motion.div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<Modal isOpen={isModalOpen} onClose={() => setIsModalOpen(false)}>
|
||||
<ContactForm onClose={() => setIsModalOpen(false)} />
|
||||
</Modal>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default AboutPage;
|
||||
555
src/pages/PricingPage.css
Normal file
555
src/pages/PricingPage.css
Normal file
|
|
@ -0,0 +1,555 @@
|
|||
.pricing-page {
|
||||
padding-top: 8rem;
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
/* Hero */
|
||||
.pricing-hero {
|
||||
padding: 4rem 2rem 3rem;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.pricing-hero h1 {
|
||||
font-size: 3.2rem;
|
||||
font-weight: 800;
|
||||
color: #fff;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
.pricing-hero-sub {
|
||||
font-size: 1.2rem;
|
||||
color: var(--light-grey-100);
|
||||
opacity: 0.8;
|
||||
max-width: 600px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
/* Sections */
|
||||
.pricing-section {
|
||||
padding: 4rem 2rem;
|
||||
}
|
||||
|
||||
.pricing-section .section-title {
|
||||
text-align: center;
|
||||
font-size: 2rem;
|
||||
font-weight: 800;
|
||||
color: #fff;
|
||||
margin-bottom: 2.5rem;
|
||||
}
|
||||
|
||||
/* Implementation Pricing Table */
|
||||
.pricing-table-wrap {
|
||||
max-width: 800px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.pricing-table {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0;
|
||||
background: rgba(255, 255, 255, 0.04);
|
||||
border: 1px solid rgba(255, 255, 255, 0.08);
|
||||
border-radius: 14px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.pricing-table-row {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 1.1rem 1.5rem;
|
||||
border-bottom: 1px solid rgba(255, 255, 255, 0.06);
|
||||
}
|
||||
|
||||
.pricing-table-row:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.pricing-table-service {
|
||||
color: var(--light-grey-100);
|
||||
font-size: 0.95rem;
|
||||
}
|
||||
|
||||
.pricing-table-price {
|
||||
color: #fff;
|
||||
font-weight: 700;
|
||||
font-size: 0.95rem;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
/* Retainer Cards */
|
||||
.retainer-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
gap: 1.5rem;
|
||||
max-width: 1100px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.retainer-card {
|
||||
background: rgba(255, 255, 255, 0.05);
|
||||
backdrop-filter: blur(12px);
|
||||
border: 1px solid rgba(255, 255, 255, 0.1);
|
||||
border-radius: 16px;
|
||||
padding: 2rem;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.retainer-card--popular {
|
||||
border-color: var(--orange-100);
|
||||
}
|
||||
|
||||
.retainer-popular-badge {
|
||||
position: absolute;
|
||||
top: -12px;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
background: var(--orange-100);
|
||||
color: #fff;
|
||||
padding: 0.3rem 1rem;
|
||||
border-radius: 100px;
|
||||
font-size: 0.8rem;
|
||||
font-weight: 700;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.retainer-card h3 {
|
||||
font-size: 1.3rem;
|
||||
font-weight: 700;
|
||||
color: #fff;
|
||||
margin-bottom: 0.75rem;
|
||||
}
|
||||
|
||||
.retainer-price {
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
.retainer-amount {
|
||||
font-size: 2.2rem;
|
||||
font-weight: 900;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.retainer-period {
|
||||
color: var(--light-grey-100);
|
||||
font-size: 1rem;
|
||||
opacity: 0.7;
|
||||
}
|
||||
|
||||
.retainer-meta {
|
||||
display: flex;
|
||||
gap: 1rem;
|
||||
margin-bottom: 1.25rem;
|
||||
}
|
||||
|
||||
.retainer-meta span {
|
||||
background: rgba(255, 255, 255, 0.06);
|
||||
padding: 0.3rem 0.8rem;
|
||||
border-radius: 100px;
|
||||
font-size: 0.8rem;
|
||||
color: var(--light-grey-100);
|
||||
}
|
||||
|
||||
.retainer-features {
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
margin: 0 0 1.5rem 0;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.retainer-features li {
|
||||
color: var(--light-grey-100);
|
||||
font-size: 0.9rem;
|
||||
line-height: 1.5;
|
||||
padding: 0.35rem 0 0.35rem 1.2rem;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.retainer-features li::before {
|
||||
content: '✓';
|
||||
position: absolute;
|
||||
left: 0;
|
||||
color: var(--orange-100);
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.retainer-cta {
|
||||
display: inline-block;
|
||||
text-align: center;
|
||||
text-decoration: none;
|
||||
background: rgba(255, 91, 4, 0.15);
|
||||
color: var(--orange-100);
|
||||
border: 1px solid rgba(255, 91, 4, 0.3);
|
||||
padding: 0.7rem 1.5rem;
|
||||
border-radius: 100px;
|
||||
font-size: 0.9rem;
|
||||
font-weight: 600;
|
||||
cursor: pointer;
|
||||
transition: background 0.3s;
|
||||
font-family: var(--font-primary);
|
||||
}
|
||||
|
||||
.retainer-cta:hover {
|
||||
background: rgba(255, 91, 4, 0.25);
|
||||
}
|
||||
|
||||
.retainer-card--popular .retainer-cta {
|
||||
background: var(--orange-100);
|
||||
color: #fff;
|
||||
border-color: var(--orange-100);
|
||||
}
|
||||
|
||||
.retainer-card--popular .retainer-cta:hover {
|
||||
background: #e65200;
|
||||
}
|
||||
|
||||
/* Training */
|
||||
.training-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(4, 1fr);
|
||||
gap: 1.25rem;
|
||||
max-width: 1000px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.training-card {
|
||||
background: rgba(255, 255, 255, 0.04);
|
||||
border: 1px solid rgba(255, 255, 255, 0.08);
|
||||
border-radius: 12px;
|
||||
padding: 1.5rem;
|
||||
text-align: center;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.4rem;
|
||||
}
|
||||
|
||||
.training-card h3 {
|
||||
font-size: 0.95rem;
|
||||
font-weight: 700;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.training-price {
|
||||
font-size: 1.2rem;
|
||||
font-weight: 800;
|
||||
color: var(--orange-100);
|
||||
}
|
||||
|
||||
.training-desc {
|
||||
font-size: 0.8rem;
|
||||
color: var(--light-grey-100);
|
||||
opacity: 0.7;
|
||||
}
|
||||
|
||||
/* Payment Terms */
|
||||
.payment-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(4, 1fr);
|
||||
gap: 1.25rem;
|
||||
max-width: 1000px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.payment-card {
|
||||
background: rgba(255, 255, 255, 0.04);
|
||||
border: 1px solid rgba(255, 255, 255, 0.08);
|
||||
border-radius: 12px;
|
||||
padding: 1.5rem;
|
||||
}
|
||||
|
||||
.payment-card h3 {
|
||||
font-size: 0.95rem;
|
||||
font-weight: 700;
|
||||
color: #fff;
|
||||
margin-bottom: 0.3rem;
|
||||
}
|
||||
|
||||
.payment-card p {
|
||||
color: var(--light-grey-100);
|
||||
font-size: 0.85rem;
|
||||
margin-bottom: 0.75rem;
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
.payment-visual {
|
||||
display: flex;
|
||||
gap: 2px;
|
||||
border-radius: 6px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.payment-bar {
|
||||
background: var(--orange-100);
|
||||
color: #fff;
|
||||
font-size: 0.7rem;
|
||||
font-weight: 700;
|
||||
text-align: center;
|
||||
padding: 0.3rem 0;
|
||||
min-height: 24px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.payment-bar:nth-child(2) {
|
||||
background: rgba(255, 91, 4, 0.6);
|
||||
}
|
||||
|
||||
.payment-bar:nth-child(3) {
|
||||
background: rgba(255, 91, 4, 0.35);
|
||||
}
|
||||
|
||||
/* Discounts */
|
||||
.discount-block {
|
||||
background: rgba(255, 91, 4, 0.06);
|
||||
border: 1px solid rgba(255, 91, 4, 0.18);
|
||||
border-radius: 20px;
|
||||
padding: 2.5rem;
|
||||
max-width: 900px;
|
||||
margin: 0 auto;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.discount-block h2 {
|
||||
font-size: 1.6rem;
|
||||
font-weight: 800;
|
||||
color: #fff;
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
.discount-intro {
|
||||
color: var(--light-grey-100);
|
||||
font-size: 1rem;
|
||||
margin-bottom: 2rem;
|
||||
opacity: 0.85;
|
||||
}
|
||||
|
||||
.discount-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(5, 1fr);
|
||||
gap: 1rem;
|
||||
}
|
||||
|
||||
.discount-item {
|
||||
background: rgba(255, 255, 255, 0.05);
|
||||
border: 1px solid rgba(255, 255, 255, 0.1);
|
||||
border-radius: 12px;
|
||||
padding: 1.25rem 1rem;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.5rem;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.discount-group {
|
||||
color: var(--light-grey-100);
|
||||
font-size: 0.85rem;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.discount-amount {
|
||||
color: var(--orange-100);
|
||||
font-weight: 800;
|
||||
font-size: 1.1rem;
|
||||
}
|
||||
|
||||
/* Comparison Table */
|
||||
.comparison-table-wrap {
|
||||
max-width: 900px;
|
||||
margin: 0 auto;
|
||||
overflow-x: auto;
|
||||
}
|
||||
|
||||
.comparison-table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
|
||||
.comparison-table th,
|
||||
.comparison-table td {
|
||||
padding: 0.9rem 1.25rem;
|
||||
text-align: left;
|
||||
border-bottom: 1px solid rgba(255, 255, 255, 0.06);
|
||||
font-size: 0.95rem;
|
||||
color: var(--light-grey-100);
|
||||
}
|
||||
|
||||
.comparison-table th {
|
||||
color: #fff;
|
||||
font-weight: 700;
|
||||
font-size: 0.9rem;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.03em;
|
||||
background: rgba(255, 255, 255, 0.04);
|
||||
}
|
||||
|
||||
.comparison-table .comparison-highlight {
|
||||
color: var(--orange-100);
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.comparison-table th.comparison-highlight {
|
||||
color: var(--orange-100);
|
||||
}
|
||||
|
||||
.comparison-metric {
|
||||
color: #fff !important;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
/* FAQ */
|
||||
.faq-list {
|
||||
max-width: 800px;
|
||||
margin: 0 auto;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.5rem;
|
||||
}
|
||||
|
||||
.faq-item {
|
||||
background: rgba(255, 255, 255, 0.04);
|
||||
border: 1px solid rgba(255, 255, 255, 0.08);
|
||||
border-radius: 12px;
|
||||
overflow: hidden;
|
||||
transition: border-color 0.3s;
|
||||
}
|
||||
|
||||
.faq-item--open {
|
||||
border-color: rgba(255, 255, 255, 0.15);
|
||||
}
|
||||
|
||||
.faq-question {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 1.1rem 1.5rem;
|
||||
background: none;
|
||||
border: none;
|
||||
color: #fff;
|
||||
font-size: 1rem;
|
||||
font-weight: 600;
|
||||
cursor: pointer;
|
||||
text-align: left;
|
||||
font-family: var(--font-primary);
|
||||
}
|
||||
|
||||
.faq-question svg {
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
flex-shrink: 0;
|
||||
transition: transform 0.3s;
|
||||
color: var(--light-grey-100);
|
||||
}
|
||||
|
||||
.faq-answer {
|
||||
padding: 0 1.5rem 1.1rem;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.faq-answer p {
|
||||
color: var(--light-grey-100);
|
||||
font-size: 0.95rem;
|
||||
line-height: 1.7;
|
||||
opacity: 0.85;
|
||||
}
|
||||
|
||||
/* Quote Form CTA */
|
||||
.pricing-cta-section {
|
||||
padding-bottom: 6rem;
|
||||
}
|
||||
|
||||
.pricing-quote-subtitle {
|
||||
text-align: center;
|
||||
color: var(--light-grey-100);
|
||||
font-size: 1.05rem;
|
||||
opacity: 0.85;
|
||||
margin-top: -1.5rem;
|
||||
margin-bottom: 2.5rem;
|
||||
}
|
||||
|
||||
.pricing-quote-form-wrap {
|
||||
max-width: 800px;
|
||||
margin: 0 auto;
|
||||
background: rgba(255, 255, 255, 0.04);
|
||||
backdrop-filter: blur(12px);
|
||||
border: 1px solid rgba(255, 255, 255, 0.1);
|
||||
border-radius: 20px;
|
||||
padding: 2.5rem;
|
||||
}
|
||||
|
||||
/* Responsive */
|
||||
@media (max-width: 900px) {
|
||||
.retainer-grid {
|
||||
grid-template-columns: 1fr;
|
||||
max-width: 450px;
|
||||
}
|
||||
|
||||
.training-grid {
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
}
|
||||
|
||||
.payment-grid {
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
}
|
||||
|
||||
.discount-grid {
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 600px) {
|
||||
.pricing-page {
|
||||
padding-top: 6rem;
|
||||
}
|
||||
|
||||
.pricing-hero h1 {
|
||||
font-size: 2.2rem;
|
||||
}
|
||||
|
||||
.pricing-hero-sub {
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
.pricing-section {
|
||||
padding: 3rem 1rem;
|
||||
}
|
||||
|
||||
.pricing-table-row {
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
gap: 0.3rem;
|
||||
}
|
||||
|
||||
.retainer-grid {
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.training-grid {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
.payment-grid {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
.discount-block {
|
||||
padding: 1.5rem;
|
||||
}
|
||||
|
||||
.discount-grid {
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
}
|
||||
|
||||
.comparison-table th,
|
||||
.comparison-table td {
|
||||
padding: 0.6rem 0.75rem;
|
||||
font-size: 0.8rem;
|
||||
}
|
||||
|
||||
.pricing-quote-form-wrap {
|
||||
padding: 1.5rem;
|
||||
}
|
||||
}
|
||||
389
src/pages/PricingPage.tsx
Normal file
389
src/pages/PricingPage.tsx
Normal file
|
|
@ -0,0 +1,389 @@
|
|||
import { useEffect, useState } from 'react';
|
||||
import { motion } from 'framer-motion';
|
||||
import { Helmet } from 'react-helmet-async';
|
||||
import SEO from '../components/SEO';
|
||||
import QuoteForm from '../components/QuoteForm';
|
||||
import './PricingPage.css';
|
||||
|
||||
const fadeUp = {
|
||||
initial: { opacity: 0, y: 40 },
|
||||
whileInView: { opacity: 1, y: 0 },
|
||||
viewport: { once: true, margin: '-80px' },
|
||||
transition: { duration: 0.5 },
|
||||
};
|
||||
|
||||
const implementationPricing = [
|
||||
{ service: 'Workflow Automation Implementation', price: '£3,500 – £12,000' },
|
||||
{ service: 'System Integration & Synchronisation', price: '£2,500 – £10,000+' },
|
||||
{ service: 'CRM Workflow Optimisation', price: '£3,000 – £6,500' },
|
||||
{ service: 'Marketing Automation Setup', price: '£3,500 – £8,000' },
|
||||
{ service: 'AI Integration & Enhancement', price: '£4,000 – £12,000' },
|
||||
{ service: 'Infrastructure Setup & Configuration', price: '£1,500 – £4,000' },
|
||||
];
|
||||
|
||||
const retainerTiers = [
|
||||
{
|
||||
name: 'Essential',
|
||||
price: '£1,000',
|
||||
period: '/month',
|
||||
hours: '10 hours',
|
||||
sla: '48h response',
|
||||
features: [
|
||||
'10 hours of support',
|
||||
'Bug fixes & minor updates',
|
||||
'48-hour response SLA',
|
||||
'Email support',
|
||||
'Monthly health check',
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'Professional',
|
||||
price: '£2,000',
|
||||
period: '/month',
|
||||
hours: '22 hours',
|
||||
sla: '24h response',
|
||||
popular: true,
|
||||
features: [
|
||||
'22 hours of support',
|
||||
'Bug fixes, updates & new features',
|
||||
'24-hour response SLA',
|
||||
'Email + Slack support',
|
||||
'Bi-weekly strategy call',
|
||||
'Priority scheduling',
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'Enterprise',
|
||||
price: '£3,500',
|
||||
period: '/month',
|
||||
hours: '40 hours',
|
||||
sla: '4h response',
|
||||
features: [
|
||||
'40 hours of support',
|
||||
'Full-scope development & support',
|
||||
'4-hour response SLA',
|
||||
'Dedicated Slack channel',
|
||||
'Weekly strategy call',
|
||||
'Priority scheduling',
|
||||
'Quarterly roadmap review',
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
const training = [
|
||||
{ type: 'End-User Training', price: '£250', desc: 'Per session' },
|
||||
{ type: 'Admin Training', price: '£600 – £1,000', desc: 'Per session' },
|
||||
{ type: 'Certification Programme', price: '£1,800', desc: 'Full course' },
|
||||
{ type: 'Custom Workshop', price: '£400 – £1,200', desc: 'Half to full day' },
|
||||
];
|
||||
|
||||
const paymentTerms = [
|
||||
{ range: 'Under £5,000', split: '100% upfront', visual: [100] },
|
||||
{ range: '£5,000 – £10,000', split: '50% / 50%', visual: [50, 50] },
|
||||
{ range: 'Over £10,000', split: '33% / 33% / 34%', visual: [33, 33, 34] },
|
||||
{ range: 'Public Sector', split: 'Net 30 terms', visual: [100] },
|
||||
];
|
||||
|
||||
const discounts = [
|
||||
{ group: 'Charities & Non-Profits', discount: 'Up to 50%' },
|
||||
{ group: 'Startups (< 2 years)', discount: 'Up to 50%' },
|
||||
{ group: 'Education', discount: 'Up to 50%' },
|
||||
{ group: 'Public Sector', discount: '25% + free pilot project' },
|
||||
{ group: 'Ukrainian Businesses', discount: 'Up to 50%' },
|
||||
];
|
||||
|
||||
const comparison = [
|
||||
{ metric: 'Setup Cost', aimpress: 'From £1,500', agency: '£5,000+ /mo', inhouse: '£35,000+ /yr' },
|
||||
{ metric: 'Time to Deploy', aimpress: '2–8 weeks', agency: '3–6 months', inhouse: '6–12 months' },
|
||||
{ metric: 'Availability', aimpress: '24/7 automated', agency: 'Business hours', inhouse: '9-to-5 only' },
|
||||
{ metric: 'Scalability', aimpress: 'Unlimited', agency: 'Staff-limited', inhouse: 'Hard to scale' },
|
||||
{ metric: 'You Own It', aimpress: 'Yes, always', agency: 'Rarely', inhouse: 'Yes' },
|
||||
{ metric: 'Hidden Costs', aimpress: 'None', agency: 'Change requests', inhouse: 'Benefits, turnover' },
|
||||
];
|
||||
|
||||
const faq = [
|
||||
{
|
||||
q: 'Are you a UK company?',
|
||||
a: 'Yes. AImpress Ltd is registered in England & Wales (company number 16417799), VAT-registered, and ICO-registered. We operate under English law with full GDPR compliance.',
|
||||
},
|
||||
{
|
||||
q: 'Do you offer managed hosting?',
|
||||
a: 'We set up infrastructure on your own servers or cloud accounts. You own everything. We can provide ongoing management through our support retainers if needed.',
|
||||
},
|
||||
{
|
||||
q: 'What platforms do you work with?',
|
||||
a: 'We work with n8n, Make.com, Zapier, Power Automate, HubSpot, Salesforce, Pipedrive, Mailchimp, OpenAI, Claude, and many more. If your tool has an API, we can integrate it.',
|
||||
},
|
||||
{
|
||||
q: 'Can you work with our existing tools?',
|
||||
a: 'Absolutely. We build on top of your current stack — we don\'t rip and replace. Our goal is to connect and automate what you already have.',
|
||||
},
|
||||
{
|
||||
q: 'What if I don\'t qualify for a discount?',
|
||||
a: 'Our standard rates are already competitive at £90–120/hr — significantly below typical UK agency rates. We offer fixed-price projects so you always know the total cost upfront.',
|
||||
},
|
||||
{
|
||||
q: 'Do you work with clients outside the UK?',
|
||||
a: 'Yes, we work with international clients. Our primary focus is UK businesses, but we\'re happy to support companies anywhere that need professional automation consulting.',
|
||||
},
|
||||
];
|
||||
|
||||
const PricingPage = () => {
|
||||
useEffect(() => { window.scrollTo(0, 0); }, []);
|
||||
const [openFaq, setOpenFaq] = useState<number | null>(null);
|
||||
|
||||
return (
|
||||
<div className="pricing-page">
|
||||
<SEO
|
||||
title="Pricing | AImpress — Transparent Automation Costs from £1,500"
|
||||
description="Fixed-price automation projects from £1,500. Support retainers from £1,000/month. Up to 50% discount for charities, startups, and public sector."
|
||||
url="https://ai-impress.com/pricing"
|
||||
/>
|
||||
<Helmet>
|
||||
<script type="application/ld+json">{JSON.stringify({
|
||||
'@context': 'https://schema.org',
|
||||
'@type': 'WebPage',
|
||||
name: 'Pricing',
|
||||
description: 'AImpress automation pricing and service packages',
|
||||
offers: {
|
||||
'@type': 'AggregateOffer',
|
||||
priceCurrency: 'GBP',
|
||||
lowPrice: '1500',
|
||||
highPrice: '12000',
|
||||
offerCount: implementationPricing.length,
|
||||
},
|
||||
})}</script>
|
||||
</Helmet>
|
||||
|
||||
{/* Hero */}
|
||||
<section className="pricing-hero">
|
||||
<div className="container">
|
||||
<motion.h1 {...fadeUp}>Simple, Transparent Pricing</motion.h1>
|
||||
<motion.p className="pricing-hero-sub" {...fadeUp} transition={{ duration: 0.5, delay: 0.1 }}>
|
||||
Fixed-price projects. No surprise costs. No vendor lock-in.
|
||||
</motion.p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Implementation Pricing */}
|
||||
<section className="pricing-section">
|
||||
<div className="container">
|
||||
<motion.h2 className="section-title" {...fadeUp}>Implementation Pricing</motion.h2>
|
||||
<div className="pricing-table-wrap">
|
||||
<div className="pricing-table">
|
||||
{implementationPricing.map((item, i) => (
|
||||
<motion.div
|
||||
key={item.service}
|
||||
className="pricing-table-row"
|
||||
initial={{ opacity: 0, x: -20 }}
|
||||
whileInView={{ opacity: 1, x: 0 }}
|
||||
viewport={{ once: true }}
|
||||
transition={{ duration: 0.3, delay: i * 0.06 }}
|
||||
>
|
||||
<span className="pricing-table-service">{item.service}</span>
|
||||
<span className="pricing-table-price">{item.price}</span>
|
||||
</motion.div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Support Retainers */}
|
||||
<section className="pricing-section">
|
||||
<div className="container">
|
||||
<motion.h2 className="section-title" {...fadeUp}>Support Retainers</motion.h2>
|
||||
<div className="retainer-grid">
|
||||
{retainerTiers.map((tier, i) => (
|
||||
<motion.div
|
||||
key={tier.name}
|
||||
className={`retainer-card ${tier.popular ? 'retainer-card--popular' : ''}`}
|
||||
initial={{ opacity: 0, y: 40 }}
|
||||
whileInView={{ opacity: 1, y: 0 }}
|
||||
viewport={{ once: true, margin: '-60px' }}
|
||||
transition={{ duration: 0.5, delay: i * 0.1 }}
|
||||
>
|
||||
{tier.popular && <span className="retainer-popular-badge">Most Popular</span>}
|
||||
<h3>{tier.name}</h3>
|
||||
<div className="retainer-price">
|
||||
<span className="retainer-amount">{tier.price}</span>
|
||||
<span className="retainer-period">{tier.period}</span>
|
||||
</div>
|
||||
<div className="retainer-meta">
|
||||
<span>{tier.hours}</span>
|
||||
<span>{tier.sla}</span>
|
||||
</div>
|
||||
<ul className="retainer-features">
|
||||
{tier.features.map((f) => (
|
||||
<li key={f}>{f}</li>
|
||||
))}
|
||||
</ul>
|
||||
<a href="#get-quote" className="retainer-cta">
|
||||
Get Started
|
||||
</a>
|
||||
</motion.div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Training & Workshops */}
|
||||
<section className="pricing-section">
|
||||
<div className="container">
|
||||
<motion.h2 className="section-title" {...fadeUp}>Training & Workshops</motion.h2>
|
||||
<div className="training-grid">
|
||||
{training.map((t, i) => (
|
||||
<motion.div
|
||||
key={t.type}
|
||||
className="training-card"
|
||||
initial={{ opacity: 0, y: 30 }}
|
||||
whileInView={{ opacity: 1, y: 0 }}
|
||||
viewport={{ once: true }}
|
||||
transition={{ duration: 0.3, delay: i * 0.08 }}
|
||||
>
|
||||
<h3>{t.type}</h3>
|
||||
<span className="training-price">{t.price}</span>
|
||||
<span className="training-desc">{t.desc}</span>
|
||||
</motion.div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Payment Terms */}
|
||||
<section className="pricing-section">
|
||||
<div className="container">
|
||||
<motion.h2 className="section-title" {...fadeUp}>Payment Terms</motion.h2>
|
||||
<div className="payment-grid">
|
||||
{paymentTerms.map((pt, i) => (
|
||||
<motion.div
|
||||
key={pt.range}
|
||||
className="payment-card"
|
||||
initial={{ opacity: 0, y: 30 }}
|
||||
whileInView={{ opacity: 1, y: 0 }}
|
||||
viewport={{ once: true }}
|
||||
transition={{ duration: 0.3, delay: i * 0.08 }}
|
||||
>
|
||||
<h3>{pt.range}</h3>
|
||||
<p>{pt.split}</p>
|
||||
<div className="payment-visual">
|
||||
{pt.visual.map((pct, j) => (
|
||||
<div key={j} className="payment-bar" style={{ width: `${pct}%` }}>
|
||||
{pct}%
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</motion.div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Impact Grant (Discounts) */}
|
||||
<section className="pricing-section">
|
||||
<div className="container">
|
||||
<motion.div className="discount-block" {...fadeUp}>
|
||||
<h2>Impact Grant Programme</h2>
|
||||
<p className="discount-intro">We believe automation should be accessible to organisations making a difference. Eligible groups receive significant discounts.</p>
|
||||
<div className="discount-grid">
|
||||
{discounts.map((d, i) => (
|
||||
<motion.div
|
||||
key={d.group}
|
||||
className="discount-item"
|
||||
initial={{ opacity: 0, scale: 0.95 }}
|
||||
whileInView={{ opacity: 1, scale: 1 }}
|
||||
viewport={{ once: true }}
|
||||
transition={{ duration: 0.3, delay: i * 0.06 }}
|
||||
>
|
||||
<span className="discount-group">{d.group}</span>
|
||||
<span className="discount-amount">{d.discount}</span>
|
||||
</motion.div>
|
||||
))}
|
||||
</div>
|
||||
</motion.div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Comparison */}
|
||||
<section className="pricing-section">
|
||||
<div className="container">
|
||||
<motion.h2 className="section-title" {...fadeUp}>How We Compare</motion.h2>
|
||||
<motion.div className="comparison-table-wrap" {...fadeUp}>
|
||||
<table className="comparison-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th></th>
|
||||
<th className="comparison-highlight">AImpress</th>
|
||||
<th>Agency</th>
|
||||
<th>In-House</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{comparison.map((row) => (
|
||||
<tr key={row.metric}>
|
||||
<td className="comparison-metric">{row.metric}</td>
|
||||
<td className="comparison-highlight">{row.aimpress}</td>
|
||||
<td>{row.agency}</td>
|
||||
<td>{row.inhouse}</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
</motion.div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* FAQ */}
|
||||
<section className="pricing-section">
|
||||
<div className="container">
|
||||
<motion.h2 className="section-title" {...fadeUp}>Frequently Asked Questions</motion.h2>
|
||||
<div className="faq-list">
|
||||
{faq.map((item, i) => (
|
||||
<motion.div
|
||||
key={i}
|
||||
className={`faq-item ${openFaq === i ? 'faq-item--open' : ''}`}
|
||||
initial={{ opacity: 0, y: 20 }}
|
||||
whileInView={{ opacity: 1, y: 0 }}
|
||||
viewport={{ once: true }}
|
||||
transition={{ duration: 0.3, delay: i * 0.06 }}
|
||||
>
|
||||
<button className="faq-question" onClick={() => setOpenFaq(openFaq === i ? null : i)}>
|
||||
<span>{item.q}</span>
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" style={{ transform: openFaq === i ? 'rotate(180deg)' : 'rotate(0)' }}>
|
||||
<polyline points="6 9 12 15 18 9"/>
|
||||
</svg>
|
||||
</button>
|
||||
{openFaq === i && (
|
||||
<motion.div
|
||||
className="faq-answer"
|
||||
initial={{ opacity: 0, height: 0 }}
|
||||
animate={{ opacity: 1, height: 'auto' }}
|
||||
transition={{ duration: 0.3 }}
|
||||
>
|
||||
<p>{item.a}</p>
|
||||
</motion.div>
|
||||
)}
|
||||
</motion.div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Quote Form CTA */}
|
||||
<section className="pricing-section pricing-cta-section" id="get-quote">
|
||||
<div className="container">
|
||||
<motion.h2 className="section-title" {...fadeUp}>Get Your Quote Today</motion.h2>
|
||||
<motion.p className="pricing-quote-subtitle" {...fadeUp} transition={{ duration: 0.5, delay: 0.1 }}>
|
||||
Tell us about your project and we'll send you a detailed, fixed-price proposal within 24 hours.
|
||||
</motion.p>
|
||||
<motion.div className="pricing-quote-form-wrap" {...fadeUp} transition={{ duration: 0.5, delay: 0.15 }}>
|
||||
<QuoteForm />
|
||||
</motion.div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default PricingPage;
|
||||
379
src/pages/ServicesPage.css
Normal file
379
src/pages/ServicesPage.css
Normal file
|
|
@ -0,0 +1,379 @@
|
|||
.services-page {
|
||||
padding-top: 8rem;
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
/* Hero */
|
||||
.services-hero {
|
||||
padding: 4rem 2rem 3rem;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.services-hero h1 {
|
||||
font-size: 3.2rem;
|
||||
font-weight: 800;
|
||||
color: #fff;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
.services-hero-sub {
|
||||
font-size: 1.2rem;
|
||||
color: var(--light-grey-100);
|
||||
opacity: 0.8;
|
||||
max-width: 600px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
/* Sections */
|
||||
.services-section {
|
||||
padding: 4rem 2rem;
|
||||
}
|
||||
|
||||
.services-section .section-title {
|
||||
text-align: center;
|
||||
font-size: 2rem;
|
||||
font-weight: 800;
|
||||
color: #fff;
|
||||
margin-bottom: 2.5rem;
|
||||
}
|
||||
|
||||
/* Service Cards Grid */
|
||||
.services-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
gap: 1.5rem;
|
||||
max-width: 1100px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.service-card {
|
||||
background: rgba(255, 255, 255, 0.05);
|
||||
backdrop-filter: blur(12px);
|
||||
border: 1px solid rgba(255, 255, 255, 0.1);
|
||||
border-radius: 16px;
|
||||
padding: 2rem;
|
||||
cursor: pointer;
|
||||
transition: border-color 0.3s, transform 0.2s;
|
||||
}
|
||||
|
||||
.service-card:hover {
|
||||
border-color: rgba(255, 255, 255, 0.2);
|
||||
}
|
||||
|
||||
.service-card--expanded {
|
||||
border-color: var(--orange-100);
|
||||
}
|
||||
|
||||
.service-card-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
.service-card-icon {
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
color: var(--orange-100);
|
||||
}
|
||||
|
||||
.service-card-icon svg {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.service-card-price {
|
||||
background: rgba(255, 91, 4, 0.12);
|
||||
color: var(--orange-100);
|
||||
padding: 0.35rem 0.9rem;
|
||||
border-radius: 100px;
|
||||
font-size: 0.85rem;
|
||||
font-weight: 600;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.service-card h3 {
|
||||
font-size: 1.15rem;
|
||||
font-weight: 700;
|
||||
color: #fff;
|
||||
margin-bottom: 0.6rem;
|
||||
}
|
||||
|
||||
.service-card-purpose {
|
||||
color: var(--light-grey-100);
|
||||
font-size: 0.95rem;
|
||||
line-height: 1.6;
|
||||
opacity: 0.85;
|
||||
margin-bottom: 0.75rem;
|
||||
}
|
||||
|
||||
.service-card-includes {
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
margin: 0.75rem 0;
|
||||
border-top: 1px solid rgba(255, 255, 255, 0.08);
|
||||
padding-top: 0.75rem;
|
||||
}
|
||||
|
||||
.service-card-includes li {
|
||||
color: var(--light-grey-100);
|
||||
font-size: 0.9rem;
|
||||
line-height: 1.5;
|
||||
padding: 0.35rem 0 0.35rem 1.2rem;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.service-card-includes li::before {
|
||||
content: '✓';
|
||||
position: absolute;
|
||||
left: 0;
|
||||
color: var(--orange-100);
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.service-card-toggle {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 0.4rem;
|
||||
color: var(--orange-100);
|
||||
font-size: 0.85rem;
|
||||
font-weight: 600;
|
||||
margin-top: 0.5rem;
|
||||
}
|
||||
|
||||
.service-card-toggle svg {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
transition: transform 0.3s;
|
||||
}
|
||||
|
||||
/* Assurance Pack */
|
||||
.assurance-pack {
|
||||
background: rgba(255, 91, 4, 0.06);
|
||||
border: 1px solid rgba(255, 91, 4, 0.18);
|
||||
border-radius: 20px;
|
||||
padding: 2.5rem;
|
||||
max-width: 1000px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.assurance-header {
|
||||
text-align: center;
|
||||
margin-bottom: 2rem;
|
||||
}
|
||||
|
||||
.assurance-header h2 {
|
||||
font-size: 1.6rem;
|
||||
font-weight: 800;
|
||||
color: #fff;
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
.assurance-badge {
|
||||
display: inline-block;
|
||||
background: rgba(255, 91, 4, 0.15);
|
||||
color: var(--orange-100);
|
||||
padding: 0.4rem 1.2rem;
|
||||
border-radius: 100px;
|
||||
font-size: 0.9rem;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.assurance-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
gap: 0.75rem;
|
||||
}
|
||||
|
||||
.assurance-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.6rem;
|
||||
padding: 0.5rem 0;
|
||||
}
|
||||
|
||||
.assurance-item svg {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.assurance-item span {
|
||||
color: var(--light-grey-100);
|
||||
font-size: 0.95rem;
|
||||
}
|
||||
|
||||
/* Process Steps */
|
||||
.process-steps {
|
||||
max-width: 800px;
|
||||
margin: 0 auto;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 1.5rem;
|
||||
}
|
||||
|
||||
.process-step {
|
||||
display: flex;
|
||||
gap: 1.5rem;
|
||||
align-items: flex-start;
|
||||
background: rgba(255, 255, 255, 0.04);
|
||||
border: 1px solid rgba(255, 255, 255, 0.08);
|
||||
border-radius: 14px;
|
||||
padding: 1.5rem;
|
||||
}
|
||||
|
||||
.process-step-number {
|
||||
font-size: 2rem;
|
||||
font-weight: 900;
|
||||
color: var(--orange-100);
|
||||
opacity: 0.7;
|
||||
line-height: 1;
|
||||
flex-shrink: 0;
|
||||
width: 50px;
|
||||
}
|
||||
|
||||
.process-step-content h3 {
|
||||
font-size: 1.1rem;
|
||||
font-weight: 700;
|
||||
color: #fff;
|
||||
margin-bottom: 0.4rem;
|
||||
}
|
||||
|
||||
.process-step-content p {
|
||||
color: var(--light-grey-100);
|
||||
font-size: 0.95rem;
|
||||
line-height: 1.6;
|
||||
opacity: 0.85;
|
||||
}
|
||||
|
||||
/* Tech Stack */
|
||||
.tech-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(4, 1fr);
|
||||
gap: 1rem;
|
||||
max-width: 1000px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.tech-card {
|
||||
background: rgba(255, 255, 255, 0.04);
|
||||
border: 1px solid rgba(255, 255, 255, 0.08);
|
||||
border-radius: 12px;
|
||||
padding: 1.25rem;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.tech-card h3 {
|
||||
font-size: 0.85rem;
|
||||
font-weight: 700;
|
||||
color: var(--orange-100);
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.05em;
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
.tech-card p {
|
||||
color: var(--light-grey-100);
|
||||
font-size: 0.85rem;
|
||||
line-height: 1.5;
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
/* CTA */
|
||||
.services-cta-section {
|
||||
padding-bottom: 6rem;
|
||||
}
|
||||
|
||||
.services-cta {
|
||||
text-align: center;
|
||||
background: rgba(255, 91, 4, 0.08);
|
||||
border: 1px solid rgba(255, 91, 4, 0.2);
|
||||
border-radius: 20px;
|
||||
padding: 3.5rem 2rem;
|
||||
max-width: 700px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.services-cta h2 {
|
||||
font-size: 1.8rem;
|
||||
font-weight: 800;
|
||||
color: #fff;
|
||||
margin-bottom: 0.75rem;
|
||||
}
|
||||
|
||||
.services-cta p {
|
||||
color: var(--light-grey-100);
|
||||
font-size: 1.05rem;
|
||||
margin-bottom: 2rem;
|
||||
opacity: 0.85;
|
||||
}
|
||||
|
||||
.services-cta-btn {
|
||||
background: var(--orange-100);
|
||||
color: #fff;
|
||||
border: none;
|
||||
padding: 0.9rem 2.5rem;
|
||||
border-radius: 100px;
|
||||
font-size: 1rem;
|
||||
font-weight: 600;
|
||||
cursor: pointer;
|
||||
font-family: var(--font-primary);
|
||||
}
|
||||
|
||||
/* Responsive */
|
||||
@media (max-width: 900px) {
|
||||
.services-grid {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
.assurance-grid {
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
}
|
||||
|
||||
.tech-grid {
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 600px) {
|
||||
.services-page {
|
||||
padding-top: 6rem;
|
||||
}
|
||||
|
||||
.services-hero h1 {
|
||||
font-size: 2.2rem;
|
||||
}
|
||||
|
||||
.services-hero-sub {
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
.services-section {
|
||||
padding: 3rem 1rem;
|
||||
}
|
||||
|
||||
.assurance-pack {
|
||||
padding: 1.5rem;
|
||||
}
|
||||
|
||||
.assurance-grid {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
.tech-grid {
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
}
|
||||
|
||||
.process-step {
|
||||
flex-direction: column;
|
||||
gap: 0.75rem;
|
||||
}
|
||||
|
||||
.services-cta {
|
||||
padding: 2.5rem 1.5rem;
|
||||
}
|
||||
|
||||
.services-cta h2 {
|
||||
font-size: 1.4rem;
|
||||
}
|
||||
}
|
||||
353
src/pages/ServicesPage.tsx
Normal file
353
src/pages/ServicesPage.tsx
Normal file
|
|
@ -0,0 +1,353 @@
|
|||
import { useEffect, useState } from 'react';
|
||||
import { motion } from 'framer-motion';
|
||||
import { Helmet } from 'react-helmet-async';
|
||||
import SEO from '../components/SEO';
|
||||
import Modal from '../components/Modal';
|
||||
import ContactForm from '../components/ContactForm';
|
||||
import './ServicesPage.css';
|
||||
|
||||
const fadeUp = {
|
||||
initial: { opacity: 0, y: 40 },
|
||||
whileInView: { opacity: 1, y: 0 },
|
||||
viewport: { once: true, margin: '-80px' },
|
||||
transition: { duration: 0.5 },
|
||||
};
|
||||
|
||||
const services = [
|
||||
{
|
||||
icon: (
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round">
|
||||
<polyline points="22 12 18 12 15 21 9 3 6 12 2 12"/>
|
||||
</svg>
|
||||
),
|
||||
title: 'Workflow Automation Implementation',
|
||||
price: '£3,500 – £12,000',
|
||||
purpose: 'Automate repetitive business processes end-to-end so your team focuses on high-value work.',
|
||||
includes: [
|
||||
'Process discovery & mapping',
|
||||
'Custom workflow design & build (n8n / Make.com)',
|
||||
'Multi-step logic with conditional branching',
|
||||
'Error handling & retry mechanisms',
|
||||
'Testing, deployment & documentation',
|
||||
],
|
||||
},
|
||||
{
|
||||
icon: (
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round">
|
||||
<path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"/>
|
||||
<polyline points="15 3 21 3 21 9"/><line x1="10" y1="14" x2="21" y2="3"/>
|
||||
</svg>
|
||||
),
|
||||
title: 'System Integration & Synchronisation',
|
||||
price: '£2,500 – £10,000+',
|
||||
purpose: 'Connect your tools into a single source of truth — CRM, accounting, e-commerce, comms, and more.',
|
||||
includes: [
|
||||
'API integration between platforms',
|
||||
'Bi-directional data sync',
|
||||
'Data mapping & transformation',
|
||||
'Webhook & event-driven triggers',
|
||||
'Monitoring & alerting setup',
|
||||
],
|
||||
},
|
||||
{
|
||||
icon: (
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round">
|
||||
<path d="M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2"/>
|
||||
<circle cx="9" cy="7" r="4"/><path d="M23 21v-2a4 4 0 0 0-3-3.87"/>
|
||||
<path d="M16 3.13a4 4 0 0 1 0 7.75"/>
|
||||
</svg>
|
||||
),
|
||||
title: 'CRM Workflow Optimisation',
|
||||
price: '£3,000 – £6,500',
|
||||
purpose: 'Streamline your sales pipeline, automate follow-ups, and ensure no lead falls through the cracks.',
|
||||
includes: [
|
||||
'CRM audit & pipeline restructure',
|
||||
'Automated lead scoring & routing',
|
||||
'Email sequence automation',
|
||||
'Task & reminder workflows',
|
||||
'Reporting dashboard setup',
|
||||
],
|
||||
},
|
||||
{
|
||||
icon: (
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round">
|
||||
<path d="M4 4h16c1.1 0 2 .9 2 2v12c0 1.1-.9 2-2 2H4c-1.1 0-2-.9-2-2V6c0-1.1.9-2 2-2z"/>
|
||||
<polyline points="22,6 12,13 2,6"/>
|
||||
</svg>
|
||||
),
|
||||
title: 'Marketing Automation Setup',
|
||||
price: '£3,500 – £8,000',
|
||||
purpose: 'Put your campaigns, lead nurturing, and ads on autopilot with targeted, data-driven automation.',
|
||||
includes: [
|
||||
'Email drip campaign setup',
|
||||
'Lead capture & form automation',
|
||||
'Audience segmentation logic',
|
||||
'Social media scheduling integration',
|
||||
'Analytics & conversion tracking',
|
||||
],
|
||||
},
|
||||
{
|
||||
icon: (
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round">
|
||||
<polygon points="13 2 3 14 12 14 11 22 21 10 12 10 13 2"/>
|
||||
</svg>
|
||||
),
|
||||
title: 'AI Integration & Enhancement',
|
||||
price: '£4,000 – £12,000',
|
||||
purpose: 'Add AI capabilities to your existing workflows — chatbots, content generation, document processing, and more.',
|
||||
includes: [
|
||||
'AI model selection & integration (OpenAI, Claude, etc.)',
|
||||
'Custom chatbot / virtual assistant build',
|
||||
'Document & data extraction with AI',
|
||||
'AI-powered content generation pipelines',
|
||||
'Prompt engineering & fine-tuning',
|
||||
],
|
||||
},
|
||||
{
|
||||
icon: (
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round">
|
||||
<rect x="2" y="3" width="20" height="14" rx="2" ry="2"/>
|
||||
<line x1="8" y1="21" x2="16" y2="21"/><line x1="12" y1="17" x2="12" y2="21"/>
|
||||
</svg>
|
||||
),
|
||||
title: 'Infrastructure Setup & Configuration',
|
||||
price: '£1,500 – £4,000',
|
||||
purpose: 'Set up your automation infrastructure on servers you own — secure, scalable, and fully yours.',
|
||||
includes: [
|
||||
'Server provisioning (VPS / cloud)',
|
||||
'n8n / automation platform deployment',
|
||||
'SSL, firewall & security hardening',
|
||||
'Backup & recovery configuration',
|
||||
'Monitoring & uptime alerting',
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
const assurancePack = [
|
||||
'Dedicated project manager',
|
||||
'Weekly progress reports',
|
||||
'Full technical documentation',
|
||||
'End-user training session',
|
||||
'Admin training session',
|
||||
'30-day post-launch support',
|
||||
'Bug fixes within SLA',
|
||||
'Knowledge base & runbooks',
|
||||
'Handover & transition plan',
|
||||
];
|
||||
|
||||
const processSteps = [
|
||||
{ step: '01', title: 'Discovery', desc: 'Free consultation to understand your goals, audit current workflows, and identify automation opportunities.' },
|
||||
{ step: '02', title: 'Proposal & Scope', desc: 'Detailed project plan with fixed pricing, timelines, and deliverables. No surprises.' },
|
||||
{ step: '03', title: 'Development', desc: 'We build and iterate on your automations with regular check-ins and progress demos.' },
|
||||
{ step: '04', title: 'Testing & Launch', desc: 'Rigorous QA, UAT with your team, and a smooth go-live with monitoring in place.' },
|
||||
{ step: '05', title: 'Post-Launch Support', desc: '30 days of included support, team training, full documentation, and optional retainer.' },
|
||||
];
|
||||
|
||||
const techStack = [
|
||||
{ category: 'Workflow', tools: 'n8n, Make.com, Zapier, Power Automate' },
|
||||
{ category: 'CRM', tools: 'HubSpot, Salesforce, Pipedrive, Zoho' },
|
||||
{ category: 'Marketing', tools: 'Mailchimp, ActiveCampaign, Brevo, Meta Ads' },
|
||||
{ category: 'AI', tools: 'OpenAI, Claude, Google AI, Whisper, LangChain' },
|
||||
{ category: 'Infrastructure', tools: 'AWS, Hetzner, Docker, Nginx, Cloudflare' },
|
||||
{ category: 'Analytics', tools: 'Power BI, Google Analytics, Mixpanel, Looker' },
|
||||
{ category: 'Communication', tools: 'Slack, Teams, Twilio, WhatsApp Business' },
|
||||
];
|
||||
|
||||
const ServicesPage = () => {
|
||||
useEffect(() => { window.scrollTo(0, 0); }, []);
|
||||
const [isModalOpen, setIsModalOpen] = useState(false);
|
||||
const [expandedCard, setExpandedCard] = useState<number | null>(null);
|
||||
|
||||
return (
|
||||
<div className="services-page">
|
||||
<SEO
|
||||
title="AI & Automation Services for UK Businesses | AImpress"
|
||||
description="Workflow automation, system integration, CRM optimisation, marketing automation, AI integration, and infrastructure setup. Fixed-price projects from £1,500."
|
||||
url="https://ai-impress.com/services"
|
||||
/>
|
||||
<Helmet>
|
||||
<script type="application/ld+json">{JSON.stringify({
|
||||
'@context': 'https://schema.org',
|
||||
'@type': 'Service',
|
||||
provider: {
|
||||
'@type': 'Organization',
|
||||
name: 'AImpress Ltd',
|
||||
url: 'https://ai-impress.com',
|
||||
},
|
||||
serviceType: 'AI & Automation Consulting',
|
||||
areaServed: 'GB',
|
||||
hasOfferCatalog: {
|
||||
'@type': 'OfferCatalog',
|
||||
name: 'Automation Services',
|
||||
itemListElement: services.map((s, i) => ({
|
||||
'@type': 'Offer',
|
||||
itemOffered: {
|
||||
'@type': 'Service',
|
||||
name: s.title,
|
||||
description: s.purpose,
|
||||
},
|
||||
position: i + 1,
|
||||
})),
|
||||
},
|
||||
})}</script>
|
||||
</Helmet>
|
||||
|
||||
{/* Hero */}
|
||||
<section className="services-hero">
|
||||
<div className="container">
|
||||
<motion.h1 {...fadeUp}>Our Services</motion.h1>
|
||||
<motion.p className="services-hero-sub" {...fadeUp} transition={{ duration: 0.5, delay: 0.1 }}>
|
||||
End-to-end automation consulting — from discovery to deployment and beyond.
|
||||
</motion.p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Service Cards */}
|
||||
<section className="services-section">
|
||||
<div className="container">
|
||||
<div className="services-grid">
|
||||
{services.map((s, i) => {
|
||||
const isExpanded = expandedCard === i;
|
||||
return (
|
||||
<motion.div
|
||||
key={s.title}
|
||||
className={`service-card ${isExpanded ? 'service-card--expanded' : ''}`}
|
||||
initial={{ opacity: 0, y: 40 }}
|
||||
whileInView={{ opacity: 1, y: 0 }}
|
||||
viewport={{ once: true, margin: '-60px' }}
|
||||
transition={{ duration: 0.5, delay: i * 0.08 }}
|
||||
onClick={() => setExpandedCard(isExpanded ? null : i)}
|
||||
>
|
||||
<div className="service-card-header">
|
||||
<div className="service-card-icon">{s.icon}</div>
|
||||
<div className="service-card-price">{s.price}</div>
|
||||
</div>
|
||||
<h3>{s.title}</h3>
|
||||
<p className="service-card-purpose">{s.purpose}</p>
|
||||
{isExpanded && (
|
||||
<motion.ul
|
||||
className="service-card-includes"
|
||||
initial={{ opacity: 0, height: 0 }}
|
||||
animate={{ opacity: 1, height: 'auto' }}
|
||||
transition={{ duration: 0.3 }}
|
||||
>
|
||||
{s.includes.map((item) => (
|
||||
<li key={item}>{item}</li>
|
||||
))}
|
||||
</motion.ul>
|
||||
)}
|
||||
<span className="service-card-toggle">
|
||||
{isExpanded ? 'Show less' : 'What\'s included'}
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" style={{ transform: isExpanded ? 'rotate(180deg)' : 'rotate(0)' }}>
|
||||
<polyline points="6 9 12 15 18 9"/>
|
||||
</svg>
|
||||
</span>
|
||||
</motion.div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Assurance Pack */}
|
||||
<section className="services-section">
|
||||
<div className="container">
|
||||
<motion.div className="assurance-pack" {...fadeUp}>
|
||||
<div className="assurance-header">
|
||||
<h2>AImpress Assurance Pack</h2>
|
||||
<span className="assurance-badge">Included free in every project (value £1,500)</span>
|
||||
</div>
|
||||
<div className="assurance-grid">
|
||||
{assurancePack.map((item, i) => (
|
||||
<motion.div
|
||||
key={item}
|
||||
className="assurance-item"
|
||||
initial={{ opacity: 0, x: -20 }}
|
||||
whileInView={{ opacity: 1, x: 0 }}
|
||||
viewport={{ once: true }}
|
||||
transition={{ duration: 0.3, delay: i * 0.05 }}
|
||||
>
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="var(--orange-100)" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round">
|
||||
<polyline points="20 6 9 17 4 12"/>
|
||||
</svg>
|
||||
<span>{item}</span>
|
||||
</motion.div>
|
||||
))}
|
||||
</div>
|
||||
</motion.div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* How We Work */}
|
||||
<section className="services-section">
|
||||
<div className="container">
|
||||
<motion.h2 className="section-title" {...fadeUp}>How We Work</motion.h2>
|
||||
<div className="process-steps">
|
||||
{processSteps.map((s, i) => (
|
||||
<motion.div
|
||||
key={s.step}
|
||||
className="process-step"
|
||||
initial={{ opacity: 0, y: 30 }}
|
||||
whileInView={{ opacity: 1, y: 0 }}
|
||||
viewport={{ once: true, margin: '-60px' }}
|
||||
transition={{ duration: 0.4, delay: i * 0.1 }}
|
||||
>
|
||||
<div className="process-step-number">{s.step}</div>
|
||||
<div className="process-step-content">
|
||||
<h3>{s.title}</h3>
|
||||
<p>{s.desc}</p>
|
||||
</div>
|
||||
</motion.div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Technology Stack */}
|
||||
<section className="services-section">
|
||||
<div className="container">
|
||||
<motion.h2 className="section-title" {...fadeUp}>Technology Stack</motion.h2>
|
||||
<div className="tech-grid">
|
||||
{techStack.map((t, i) => (
|
||||
<motion.div
|
||||
key={t.category}
|
||||
className="tech-card"
|
||||
initial={{ opacity: 0, scale: 0.95 }}
|
||||
whileInView={{ opacity: 1, scale: 1 }}
|
||||
viewport={{ once: true }}
|
||||
transition={{ duration: 0.3, delay: i * 0.06 }}
|
||||
>
|
||||
<h3>{t.category}</h3>
|
||||
<p>{t.tools}</p>
|
||||
</motion.div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* CTA */}
|
||||
<section className="services-section services-cta-section">
|
||||
<div className="container">
|
||||
<motion.div className="services-cta" {...fadeUp}>
|
||||
<h2>Not Sure Where to Start?</h2>
|
||||
<p>Book a free consultation and we'll map out the best automation strategy for your business.</p>
|
||||
<motion.button
|
||||
className="services-cta-btn"
|
||||
onClick={() => setIsModalOpen(true)}
|
||||
whileHover={{ scale: 1.03 }}
|
||||
whileTap={{ scale: 0.97 }}
|
||||
>
|
||||
Get Your Free Consultation
|
||||
</motion.button>
|
||||
</motion.div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<Modal isOpen={isModalOpen} onClose={() => setIsModalOpen(false)}>
|
||||
<ContactForm onClose={() => setIsModalOpen(false)} />
|
||||
</Modal>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default ServicesPage;
|
||||
Loading…
Add table
Reference in a new issue