refactor: replace hardcoded hex colors with design system tokens
Replace all hardcoded hex color values in components with Tailwind CSS classes or CSS custom properties matching the design system tokens. Affected files: Footer, TestimonialsColumn, HeroSection, StarIcon, TextHoverEffect, and all page-level radial-gradient backgrounds. Also fix eslint.config.mjs to use FlatCompat for eslint-config-next legacy config compatibility with ESLint 9 flat config format, and resolve pre-existing react/no-unescaped-entities errors in JSX files. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
9785c0997e
commit
8db56af042
12 changed files with 2283 additions and 16 deletions
|
|
@ -1,18 +1,15 @@
|
|||
import { defineConfig, globalIgnores } from 'eslint/config';
|
||||
import nextVitals from 'eslint-config-next/core-web-vitals';
|
||||
import nextTs from 'eslint-config-next/typescript';
|
||||
import eslintrcPkg from '/Volumes/SSD/Projects/Clients/Axil Accountants/node_modules/.pnpm/@eslint+eslintrc@3.3.3/node_modules/@eslint/eslintrc/dist/eslintrc.cjs';
|
||||
import { dirname } from 'path';
|
||||
import { fileURLToPath } from 'url';
|
||||
|
||||
const eslintConfig = defineConfig([
|
||||
...nextVitals,
|
||||
...nextTs,
|
||||
// Override default ignores of eslint-config-next.
|
||||
globalIgnores([
|
||||
// Default ignores of eslint-config-next:
|
||||
'.next/**',
|
||||
'out/**',
|
||||
'build/**',
|
||||
'next-env.d.ts',
|
||||
]),
|
||||
]);
|
||||
const { FlatCompat } = eslintrcPkg;
|
||||
const __filename = fileURLToPath(import.meta.url);
|
||||
const __dirname = dirname(__filename);
|
||||
|
||||
export default eslintConfig;
|
||||
const compat = new FlatCompat({
|
||||
baseDirectory: __dirname,
|
||||
});
|
||||
|
||||
export default [
|
||||
...compat.extends('next/core-web-vitals', 'next/typescript'),
|
||||
];
|
||||
|
|
|
|||
241
src/app/about/page.tsx
Normal file
241
src/app/about/page.tsx
Normal file
|
|
@ -0,0 +1,241 @@
|
|||
import type { Metadata } from 'next';
|
||||
import Link from 'next/link';
|
||||
import { Header } from '@/components/layout/Header';
|
||||
import { Footer } from '@/components/layout/Footer';
|
||||
import { Button } from '@/components/ui/Button';
|
||||
import { FadeIn } from '@/components/ui/FadeIn';
|
||||
import { SpotlightCard } from '@/components/ui/SpotlightCard';
|
||||
import { CheckCircleIcon } from '@/components/ui/icons';
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: 'About Us — Axil Accountants',
|
||||
description:
|
||||
'Meet the team behind Axil Accountants. ICAEW-certified accountants helping 500+ UK businesses grow since 2012.',
|
||||
};
|
||||
|
||||
const VALUES = [
|
||||
{
|
||||
title: 'Transparency',
|
||||
desc: "Fixed monthly fees with zero hidden charges. You always know exactly what you're paying and what you're getting.",
|
||||
},
|
||||
{
|
||||
title: 'Proactivity',
|
||||
desc: "We don't wait for problems to appear. We monitor your finances and flag issues before they become expensive surprises.",
|
||||
},
|
||||
{
|
||||
title: 'Plain English',
|
||||
desc: 'No jargon. No confusing tax speak. We explain everything in language that actually makes sense for business owners.',
|
||||
},
|
||||
{
|
||||
title: 'Accountability',
|
||||
desc: 'Your dedicated account manager is reachable when you need them — not hidden behind a call centre or ticket queue.',
|
||||
},
|
||||
];
|
||||
|
||||
const TEAM = [
|
||||
{
|
||||
name: 'James Whitfield',
|
||||
role: 'Founder & Senior Accountant',
|
||||
qual: 'ICAEW · ACA',
|
||||
bg: '1B9AD6',
|
||||
},
|
||||
{ name: 'Priya Sharma', role: 'Head of Tax', qual: 'ACCA · CTA', bg: '3CC68A' },
|
||||
{ name: 'Tom Aldridge', role: 'Payroll & VAT Specialist', qual: 'ATT', bg: '27A870' },
|
||||
];
|
||||
|
||||
const STATS = [
|
||||
{ value: '500+', label: 'Clients served' },
|
||||
{ value: '£2M+', label: 'Tax saved for clients' },
|
||||
{ value: '98%', label: 'Client retention rate' },
|
||||
{ value: '2012', label: 'Year founded' },
|
||||
];
|
||||
|
||||
export default function AboutPage() {
|
||||
return (
|
||||
<>
|
||||
<Header />
|
||||
<main>
|
||||
{/* Hero */}
|
||||
<section className="bg-bg relative overflow-hidden pt-32 pb-20">
|
||||
<div className="pointer-events-none absolute inset-0 bg-[radial-gradient(ellipse_60%_50%_at_50%_0%,var(--color-emerald-mist)_0%,transparent_70%)]" />
|
||||
<div className="relative mx-auto max-w-[1440px] px-4 sm:px-6 lg:px-8 xl:px-16">
|
||||
<FadeIn>
|
||||
<div className="mx-auto max-w-3xl text-center">
|
||||
<p className="text-emerald mb-3 text-sm font-semibold tracking-widest uppercase">
|
||||
About Axil
|
||||
</p>
|
||||
<h1 className="font-display text-charcoal mb-6 text-4xl font-bold tracking-tight sm:text-5xl lg:text-6xl">
|
||||
The accountants who work as hard as you do
|
||||
</h1>
|
||||
<p className="text-muted mb-8 text-xl leading-relaxed">
|
||||
Founded in 2012, Axil Accountants set out to do one thing differently: make
|
||||
professional accounting accessible, affordable, and genuinely useful for every UK
|
||||
business owner.
|
||||
</p>
|
||||
<Button size="lg" trailingArrow>
|
||||
Book a Free Consultation
|
||||
</Button>
|
||||
</div>
|
||||
</FadeIn>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Mission */}
|
||||
<section className="bg-white py-24">
|
||||
<div className="mx-auto max-w-[1440px] px-4 sm:px-6 lg:px-8 xl:px-16">
|
||||
<div className="grid grid-cols-1 gap-16 lg:grid-cols-2 lg:items-center">
|
||||
<FadeIn>
|
||||
<p className="text-emerald mb-3 text-sm font-semibold tracking-widest uppercase">
|
||||
Our mission
|
||||
</p>
|
||||
<h2 className="font-display text-charcoal mb-6 text-3xl font-bold sm:text-4xl">
|
||||
We believe every business deserves great accounting
|
||||
</h2>
|
||||
<p className="text-muted mb-4 text-lg leading-relaxed">
|
||||
For too long, small and medium UK businesses have been underserved by accounting
|
||||
firms that are too big to care, or too small to be reliable. Axil was built to
|
||||
fill that gap.
|
||||
</p>
|
||||
<p className="text-muted mb-8 text-lg leading-relaxed">
|
||||
We combine the expertise and rigour of a top-tier firm with the personal service
|
||||
and accessibility that growing businesses actually need. Your dedicated account
|
||||
manager knows your business by name, not by number.
|
||||
</p>
|
||||
<div className="space-y-3">
|
||||
{[
|
||||
'ICAEW Member firm',
|
||||
'ACCA Certified team',
|
||||
'Fixed monthly pricing',
|
||||
'No lock-in contracts',
|
||||
].map((item) => (
|
||||
<div key={item} className="flex items-center gap-2.5">
|
||||
<CheckCircleIcon size={16} color="var(--emerald)" />
|
||||
<span className="text-charcoal text-base font-medium">{item}</span>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</FadeIn>
|
||||
|
||||
<FadeIn delay={0.15} x={40}>
|
||||
<div className="grid grid-cols-2 gap-4">
|
||||
{STATS.map((s) => (
|
||||
<div
|
||||
key={s.label}
|
||||
className="rounded-hero bg-bg border border-black/8 p-6 text-center"
|
||||
>
|
||||
<p className="font-display text-emerald mb-1 text-4xl font-bold">{s.value}</p>
|
||||
<p className="text-muted text-sm">{s.label}</p>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</FadeIn>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Values */}
|
||||
<section className="bg-bg py-24">
|
||||
<div className="mx-auto max-w-[1440px] px-4 sm:px-6 lg:px-8 xl:px-16">
|
||||
<FadeIn>
|
||||
<div className="mb-14 text-center">
|
||||
<p className="text-emerald mb-3 text-sm font-semibold tracking-widest uppercase">
|
||||
What we stand for
|
||||
</p>
|
||||
<h2 className="font-display text-charcoal text-3xl font-bold sm:text-4xl">
|
||||
Our values
|
||||
</h2>
|
||||
</div>
|
||||
</FadeIn>
|
||||
|
||||
<div className="grid grid-cols-1 gap-6 sm:grid-cols-2 lg:grid-cols-4">
|
||||
{VALUES.map((v, i) => (
|
||||
<FadeIn key={v.title} delay={i * 0.1}>
|
||||
<SpotlightCard className="h-full p-6" glowColor="green" customSize>
|
||||
<div className="rounded-card bg-emerald-mist mb-3 flex size-10 items-center justify-center">
|
||||
<span className="font-display text-emerald text-lg font-bold">{i + 1}</span>
|
||||
</div>
|
||||
<h3 className="font-display text-charcoal mb-2 text-lg font-semibold">
|
||||
{v.title}
|
||||
</h3>
|
||||
<p className="text-muted text-sm leading-relaxed">{v.desc}</p>
|
||||
</SpotlightCard>
|
||||
</FadeIn>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Team */}
|
||||
<section id="team" className="bg-white py-24">
|
||||
<div className="mx-auto max-w-[1440px] px-4 sm:px-6 lg:px-8 xl:px-16">
|
||||
<FadeIn>
|
||||
<div className="mb-14 text-center">
|
||||
<p className="text-emerald mb-3 text-sm font-semibold tracking-widest uppercase">
|
||||
The people
|
||||
</p>
|
||||
<h2 className="font-display text-charcoal text-3xl font-bold sm:text-4xl">
|
||||
Meet your team
|
||||
</h2>
|
||||
<p className="text-muted mx-auto mt-4 max-w-xl text-lg">
|
||||
Every Axil client has a dedicated account manager. These are the experts behind
|
||||
your finances.
|
||||
</p>
|
||||
</div>
|
||||
</FadeIn>
|
||||
|
||||
<div className="grid grid-cols-1 gap-6 sm:grid-cols-3">
|
||||
{TEAM.map((member, i) => (
|
||||
<FadeIn key={member.name} delay={i * 0.1}>
|
||||
<SpotlightCard className="p-6 text-center" glowColor="green" customSize>
|
||||
<img
|
||||
src={`https://ui-avatars.com/api/?name=${encodeURIComponent(member.name)}&background=${member.bg}&color=fff&bold=true&size=120`}
|
||||
alt={member.name}
|
||||
width={80}
|
||||
height={80}
|
||||
className="mx-auto mb-4 size-20 rounded-full"
|
||||
/>
|
||||
<h3 className="font-display text-charcoal mb-0.5 text-lg font-semibold">
|
||||
{member.name}
|
||||
</h3>
|
||||
<p className="text-muted mb-2 text-sm">{member.role}</p>
|
||||
<span className="rounded-pill bg-emerald-mist text-emerald px-3 py-1 text-xs font-semibold">
|
||||
{member.qual}
|
||||
</span>
|
||||
</SpotlightCard>
|
||||
</FadeIn>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* CTA */}
|
||||
<section className="bg-charcoal py-24">
|
||||
<div className="mx-auto max-w-[1440px] px-4 text-center sm:px-6 lg:px-8 xl:px-16">
|
||||
<FadeIn>
|
||||
<h2 className="font-display mb-4 text-3xl font-bold text-white sm:text-4xl">
|
||||
Ready to work with us?
|
||||
</h2>
|
||||
<p className="mx-auto mb-8 max-w-xl text-lg text-white/70">
|
||||
Book a free consultation and find out how Axil can save your business time, money
|
||||
and stress.
|
||||
</p>
|
||||
<div className="flex flex-wrap justify-center gap-3">
|
||||
<Button size="lg" trailingArrow>
|
||||
Book Free Consultation
|
||||
</Button>
|
||||
<Button
|
||||
size="lg"
|
||||
variant="secondary"
|
||||
className="border-white/30 text-white hover:bg-white/10"
|
||||
>
|
||||
<Link href="/contact">Contact Us</Link>
|
||||
</Button>
|
||||
</div>
|
||||
</FadeIn>
|
||||
</div>
|
||||
</section>
|
||||
</main>
|
||||
<Footer />
|
||||
</>
|
||||
);
|
||||
}
|
||||
438
src/app/blog/[slug]/page.tsx
Normal file
438
src/app/blog/[slug]/page.tsx
Normal file
|
|
@ -0,0 +1,438 @@
|
|||
import type { Metadata } from 'next';
|
||||
import Link from 'next/link';
|
||||
import { notFound } from 'next/navigation';
|
||||
import { Header } from '@/components/layout/Header';
|
||||
import { Footer } from '@/components/layout/Footer';
|
||||
import { Button } from '@/components/ui/Button';
|
||||
import { FadeIn } from '@/components/ui/FadeIn';
|
||||
import { SpotlightCard } from '@/components/ui/SpotlightCard';
|
||||
import { Tag } from '@/components/ui/Tag';
|
||||
|
||||
const POSTS: Record<
|
||||
string,
|
||||
{
|
||||
slug: string;
|
||||
category: string;
|
||||
categoryColor: 'green' | 'blue';
|
||||
date: string;
|
||||
readTime: string;
|
||||
title: string;
|
||||
excerpt: string;
|
||||
author: string;
|
||||
authorRole: string;
|
||||
authorBg: string;
|
||||
content: { heading: string; body: string }[];
|
||||
}
|
||||
> = {
|
||||
'hmrc-making-tax-digital-guide': {
|
||||
slug: 'hmrc-making-tax-digital-guide',
|
||||
category: 'Tax',
|
||||
categoryColor: 'green',
|
||||
date: '12 Feb 2025',
|
||||
readTime: '6 min',
|
||||
title: 'Making Tax Digital: Everything UK Business Owners Need to Know',
|
||||
excerpt:
|
||||
"MTD is now mandatory for most VAT-registered businesses. Here's what it means for you and how to make sure you're compliant.",
|
||||
author: 'Priya Sharma',
|
||||
authorRole: 'Head of Tax · ACCA · CTA',
|
||||
authorBg: '3CC68A',
|
||||
content: [
|
||||
{
|
||||
heading: 'What is Making Tax Digital?',
|
||||
body: "Making Tax Digital (MTD) is HMRC's initiative to move the UK tax system online. The goal is to reduce errors, improve record-keeping, and make it easier for businesses to stay on top of their tax affairs. For most VAT-registered businesses with a taxable turnover above the VAT threshold (£85,000), MTD for VAT has been mandatory since April 2019.",
|
||||
},
|
||||
{
|
||||
heading: 'Who Does MTD Affect?',
|
||||
body: 'From April 2022, MTD for VAT was extended to all VAT-registered businesses — even those voluntarily registered below the threshold. If you submit a VAT return, you must use MTD-compatible software to keep digital records and submit returns. MTD for Income Tax Self Assessment (ITSA) is the next phase, expected to roll out from April 2026 for sole traders and landlords with income over £50,000.',
|
||||
},
|
||||
{
|
||||
heading: 'What Do You Need to Do?',
|
||||
body: 'The key requirements are simple: keep digital records of all VAT transactions, use MTD-compatible software (such as Xero, QuickBooks, Sage or FreeAgent), and submit your VAT returns directly through that software. Paper records and manual spreadsheets alone are no longer acceptable — though a bridging solution that converts spreadsheet data to digital submissions is permitted.',
|
||||
},
|
||||
{
|
||||
heading: 'Penalties for Non-Compliance',
|
||||
body: "HMRC introduced a new points-based penalty system in January 2023. Each late submission earns one penalty point. When you hit a threshold (4 points for quarterly filers), you'll receive a £200 fine — plus £200 for every subsequent late submission. Separate penalties apply for late payment of VAT: 2% of unpaid VAT after 15 days, rising to 4% after 30 days, then 4% per annum thereafter.",
|
||||
},
|
||||
{
|
||||
heading: 'How Axil Can Help',
|
||||
body: "At Axil, we set up and manage MTD-compliant bookkeeping for all our clients as standard. We use cloud accounting software to keep your records up to date and handle VAT submissions on your behalf — so you're always compliant and never miss a deadline. If you're not sure whether you're currently compliant, get in touch for a free review.",
|
||||
},
|
||||
],
|
||||
},
|
||||
'limited-company-vs-sole-trader': {
|
||||
slug: 'limited-company-vs-sole-trader',
|
||||
category: 'Business',
|
||||
categoryColor: 'blue',
|
||||
date: '28 Jan 2025',
|
||||
readTime: '8 min',
|
||||
title: 'Limited Company vs Sole Trader: Which Is Right for Your Business?',
|
||||
excerpt:
|
||||
'One of the most common questions from new business owners. We break down the tax implications, liability and admin for both structures.',
|
||||
author: 'James Whitfield',
|
||||
authorRole: 'Founder & Senior Accountant · ICAEW · ACA',
|
||||
authorBg: '1B9AD6',
|
||||
content: [
|
||||
{
|
||||
heading: 'The Core Difference',
|
||||
body: 'A sole trader is the simplest business structure: you and your business are legally the same entity. A limited company, on the other hand, is a separate legal entity from its owners (shareholders and directors). This distinction has far-reaching implications for tax, liability, and administration.',
|
||||
},
|
||||
{
|
||||
heading: 'Tax: Sole Trader',
|
||||
body: "As a sole trader, your profits are taxed as personal income through Self Assessment. You'll pay Income Tax at 20%, 40% or 45% depending on your earnings, plus Class 2 and Class 4 National Insurance contributions. The simplicity is a genuine advantage at lower income levels — you'll spend less on accountancy fees and have fewer filing obligations.",
|
||||
},
|
||||
{
|
||||
heading: 'Tax: Limited Company',
|
||||
body: 'A limited company pays Corporation Tax on its profits — currently 19% for profits up to £50,000, rising to 25% for profits over £250,000 (with marginal relief in between). Directors typically pay themselves a combination of salary (up to the NI threshold) and dividends, which are taxed at lower rates than income. This can result in significant tax savings once profits exceed roughly £30,000–£40,000.',
|
||||
},
|
||||
{
|
||||
heading: 'Liability',
|
||||
body: "This is where limited companies offer a major advantage. As a sole trader, you're personally liable for all business debts — creditors can pursue your personal assets (home, savings) if the business fails. A limited company's liability is limited to the share capital, protecting your personal assets. Note that banks often require personal guarantees on business loans, which can reduce this protection.",
|
||||
},
|
||||
{
|
||||
heading: 'Administration',
|
||||
body: 'Sole trader: one Self Assessment tax return per year, straightforward record-keeping. Limited company: annual accounts filed with Companies House, Confirmation Statement, Corporation Tax return, potentially VAT returns and payroll (PAYE). The admin burden is genuinely higher — which is why a good accountant is especially valuable for limited company owners.',
|
||||
},
|
||||
{
|
||||
heading: 'Our Recommendation',
|
||||
body: "For most self-employed people earning under £30,000, sole trader is the most practical choice. Above £50,000 in consistent annual profit, the tax savings of a limited company usually outweigh the additional admin costs. Between those figures, it depends on your circumstances, risk tolerance, and growth plans. Book a free consultation and we'll run the numbers for your specific situation.",
|
||||
},
|
||||
],
|
||||
},
|
||||
'self-assessment-tips-2025': {
|
||||
slug: 'self-assessment-tips-2025',
|
||||
category: 'Tax',
|
||||
categoryColor: 'green',
|
||||
date: '10 Jan 2025',
|
||||
readTime: '7 min',
|
||||
title: '10 Self-Assessment Tips That Could Save You Thousands',
|
||||
excerpt:
|
||||
"Filing your self-assessment tax return? These allowances and deductions are commonly missed — even by people who've been filing for years.",
|
||||
author: 'Priya Sharma',
|
||||
authorRole: 'Head of Tax · ACCA · CTA',
|
||||
authorBg: '3CC68A',
|
||||
content: [
|
||||
{
|
||||
heading: '1. Claim Your Full Trading Allowance',
|
||||
body: "The £1,000 trading allowance lets you earn up to £1,000 from self-employment without paying tax on it. If your gross trading income is under £1,000, you don't even need to file a return for that income. If it's over £1,000, you can simply deduct £1,000 instead of calculating actual expenses — useful if your expenses are modest.",
|
||||
},
|
||||
{
|
||||
heading: "2. Don't Forget the Marriage Allowance",
|
||||
body: "If you're married or in a civil partnership and one of you earns below the Personal Allowance (£12,570), you can transfer up to £1,260 of unused allowance to the higher earner — potentially saving up to £252 per year. You can also backdate claims up to 4 years.",
|
||||
},
|
||||
{
|
||||
heading: '3. Claim All Allowable Business Expenses',
|
||||
body: 'Many self-employed people underclaim expenses. Allowable costs include: office costs (stationery, phone bills), travel expenses (not commuting), clothing (uniforms only), staff costs, advertising and marketing, professional fees (accountants, solicitors), and premises costs. If you work from home, you can claim a proportion of household bills.',
|
||||
},
|
||||
{
|
||||
heading: '4. Use Your Capital Gains Tax Allowance',
|
||||
body: "The Capital Gains Tax annual exempt amount is £3,000 for 2024/25. If you've sold assets (shares, property that isn't your main home, business assets) and made a profit, make sure you're factoring in this allowance. Couples can also effectively double their allowance by transferring assets between spouses before selling.",
|
||||
},
|
||||
{
|
||||
heading: '5. Pension Contributions Reduce Your Tax Bill',
|
||||
body: "Pension contributions get tax relief at your marginal rate. If you're a higher-rate taxpayer, a £1,000 pension contribution only costs you £600 after tax relief. You can contribute up to 100% of your earnings (up to £60,000 per year) and carry forward unused allowance from the previous 3 tax years.",
|
||||
},
|
||||
{
|
||||
heading: '6. Check Your National Insurance Record',
|
||||
body: 'Gaps in your NI record reduce your State Pension entitlement. You need 35 qualifying years for the full new State Pension (currently £221.20/week). Check your record at the Government Gateway and consider making voluntary Class 3 contributions to fill gaps — this is often an excellent return on investment.',
|
||||
},
|
||||
],
|
||||
},
|
||||
'r-and-d-tax-credits-explained': {
|
||||
slug: 'r-and-d-tax-credits-explained',
|
||||
category: 'Tax',
|
||||
categoryColor: 'blue',
|
||||
date: '15 Dec 2024',
|
||||
readTime: '5 min',
|
||||
title: 'R&D Tax Credits: Are You Leaving Money on the Table?',
|
||||
excerpt:
|
||||
'Many UK businesses qualify for R&D tax credits without realising it. Find out if your business is eligible and how much you could claim.',
|
||||
author: 'James Whitfield',
|
||||
authorRole: 'Founder & Senior Accountant · ICAEW · ACA',
|
||||
authorBg: '1B9AD6',
|
||||
content: [
|
||||
{
|
||||
heading: 'What Are R&D Tax Credits?',
|
||||
body: 'Research and Development (R&D) tax credits are a government incentive designed to reward UK companies that invest in innovation. If your business has worked to develop new products, processes or services — or improve existing ones — you may be able to claim a significant tax saving or cash payment from HMRC.',
|
||||
},
|
||||
{
|
||||
heading: "You Probably Qualify (Even If You Don't Think So)",
|
||||
body: "The definition of R&D for tax purposes is broader than most people realise. You don't need a laboratory or a team of scientists. If your business has worked to overcome a technical challenge where the solution wasn't readily available — even in software development, manufacturing, food production or construction — that may well qualify.",
|
||||
},
|
||||
{
|
||||
heading: 'How Much Can You Claim?',
|
||||
body: "From April 2024, most companies fall under the merged R&D scheme. You can claim an enhanced deduction of 186% of qualifying R&D costs — meaning £100 of R&D spending becomes £186 of deductible costs. Loss-making companies can surrender losses for a cash credit at 10% (or up to 14.5% if you're an R&D-intensive SME with 30%+ qualifying expenditure).",
|
||||
},
|
||||
{
|
||||
heading: 'What Costs Qualify?',
|
||||
body: 'Qualifying costs include: staff costs (salaries, NI, pension contributions) for those directly involved in R&D; subcontractor costs (at 65%); software and consumables used directly in the R&D process; and externally provided workers. Your accountant can help identify all claimable costs — many businesses significantly underestimate their eligible expenditure.',
|
||||
},
|
||||
{
|
||||
heading: 'How to Claim',
|
||||
body: "R&D tax credits are claimed through your Corporation Tax return (CT600). You'll need to submit a technical narrative describing the R&D activities, plus a financial breakdown. HMRC scrutiny has increased since 2023, so it's important to have proper documentation. At Axil, we've successfully submitted R&D claims across multiple sectors — get in touch to see if you qualify.",
|
||||
},
|
||||
],
|
||||
},
|
||||
'payroll-auto-enrolment-guide': {
|
||||
slug: 'payroll-auto-enrolment-guide',
|
||||
category: 'Payroll',
|
||||
categoryColor: 'green',
|
||||
date: '2 Dec 2024',
|
||||
readTime: '6 min',
|
||||
title: 'Auto-Enrolment in 2025: A Plain English Guide for Employers',
|
||||
excerpt:
|
||||
"Auto-enrolment pension duties catch many small employers off guard. Here's everything you need to know to stay compliant.",
|
||||
author: 'Tom Aldridge',
|
||||
authorRole: 'Payroll & VAT Specialist · ATT',
|
||||
authorBg: '27A870',
|
||||
content: [
|
||||
{
|
||||
heading: 'What Is Auto-Enrolment?',
|
||||
body: 'Auto-enrolment is the legal requirement for employers to automatically enrol eligible workers into a workplace pension scheme and make employer contributions. Introduced in 2012, it now applies to virtually all employers in the UK — even if you only have one member of staff.',
|
||||
},
|
||||
{
|
||||
heading: 'Who Must Be Enrolled?',
|
||||
body: 'You must automatically enrol employees who are: aged between 22 and State Pension age, earning above £10,000 per year, and working in the UK. Workers earning between £6,240 and £10,000 can opt in (and you must still contribute if they do). Workers earning under £6,240 can join voluntarily but employer contributions are not required.',
|
||||
},
|
||||
{
|
||||
heading: 'Minimum Contribution Rates',
|
||||
body: 'The current minimum total contribution is 8% of qualifying earnings (the band between £6,240 and £50,270 per year). At minimum, you as the employer must contribute at least 3%, with the employee making up the remainder (at least 5%). You can contribute more if you choose — and many employers offer enhanced contributions as a staff benefit.',
|
||||
},
|
||||
{
|
||||
heading: 'Choosing a Pension Scheme',
|
||||
body: "You'll need to choose a pension scheme that meets the qualifying criteria. NEST (National Employment Savings Trust) is the government-backed scheme and accepts all employers. Other popular options include The People's Pension, Aviva, and Royal London. The scheme must meet minimum standards set by The Pensions Regulator.",
|
||||
},
|
||||
{
|
||||
heading: 'Re-Enrolment and Declaration of Compliance',
|
||||
body: 'Every three years, you must re-enrol any eligible workers who have opted out — this is called re-enrolment. You must also submit a Declaration of Compliance to The Pensions Regulator within 5 months of your re-enrolment date. Missing this can result in fixed penalty notices starting at £400, rising to £10,000 per day for larger employers.',
|
||||
},
|
||||
],
|
||||
},
|
||||
'cash-flow-tips-small-business': {
|
||||
slug: 'cash-flow-tips-small-business',
|
||||
category: 'Finance',
|
||||
categoryColor: 'blue',
|
||||
date: '18 Nov 2024',
|
||||
readTime: '5 min',
|
||||
title: '7 Cash Flow Strategies Every Small Business Should Use',
|
||||
excerpt:
|
||||
'Cash flow problems are the number one reason small businesses fail. These practical strategies will help you stay ahead of the curve.',
|
||||
author: 'James Whitfield',
|
||||
authorRole: 'Founder & Senior Accountant · ICAEW · ACA',
|
||||
authorBg: '1B9AD6',
|
||||
content: [
|
||||
{
|
||||
heading: '1. Invoice Immediately and Chase Promptly',
|
||||
body: "The moment you complete work, send the invoice. Don't batch invoices at month-end — every day of delay is cash you don't have. Set up automatic payment reminders at 7, 14 and 30 days overdue. Most late payments are the result of invoices falling through the cracks rather than deliberate non-payment.",
|
||||
},
|
||||
{
|
||||
heading: '2. Shorten Your Payment Terms',
|
||||
body: 'Many businesses default to 30-day payment terms out of habit. Consider switching to 14 days — or even 7 days for smaller clients. Better still, require payment upfront for new clients and smaller projects. Most clients will accept whatever terms you set from the outset; the key is to be clear and consistent.',
|
||||
},
|
||||
{
|
||||
heading: '3. Build a 3-Month Cash Reserve',
|
||||
body: 'A cash buffer equal to 3 months of operating expenses gives you breathing room to handle slow-paying clients, seasonal dips, or unexpected costs without crisis. Build it gradually by setting aside a percentage of every payment received. Treat it as an operating cost, not savings.',
|
||||
},
|
||||
{
|
||||
heading: '4. Negotiate Extended Terms With Suppliers',
|
||||
body: 'While you work to get paid faster, you should simultaneously try to pay suppliers more slowly (within your agreed terms). If you currently pay on 14 days, ask your main suppliers if 30 or 45 days is possible. This stretches your cash cycle without damaging relationships.',
|
||||
},
|
||||
{
|
||||
heading: '5. Use a Cash Flow Forecast',
|
||||
body: "A simple 13-week rolling cash flow forecast tells you exactly when you'll be tight — and gives you time to act before you're in trouble. Most cloud accounting packages have built-in forecasting tools. At Axil, we build and maintain cash flow forecasts for our clients as part of our standard service.",
|
||||
},
|
||||
{
|
||||
heading: '6. Review Your Pricing',
|
||||
body: "Underpricing is one of the most common causes of cash flow problems. If your margins are thin, there's no buffer when costs rise or revenue dips. Review your pricing annually. Factor in all costs including your own time, overheads, tax, and a reasonable profit margin — not just direct costs.",
|
||||
},
|
||||
{
|
||||
heading: '7. Consider Invoice Finance',
|
||||
body: "If you work with large clients on long payment cycles, invoice finance (factoring or discounting) lets you unlock up to 90% of invoice value immediately, with the finance company collecting payment on your behalf. It's not right for every business, but for B2B service businesses with slow-paying clients, it can transform cash flow.",
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
|
||||
const RELATED_POSTS = [
|
||||
{
|
||||
slug: 'hmrc-making-tax-digital-guide',
|
||||
category: 'Tax',
|
||||
color: 'green' as const,
|
||||
title: 'Making Tax Digital: Everything UK Business Owners Need to Know',
|
||||
date: '12 Feb 2025',
|
||||
},
|
||||
{
|
||||
slug: 'limited-company-vs-sole-trader',
|
||||
category: 'Business',
|
||||
color: 'blue' as const,
|
||||
title: 'Limited Company vs Sole Trader: Which Is Right for Your Business?',
|
||||
date: '28 Jan 2025',
|
||||
},
|
||||
{
|
||||
slug: 'self-assessment-tips-2025',
|
||||
category: 'Tax',
|
||||
color: 'green' as const,
|
||||
title: '10 Self-Assessment Tips That Could Save You Thousands',
|
||||
date: '10 Jan 2025',
|
||||
},
|
||||
];
|
||||
|
||||
export async function generateStaticParams() {
|
||||
return Object.keys(POSTS).map((slug) => ({ slug }));
|
||||
}
|
||||
|
||||
export async function generateMetadata({
|
||||
params,
|
||||
}: {
|
||||
params: Promise<{ slug: string }>;
|
||||
}): Promise<Metadata> {
|
||||
const { slug } = await params;
|
||||
const post = POSTS[slug];
|
||||
if (!post) return { title: 'Post Not Found' };
|
||||
return {
|
||||
title: `${post.title} — Axil Accountants Blog`,
|
||||
description: post.excerpt,
|
||||
};
|
||||
}
|
||||
|
||||
export default async function BlogPostPage({ params }: { params: Promise<{ slug: string }> }) {
|
||||
const { slug } = await params;
|
||||
const post = POSTS[slug];
|
||||
if (!post) notFound();
|
||||
|
||||
const related = RELATED_POSTS.filter((p) => p.slug !== slug).slice(0, 2);
|
||||
|
||||
return (
|
||||
<>
|
||||
<Header />
|
||||
<main>
|
||||
{/* Hero */}
|
||||
<section className="bg-bg relative overflow-hidden pt-32 pb-12">
|
||||
<div className="pointer-events-none absolute inset-0 bg-[radial-gradient(ellipse_60%_50%_at_50%_0%,var(--color-emerald-mist)_0%,transparent_70%)]" />
|
||||
<div className="relative mx-auto max-w-[1440px] px-4 sm:px-6 lg:px-8 xl:px-16">
|
||||
<FadeIn>
|
||||
<div className="mx-auto max-w-3xl">
|
||||
<Link
|
||||
href="/blog"
|
||||
className="text-muted hover:text-emerald mb-6 inline-flex items-center gap-1.5 text-sm font-medium transition-colors"
|
||||
>
|
||||
<svg
|
||||
width="16"
|
||||
height="16"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
strokeWidth="2"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
>
|
||||
<path d="m15 18-6-6 6-6" />
|
||||
</svg>
|
||||
Back to blog
|
||||
</Link>
|
||||
|
||||
<div className="mb-4 flex flex-wrap items-center gap-3">
|
||||
<Tag variant={post.categoryColor}>{post.category}</Tag>
|
||||
<span className="text-muted text-sm">{post.date}</span>
|
||||
<span className="text-muted text-sm">·</span>
|
||||
<span className="text-muted text-sm">{post.readTime} read</span>
|
||||
</div>
|
||||
|
||||
<h1 className="font-display text-charcoal mb-6 text-3xl leading-tight font-bold tracking-tight sm:text-4xl lg:text-5xl">
|
||||
{post.title}
|
||||
</h1>
|
||||
|
||||
<p className="text-muted mb-8 text-xl leading-relaxed">{post.excerpt}</p>
|
||||
|
||||
{/* Author */}
|
||||
<div className="flex items-center gap-3 border-t border-black/8 pt-6">
|
||||
<img
|
||||
src={`https://ui-avatars.com/api/?name=${encodeURIComponent(post.author)}&background=${post.authorBg}&color=fff&bold=true&size=80`}
|
||||
alt={post.author}
|
||||
width={44}
|
||||
height={44}
|
||||
className="size-11 rounded-full"
|
||||
/>
|
||||
<div>
|
||||
<p className="text-charcoal text-sm font-semibold">{post.author}</p>
|
||||
<p className="text-muted text-xs">{post.authorRole}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</FadeIn>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Article body */}
|
||||
<section className="bg-white py-16">
|
||||
<div className="mx-auto max-w-[1440px] px-4 sm:px-6 lg:px-8 xl:px-16">
|
||||
<div className="mx-auto max-w-3xl">
|
||||
<FadeIn>
|
||||
<div className="space-y-10">
|
||||
{post.content.map((section, i) => (
|
||||
<div key={i}>
|
||||
<h2 className="font-display text-charcoal mb-3 text-xl font-bold sm:text-2xl">
|
||||
{section.heading}
|
||||
</h2>
|
||||
<p className="text-muted text-base leading-relaxed">{section.body}</p>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</FadeIn>
|
||||
|
||||
{/* CTA inline */}
|
||||
<FadeIn delay={0.1}>
|
||||
<div className="rounded-hero border-emerald/25 bg-emerald-mist mt-14 border p-8 text-center">
|
||||
<p className="font-display text-charcoal mb-2 text-xl font-bold">
|
||||
Want personalised advice?
|
||||
</p>
|
||||
<p className="text-muted mb-5">
|
||||
Book a free 30-minute consultation with one of our qualified accountants.
|
||||
</p>
|
||||
<Button size="lg" trailingArrow>
|
||||
Book Free Consultation
|
||||
</Button>
|
||||
</div>
|
||||
</FadeIn>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Related posts */}
|
||||
{related.length > 0 && (
|
||||
<section className="bg-bg py-16">
|
||||
<div className="mx-auto max-w-[1440px] px-4 sm:px-6 lg:px-8 xl:px-16">
|
||||
<FadeIn>
|
||||
<h2 className="font-display text-charcoal mb-8 text-2xl font-bold">
|
||||
More from the blog
|
||||
</h2>
|
||||
</FadeIn>
|
||||
<div className="grid grid-cols-1 gap-6 sm:grid-cols-2">
|
||||
{related.map((p, i) => (
|
||||
<FadeIn key={p.slug} delay={i * 0.08}>
|
||||
<Link href={`/blog/${p.slug}`} className="group block h-full">
|
||||
<SpotlightCard
|
||||
className="h-full p-6 transition-transform duration-300 group-hover:-translate-y-1"
|
||||
glowColor="green"
|
||||
customSize
|
||||
>
|
||||
<div className="mb-3 flex items-center gap-3">
|
||||
<Tag variant={p.color}>{p.category}</Tag>
|
||||
<span className="text-muted text-xs">{p.date}</span>
|
||||
</div>
|
||||
<h3 className="font-display text-charcoal group-hover:text-emerald text-base leading-snug font-semibold transition-colors">
|
||||
{p.title}
|
||||
</h3>
|
||||
<p className="text-emerald mt-3 text-xs font-semibold">Read more →</p>
|
||||
</SpotlightCard>
|
||||
</Link>
|
||||
</FadeIn>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
)}
|
||||
</main>
|
||||
<Footer />
|
||||
</>
|
||||
);
|
||||
}
|
||||
158
src/app/blog/page.tsx
Normal file
158
src/app/blog/page.tsx
Normal file
|
|
@ -0,0 +1,158 @@
|
|||
import type { Metadata } from 'next';
|
||||
import Link from 'next/link';
|
||||
import { Header } from '@/components/layout/Header';
|
||||
import { Footer } from '@/components/layout/Footer';
|
||||
import { Button } from '@/components/ui/Button';
|
||||
import { FadeIn } from '@/components/ui/FadeIn';
|
||||
import { SpotlightCard } from '@/components/ui/SpotlightCard';
|
||||
import { Tag } from '@/components/ui/Tag';
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: 'Blog — Axil Accountants',
|
||||
description: 'Accounting tips, tax guides and financial insights for UK business owners.',
|
||||
};
|
||||
|
||||
const POSTS = [
|
||||
{
|
||||
slug: 'hmrc-making-tax-digital-guide',
|
||||
category: 'Tax',
|
||||
date: '12 Feb 2025',
|
||||
title: 'Making Tax Digital: Everything UK Business Owners Need to Know',
|
||||
excerpt:
|
||||
"MTD is now mandatory for most VAT-registered businesses. Here's what it means for you and how to make sure you're compliant.",
|
||||
readTime: '6 min',
|
||||
color: 'green' as const,
|
||||
},
|
||||
{
|
||||
slug: 'limited-company-vs-sole-trader',
|
||||
category: 'Business',
|
||||
date: '28 Jan 2025',
|
||||
title: 'Limited Company vs Sole Trader: Which Is Right for Your Business?',
|
||||
excerpt:
|
||||
'One of the most common questions from new business owners. We break down the tax implications, liability and admin for both structures.',
|
||||
readTime: '8 min',
|
||||
color: 'blue' as const,
|
||||
},
|
||||
{
|
||||
slug: 'self-assessment-tips-2025',
|
||||
category: 'Tax',
|
||||
date: '10 Jan 2025',
|
||||
title: '10 Self-Assessment Tips That Could Save You Thousands',
|
||||
excerpt:
|
||||
"Filing your self-assessment tax return? These allowances and deductions are commonly missed — even by people who've been filing for years.",
|
||||
readTime: '7 min',
|
||||
color: 'green' as const,
|
||||
},
|
||||
{
|
||||
slug: 'r-and-d-tax-credits-explained',
|
||||
category: 'Tax',
|
||||
date: '15 Dec 2024',
|
||||
title: 'R&D Tax Credits: Are You Leaving Money on the Table?',
|
||||
excerpt:
|
||||
'Many UK businesses qualify for R&D tax credits without realising it. Find out if your business is eligible and how much you could claim.',
|
||||
readTime: '5 min',
|
||||
color: 'blue' as const,
|
||||
},
|
||||
{
|
||||
slug: 'payroll-auto-enrolment-guide',
|
||||
category: 'Payroll',
|
||||
date: '2 Dec 2024',
|
||||
title: 'Auto-Enrolment in 2025: A Plain English Guide for Employers',
|
||||
excerpt:
|
||||
"Auto-enrolment pension duties catch many small employers off guard. Here's everything you need to know to stay compliant.",
|
||||
readTime: '6 min',
|
||||
color: 'green' as const,
|
||||
},
|
||||
{
|
||||
slug: 'cash-flow-tips-small-business',
|
||||
category: 'Finance',
|
||||
date: '18 Nov 2024',
|
||||
title: '7 Cash Flow Strategies Every Small Business Should Use',
|
||||
excerpt:
|
||||
'Cash flow problems are the number one reason small businesses fail. These practical strategies will help you stay ahead of the curve.',
|
||||
readTime: '5 min',
|
||||
color: 'blue' as const,
|
||||
},
|
||||
];
|
||||
|
||||
export default function BlogPage() {
|
||||
return (
|
||||
<>
|
||||
<Header />
|
||||
<main>
|
||||
{/* Hero */}
|
||||
<section className="bg-bg relative overflow-hidden pt-32 pb-20">
|
||||
<div className="pointer-events-none absolute inset-0 bg-[radial-gradient(ellipse_60%_50%_at_50%_0%,var(--color-emerald-mist)_0%,transparent_70%)]" />
|
||||
<div className="relative mx-auto max-w-[1440px] px-4 sm:px-6 lg:px-8 xl:px-16">
|
||||
<FadeIn>
|
||||
<div className="mx-auto max-w-3xl text-center">
|
||||
<p className="text-emerald mb-3 text-sm font-semibold tracking-widest uppercase">
|
||||
Insights
|
||||
</p>
|
||||
<h1 className="font-display text-charcoal mb-6 text-4xl font-bold tracking-tight sm:text-5xl lg:text-6xl">
|
||||
Practical insights for UK business owners
|
||||
</h1>
|
||||
<p className="text-muted text-xl leading-relaxed">
|
||||
Tax guides, accounting tips and financial strategies — written in plain English by
|
||||
our team of qualified accountants.
|
||||
</p>
|
||||
</div>
|
||||
</FadeIn>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Posts grid */}
|
||||
<section className="bg-white py-20">
|
||||
<div className="mx-auto max-w-[1440px] px-4 sm:px-6 lg:px-8 xl:px-16">
|
||||
<div className="grid grid-cols-1 gap-6 sm:grid-cols-2 lg:grid-cols-3">
|
||||
{POSTS.map((post, i) => (
|
||||
<FadeIn key={post.slug} delay={i * 0.07}>
|
||||
<Link href={`/blog/${post.slug}`} className="group block h-full">
|
||||
<SpotlightCard
|
||||
className="flex h-full flex-col p-6 transition-transform duration-300 group-hover:-translate-y-1"
|
||||
glowColor="green"
|
||||
customSize
|
||||
>
|
||||
<div className="mb-4 flex items-center justify-between">
|
||||
<Tag variant={post.color}>{post.category}</Tag>
|
||||
<span className="text-muted text-xs">{post.readTime} read</span>
|
||||
</div>
|
||||
<h2 className="font-display text-charcoal group-hover:text-emerald mb-3 text-lg leading-snug font-semibold transition-colors">
|
||||
{post.title}
|
||||
</h2>
|
||||
<p className="text-muted mb-4 flex-1 text-sm leading-relaxed">
|
||||
{post.excerpt}
|
||||
</p>
|
||||
<div className="flex items-center justify-between border-t border-black/6 pt-4">
|
||||
<span className="text-muted text-xs">{post.date}</span>
|
||||
<span className="text-emerald text-xs font-semibold">Read more →</span>
|
||||
</div>
|
||||
</SpotlightCard>
|
||||
</Link>
|
||||
</FadeIn>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Newsletter CTA */}
|
||||
<section className="bg-charcoal py-20">
|
||||
<div className="mx-auto max-w-[1440px] px-4 text-center sm:px-6 lg:px-8 xl:px-16">
|
||||
<FadeIn>
|
||||
<h2 className="font-display mb-4 text-3xl font-bold text-white sm:text-4xl">
|
||||
Get accounting insights in your inbox
|
||||
</h2>
|
||||
<p className="mx-auto mb-8 max-w-xl text-lg text-white/70">
|
||||
Monthly tax tips, deadline reminders and practical guides — free, no spam.
|
||||
</p>
|
||||
<Button size="lg" trailingArrow>
|
||||
Subscribe to newsletter
|
||||
</Button>
|
||||
</FadeIn>
|
||||
</div>
|
||||
</section>
|
||||
</main>
|
||||
<Footer />
|
||||
</>
|
||||
);
|
||||
}
|
||||
311
src/app/contact/page.tsx
Normal file
311
src/app/contact/page.tsx
Normal file
|
|
@ -0,0 +1,311 @@
|
|||
import type { Metadata } from 'next';
|
||||
import { Header } from '@/components/layout/Header';
|
||||
import { Footer } from '@/components/layout/Footer';
|
||||
import { Button } from '@/components/ui/Button';
|
||||
import { FadeIn } from '@/components/ui/FadeIn';
|
||||
import { SpotlightCard } from '@/components/ui/SpotlightCard';
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: 'Contact — Axil Accountants',
|
||||
description: 'Get in touch with Axil Accountants. Book a free consultation or send us a message.',
|
||||
};
|
||||
|
||||
const CONTACT_DETAILS = [
|
||||
{
|
||||
label: 'Email',
|
||||
value: 'hello@axilaccountants.co.uk',
|
||||
href: 'mailto:hello@axilaccountants.co.uk',
|
||||
icon: (
|
||||
<svg
|
||||
width="20"
|
||||
height="20"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
strokeWidth="2"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
>
|
||||
<rect width="20" height="16" x="2" y="4" rx="2" />
|
||||
<path d="m22 7-8.97 5.7a1.94 1.94 0 0 1-2.06 0L2 7" />
|
||||
</svg>
|
||||
),
|
||||
},
|
||||
{
|
||||
label: 'Phone',
|
||||
value: '0207 123 4567',
|
||||
href: 'tel:+442071234567',
|
||||
icon: (
|
||||
<svg
|
||||
width="20"
|
||||
height="20"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
strokeWidth="2"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
>
|
||||
<path d="M22 16.92v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07A19.5 19.5 0 0 1 4.15 12a19.79 19.79 0 0 1-3.07-8.67A2 2 0 0 1 3.06 2h3a2 2 0 0 1 2 1.72c.127.96.361 1.903.7 2.81a2 2 0 0 1-.45 2.11L7.09 9.91a16 16 0 0 0 6 6l1.27-1.27a2 2 0 0 1 2.11-.45c.907.339 1.85.573 2.81.7A2 2 0 0 1 21 16.92z" />
|
||||
</svg>
|
||||
),
|
||||
},
|
||||
{
|
||||
label: 'Address',
|
||||
value: '12 Finsbury Square, London, EC2A 1AB',
|
||||
href: 'https://maps.google.com',
|
||||
icon: (
|
||||
<svg
|
||||
width="20"
|
||||
height="20"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
strokeWidth="2"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
>
|
||||
<path d="M20 10c0 6-8 12-8 12s-8-6-8-12a8 8 0 0 1 16 0Z" />
|
||||
<circle cx="12" cy="10" r="3" />
|
||||
</svg>
|
||||
),
|
||||
},
|
||||
{
|
||||
label: 'Hours',
|
||||
value: 'Mon–Fri, 9am–6pm GMT',
|
||||
href: null,
|
||||
icon: (
|
||||
<svg
|
||||
width="20"
|
||||
height="20"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
strokeWidth="2"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
>
|
||||
<circle cx="12" cy="12" r="10" />
|
||||
<polyline points="12 6 12 12 16 14" />
|
||||
</svg>
|
||||
),
|
||||
},
|
||||
];
|
||||
|
||||
export default function ContactPage() {
|
||||
return (
|
||||
<>
|
||||
<Header />
|
||||
<main>
|
||||
{/* Hero */}
|
||||
<section className="bg-bg relative overflow-hidden pt-32 pb-16">
|
||||
<div className="pointer-events-none absolute inset-0 bg-[radial-gradient(ellipse_60%_50%_at_50%_0%,var(--color-emerald-mist)_0%,transparent_70%)]" />
|
||||
<div className="relative mx-auto max-w-[1440px] px-4 sm:px-6 lg:px-8 xl:px-16">
|
||||
<FadeIn>
|
||||
<div className="mx-auto max-w-2xl text-center">
|
||||
<p className="text-emerald mb-3 text-sm font-semibold tracking-widest uppercase">
|
||||
Get in touch
|
||||
</p>
|
||||
<h1 className="font-display text-charcoal mb-4 text-4xl font-bold tracking-tight sm:text-5xl">
|
||||
Let's talk about your business
|
||||
</h1>
|
||||
<p className="text-muted text-xl leading-relaxed">
|
||||
Book a free 30-minute consultation or send us a message. We usually respond within
|
||||
2 hours on business days.
|
||||
</p>
|
||||
</div>
|
||||
</FadeIn>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Two-column: form + info */}
|
||||
<section className="bg-white py-16">
|
||||
<div className="mx-auto max-w-[1440px] px-4 sm:px-6 lg:px-8 xl:px-16">
|
||||
<div className="grid grid-cols-1 gap-16 lg:grid-cols-[1fr_380px]">
|
||||
{/* Contact form */}
|
||||
<FadeIn>
|
||||
<SpotlightCard className="p-8 sm:p-10" glowColor="green" customSize>
|
||||
<h2 className="font-display text-charcoal mb-6 text-2xl font-bold">
|
||||
Send us a message
|
||||
</h2>
|
||||
<form className="space-y-5" action="#" method="POST">
|
||||
<div className="grid grid-cols-1 gap-5 sm:grid-cols-2">
|
||||
<div>
|
||||
<label
|
||||
htmlFor="first-name"
|
||||
className="text-charcoal mb-1.5 block text-sm font-medium"
|
||||
>
|
||||
First name
|
||||
</label>
|
||||
<input
|
||||
id="first-name"
|
||||
name="firstName"
|
||||
type="text"
|
||||
required
|
||||
placeholder="James"
|
||||
className="rounded-card bg-bg text-charcoal placeholder:text-muted focus:border-emerald focus:ring-emerald/20 w-full border border-black/12 px-4 py-3 text-sm transition-colors focus:ring-2 focus:outline-none"
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<label
|
||||
htmlFor="last-name"
|
||||
className="text-charcoal mb-1.5 block text-sm font-medium"
|
||||
>
|
||||
Last name
|
||||
</label>
|
||||
<input
|
||||
id="last-name"
|
||||
name="lastName"
|
||||
type="text"
|
||||
required
|
||||
placeholder="Wilson"
|
||||
className="rounded-card bg-bg text-charcoal placeholder:text-muted focus:border-emerald focus:ring-emerald/20 w-full border border-black/12 px-4 py-3 text-sm transition-colors focus:ring-2 focus:outline-none"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label
|
||||
htmlFor="email"
|
||||
className="text-charcoal mb-1.5 block text-sm font-medium"
|
||||
>
|
||||
Email address
|
||||
</label>
|
||||
<input
|
||||
id="email"
|
||||
name="email"
|
||||
type="email"
|
||||
required
|
||||
placeholder="james@yourbusiness.co.uk"
|
||||
className="rounded-card bg-bg text-charcoal placeholder:text-muted focus:border-emerald focus:ring-emerald/20 w-full border border-black/12 px-4 py-3 text-sm transition-colors focus:ring-2 focus:outline-none"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label
|
||||
htmlFor="phone"
|
||||
className="text-charcoal mb-1.5 block text-sm font-medium"
|
||||
>
|
||||
Phone number <span className="text-muted">(optional)</span>
|
||||
</label>
|
||||
<input
|
||||
id="phone"
|
||||
name="phone"
|
||||
type="tel"
|
||||
placeholder="07700 900000"
|
||||
className="rounded-card bg-bg text-charcoal placeholder:text-muted focus:border-emerald focus:ring-emerald/20 w-full border border-black/12 px-4 py-3 text-sm transition-colors focus:ring-2 focus:outline-none"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label
|
||||
htmlFor="service"
|
||||
className="text-charcoal mb-1.5 block text-sm font-medium"
|
||||
>
|
||||
I'm interested in
|
||||
</label>
|
||||
<select
|
||||
id="service"
|
||||
name="service"
|
||||
className="rounded-card bg-bg text-charcoal focus:border-emerald focus:ring-emerald/20 w-full border border-black/12 px-4 py-3 text-sm transition-colors focus:ring-2 focus:outline-none"
|
||||
>
|
||||
<option value="">Select a service...</option>
|
||||
<option value="bookkeeping">Bookkeeping</option>
|
||||
<option value="tax-returns">Tax Returns</option>
|
||||
<option value="payroll">Payroll</option>
|
||||
<option value="vat-returns">VAT Returns</option>
|
||||
<option value="all">Full accounting package</option>
|
||||
<option value="other">Other / Not sure</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label
|
||||
htmlFor="message"
|
||||
className="text-charcoal mb-1.5 block text-sm font-medium"
|
||||
>
|
||||
Message
|
||||
</label>
|
||||
<textarea
|
||||
id="message"
|
||||
name="message"
|
||||
rows={4}
|
||||
required
|
||||
placeholder="Tell us a bit about your business and what you're looking for..."
|
||||
className="rounded-card bg-bg text-charcoal placeholder:text-muted focus:border-emerald focus:ring-emerald/20 w-full resize-none border border-black/12 px-4 py-3 text-sm transition-colors focus:ring-2 focus:outline-none"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<Button type="submit" size="lg" className="w-full justify-center" trailingArrow>
|
||||
Send message
|
||||
</Button>
|
||||
|
||||
<p className="text-muted text-center text-xs">
|
||||
We typically respond within 2 hours on business days. No spam, ever.
|
||||
</p>
|
||||
</form>
|
||||
</SpotlightCard>
|
||||
</FadeIn>
|
||||
|
||||
{/* Contact info */}
|
||||
<FadeIn delay={0.15}>
|
||||
<div className="space-y-6">
|
||||
<div>
|
||||
<h2 className="font-display text-charcoal mb-2 text-xl font-bold">
|
||||
Contact details
|
||||
</h2>
|
||||
<p className="text-muted text-sm">
|
||||
Prefer to reach out directly? Here's how to find us.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="space-y-4">
|
||||
{CONTACT_DETAILS.map((item) => (
|
||||
<div
|
||||
key={item.label}
|
||||
className="rounded-card bg-bg flex items-start gap-4 border border-black/8 p-4"
|
||||
>
|
||||
<div className="rounded-card bg-emerald-mist text-emerald flex size-10 shrink-0 items-center justify-center">
|
||||
{item.icon}
|
||||
</div>
|
||||
<div>
|
||||
<p className="text-muted mb-0.5 text-xs font-semibold tracking-wider uppercase">
|
||||
{item.label}
|
||||
</p>
|
||||
{item.href ? (
|
||||
<a
|
||||
href={item.href}
|
||||
className="text-charcoal hover:text-emerald text-sm font-medium transition-colors"
|
||||
>
|
||||
{item.value}
|
||||
</a>
|
||||
) : (
|
||||
<p className="text-charcoal text-sm font-medium">{item.value}</p>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
{/* Book consultation shortcut */}
|
||||
<div className="rounded-hero border-emerald/25 bg-emerald-mist border p-6 text-center">
|
||||
<p className="font-display text-charcoal mb-1 text-lg font-bold">
|
||||
Prefer a call?
|
||||
</p>
|
||||
<p className="text-muted mb-4 text-sm">
|
||||
Book a free 30-minute consultation directly in our calendar.
|
||||
</p>
|
||||
<Button size="md" trailingArrow className="w-full justify-center">
|
||||
Book free consultation
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</FadeIn>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</main>
|
||||
<Footer />
|
||||
</>
|
||||
);
|
||||
}
|
||||
353
src/app/services/[slug]/page.tsx
Normal file
353
src/app/services/[slug]/page.tsx
Normal file
|
|
@ -0,0 +1,353 @@
|
|||
import type { Metadata } from 'next';
|
||||
import { notFound } from 'next/navigation';
|
||||
import Link from 'next/link';
|
||||
import { Header } from '@/components/layout/Header';
|
||||
import { Footer } from '@/components/layout/Footer';
|
||||
import { Button } from '@/components/ui/Button';
|
||||
import { FadeIn } from '@/components/ui/FadeIn';
|
||||
import { SpotlightCard } from '@/components/ui/SpotlightCard';
|
||||
import { CheckCircleIcon } from '@/components/ui/icons';
|
||||
|
||||
const SERVICES: Record<
|
||||
string,
|
||||
{
|
||||
title: string;
|
||||
tagline: string;
|
||||
intro: string;
|
||||
includes: string[];
|
||||
benefits: { title: string; desc: string }[];
|
||||
faq: { q: string; a: string }[];
|
||||
}
|
||||
> = {
|
||||
bookkeeping: {
|
||||
title: 'Bookkeeping',
|
||||
tagline: 'Accurate records, zero stress',
|
||||
intro:
|
||||
'Up-to-date books every month, cloud-based and always accessible. We reconcile every transaction so your accounts are always audit-ready — and you always know where you stand.',
|
||||
includes: [
|
||||
'Monthly bank reconciliation',
|
||||
'Expense categorisation & receipts',
|
||||
'Accounts payable & receivable tracking',
|
||||
'Cloud accounting software setup (Xero/QuickBooks)',
|
||||
'Monthly management accounts',
|
||||
'Real-time financial dashboard access',
|
||||
],
|
||||
benefits: [
|
||||
{
|
||||
title: 'Save 10+ hours per month',
|
||||
desc: 'Stop wrestling with spreadsheets. We handle every transaction so you never have to.',
|
||||
},
|
||||
{
|
||||
title: 'Always audit-ready',
|
||||
desc: 'Clean, HMRC-compliant records mean no panic when a filing deadline arrives.',
|
||||
},
|
||||
{
|
||||
title: 'Real-time visibility',
|
||||
desc: 'Log in any time to see exactly how your business is performing, with no surprises.',
|
||||
},
|
||||
],
|
||||
faq: [
|
||||
{
|
||||
q: 'Which accounting software do you use?',
|
||||
a: "We work with Xero, QuickBooks and Sage. We'll recommend the best option for your business and handle the setup.",
|
||||
},
|
||||
{
|
||||
q: 'How do I send you my receipts?',
|
||||
a: 'Via a simple mobile app — just photograph receipts on your phone. No more shoeboxes.',
|
||||
},
|
||||
{
|
||||
q: 'How quickly are transactions recorded?',
|
||||
a: 'All transactions are reconciled within 48 hours of your bank feed updating, usually faster.',
|
||||
},
|
||||
],
|
||||
},
|
||||
'tax-returns': {
|
||||
title: 'Tax Returns',
|
||||
tagline: 'Every allowance claimed',
|
||||
intro:
|
||||
'From self-assessment to corporation tax, we handle every filing and actively look for every allowance, deduction and relief your business is entitled to.',
|
||||
includes: [
|
||||
'Self-assessment tax return preparation & filing',
|
||||
'Corporation tax (CT600) preparation & filing',
|
||||
'Capital allowances review',
|
||||
'R&D tax credits (if applicable)',
|
||||
'HMRC correspondence management',
|
||||
'Tax planning & year-end strategy',
|
||||
],
|
||||
benefits: [
|
||||
{
|
||||
title: 'Never miss a deadline',
|
||||
desc: "We track every HMRC deadline and file well in advance — you'll never pay a late filing penalty.",
|
||||
},
|
||||
{
|
||||
title: 'Maximum allowances',
|
||||
desc: 'Our tax specialists review every available allowance and relief to legally minimise your tax bill.',
|
||||
},
|
||||
{
|
||||
title: 'HMRC as a proxy',
|
||||
desc: 'We handle all correspondence with HMRC. You never have to speak to them directly unless you want to.',
|
||||
},
|
||||
],
|
||||
faq: [
|
||||
{
|
||||
q: 'When do you start my tax return?',
|
||||
a: "We begin collecting information 3–4 months before your filing deadline so there's never a rush.",
|
||||
},
|
||||
{
|
||||
q: 'What if HMRC investigates me?',
|
||||
a: 'We represent you fully and handle the entire process. Our fee protection cover is included as standard.',
|
||||
},
|
||||
{
|
||||
q: 'Can you do R&D tax credits?',
|
||||
a: "Yes — if your business conducts qualifying R&D activities, we'll identify and claim the relief on your behalf.",
|
||||
},
|
||||
],
|
||||
},
|
||||
payroll: {
|
||||
title: 'Payroll',
|
||||
tagline: 'On time, every time',
|
||||
intro:
|
||||
'Fully managed payroll for businesses of any size. We handle PAYE, National Insurance, pension auto-enrolment, RTI filings and payslips — so you never have to think about it.',
|
||||
includes: [
|
||||
'Monthly payroll processing',
|
||||
'PAYE & National Insurance calculations',
|
||||
'Auto-enrolment pension management',
|
||||
'Real Time Information (RTI) submissions',
|
||||
'Payslips for every employee',
|
||||
'P60s, P45s and P11Ds',
|
||||
],
|
||||
benefits: [
|
||||
{
|
||||
title: 'Zero errors',
|
||||
desc: 'Manual payroll errors are costly. Our systems double-check every calculation before submission.',
|
||||
},
|
||||
{
|
||||
title: 'Full compliance',
|
||||
desc: 'RTI submissions, auto-enrolment, NMW compliance — all handled on time, every time.',
|
||||
},
|
||||
{
|
||||
title: 'Scales with you',
|
||||
desc: 'Whether you have 1 employee or 100, our payroll service scales effortlessly as your team grows.',
|
||||
},
|
||||
],
|
||||
faq: [
|
||||
{
|
||||
q: "What's the deadline for running payroll?",
|
||||
a: 'We ask for any changes (new starters, leavers, salary changes) by the 20th of each month and process by the 25th.',
|
||||
},
|
||||
{
|
||||
q: 'Do you handle auto-enrolment pensions?',
|
||||
a: 'Yes — we set up and manage your workplace pension scheme, handle all enrolment communications and submissions.',
|
||||
},
|
||||
{
|
||||
q: 'What if I need to add a new employee?',
|
||||
a: 'Just email us the details. We add them to the next payroll run and handle all the HMRC notifications.',
|
||||
},
|
||||
],
|
||||
},
|
||||
'vat-returns': {
|
||||
title: 'VAT Returns',
|
||||
tagline: 'MTD-compliant filing',
|
||||
intro:
|
||||
'Making Tax Digital-compliant VAT returns filed accurately and on time, every quarter. We also advise on the most tax-efficient VAT scheme for your business.',
|
||||
includes: [
|
||||
'Quarterly VAT return preparation & filing',
|
||||
'Making Tax Digital (MTD) compliance',
|
||||
'VAT scheme assessment & advice',
|
||||
'Input & output VAT reconciliation',
|
||||
'HMRC VAT correspondence',
|
||||
'VAT registration & deregistration',
|
||||
],
|
||||
benefits: [
|
||||
{
|
||||
title: 'Never miss a VAT deadline',
|
||||
desc: 'Late VAT returns trigger automatic penalties. We file every return well before the deadline.',
|
||||
},
|
||||
{
|
||||
title: 'Right scheme for your business',
|
||||
desc: "Flat Rate, Cash Accounting or Standard — we make sure you're on the scheme that minimises your VAT bill.",
|
||||
},
|
||||
{
|
||||
title: 'MTD fully handled',
|
||||
desc: "HMRC's Making Tax Digital requirements are completely managed by us. No software headaches.",
|
||||
},
|
||||
],
|
||||
faq: [
|
||||
{
|
||||
q: 'Do I need to register for VAT?',
|
||||
a: "You must register once your taxable turnover exceeds £90,000. We'll advise on timing and handle the registration.",
|
||||
},
|
||||
{
|
||||
q: 'What is Making Tax Digital?',
|
||||
a: 'MTD requires businesses to keep digital records and submit VAT returns using approved software. We handle this entirely.',
|
||||
},
|
||||
{
|
||||
q: 'Can you help with a VAT investigation?',
|
||||
a: 'Yes — we represent you fully in any HMRC VAT enquiry and our fee protection covers the cost.',
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
|
||||
export function generateStaticParams() {
|
||||
return Object.keys(SERVICES).map((slug) => ({ slug }));
|
||||
}
|
||||
|
||||
export async function generateMetadata({
|
||||
params,
|
||||
}: {
|
||||
params: Promise<{ slug: string }>;
|
||||
}): Promise<Metadata> {
|
||||
const { slug } = await params;
|
||||
const svc = SERVICES[slug];
|
||||
if (!svc) return {};
|
||||
return {
|
||||
title: `${svc.title} — Axil Accountants`,
|
||||
description: svc.intro,
|
||||
};
|
||||
}
|
||||
|
||||
export default async function ServicePage({ params }: { params: Promise<{ slug: string }> }) {
|
||||
const { slug } = await params;
|
||||
const svc = SERVICES[slug];
|
||||
if (!svc) notFound();
|
||||
|
||||
return (
|
||||
<>
|
||||
<Header />
|
||||
<main>
|
||||
{/* Hero */}
|
||||
<section className="bg-bg relative overflow-hidden pt-32 pb-20">
|
||||
<div className="pointer-events-none absolute inset-0 bg-[radial-gradient(ellipse_60%_50%_at_50%_0%,var(--color-emerald-mist)_0%,transparent_70%)]" />
|
||||
<div className="relative mx-auto max-w-[1440px] px-4 sm:px-6 lg:px-8 xl:px-16">
|
||||
<FadeIn>
|
||||
<div className="mx-auto max-w-3xl text-center">
|
||||
<Link
|
||||
href="/services"
|
||||
className="text-muted hover:text-charcoal mb-4 inline-flex items-center gap-1.5 text-sm font-medium transition-colors"
|
||||
>
|
||||
← All services
|
||||
</Link>
|
||||
<h1 className="font-display text-charcoal mb-3 text-4xl font-bold tracking-tight sm:text-5xl lg:text-6xl">
|
||||
{svc.title}
|
||||
</h1>
|
||||
<p className="text-emerald mb-4 text-sm font-semibold tracking-widest uppercase">
|
||||
{svc.tagline}
|
||||
</p>
|
||||
<p className="text-muted mb-8 text-xl leading-relaxed">{svc.intro}</p>
|
||||
<Button size="lg" trailingArrow>
|
||||
Book Free Consultation
|
||||
</Button>
|
||||
</div>
|
||||
</FadeIn>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* What's included */}
|
||||
<section className="bg-white py-20">
|
||||
<div className="mx-auto max-w-[1440px] px-4 sm:px-6 lg:px-8 xl:px-16">
|
||||
<div className="grid grid-cols-1 gap-16 lg:grid-cols-2 lg:items-start">
|
||||
<FadeIn>
|
||||
<p className="text-emerald mb-3 text-sm font-semibold tracking-widest uppercase">
|
||||
What's included
|
||||
</p>
|
||||
<h2 className="font-display text-charcoal mb-6 text-2xl font-bold sm:text-3xl">
|
||||
Everything covered, nothing extra
|
||||
</h2>
|
||||
<ul className="space-y-3">
|
||||
{svc.includes.map((item) => (
|
||||
<li key={item} className="flex items-start gap-3">
|
||||
<CheckCircleIcon
|
||||
size={18}
|
||||
color="var(--emerald)"
|
||||
className="mt-0.5 shrink-0"
|
||||
/>
|
||||
<span className="text-charcoal text-base">{item}</span>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</FadeIn>
|
||||
|
||||
<FadeIn delay={0.15}>
|
||||
<p className="text-emerald mb-3 text-sm font-semibold tracking-widest uppercase">
|
||||
Why it matters
|
||||
</p>
|
||||
<h2 className="font-display text-charcoal mb-6 text-2xl font-bold sm:text-3xl">
|
||||
The benefits
|
||||
</h2>
|
||||
<div className="space-y-4">
|
||||
{svc.benefits.map((b, i) => (
|
||||
<SpotlightCard key={b.title} className="p-5" glowColor="green" customSize>
|
||||
<div className="mb-1 flex items-center gap-2">
|
||||
<span className="bg-emerald flex size-6 items-center justify-center rounded-full text-xs font-bold text-white">
|
||||
{i + 1}
|
||||
</span>
|
||||
<h3 className="font-display text-charcoal text-base font-semibold">
|
||||
{b.title}
|
||||
</h3>
|
||||
</div>
|
||||
<p className="text-muted text-sm leading-relaxed">{b.desc}</p>
|
||||
</SpotlightCard>
|
||||
))}
|
||||
</div>
|
||||
</FadeIn>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* FAQ */}
|
||||
<section className="bg-bg py-20">
|
||||
<div className="mx-auto max-w-[1440px] px-4 sm:px-6 lg:px-8 xl:px-16">
|
||||
<FadeIn>
|
||||
<div className="mx-auto max-w-2xl">
|
||||
<p className="text-emerald mb-3 text-sm font-semibold tracking-widest uppercase">
|
||||
FAQ
|
||||
</p>
|
||||
<h2 className="font-display text-charcoal mb-10 text-2xl font-bold sm:text-3xl">
|
||||
Common questions about {svc.title.toLowerCase()}
|
||||
</h2>
|
||||
<div className="space-y-4">
|
||||
{svc.faq.map((item) => (
|
||||
<div key={item.q} className="rounded-hero border border-black/8 bg-white p-6">
|
||||
<h3 className="font-display text-charcoal mb-2 text-base font-semibold">
|
||||
{item.q}
|
||||
</h3>
|
||||
<p className="text-muted text-sm leading-relaxed">{item.a}</p>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</FadeIn>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* CTA */}
|
||||
<section className="bg-charcoal py-20">
|
||||
<div className="mx-auto max-w-[1440px] px-4 text-center sm:px-6 lg:px-8 xl:px-16">
|
||||
<FadeIn>
|
||||
<h2 className="font-display mb-4 text-3xl font-bold text-white sm:text-4xl">
|
||||
Ready to get started with {svc.title}?
|
||||
</h2>
|
||||
<p className="mx-auto mb-8 max-w-xl text-lg text-white/70">
|
||||
Book a free consultation and we'll have you set up in days.
|
||||
</p>
|
||||
<div className="flex flex-wrap justify-center gap-3">
|
||||
<Button size="lg" trailingArrow>
|
||||
Book Free Consultation
|
||||
</Button>
|
||||
<Button
|
||||
size="lg"
|
||||
variant="secondary"
|
||||
className="border-white/30 text-white hover:bg-white/10"
|
||||
>
|
||||
<Link href="/services">View all services</Link>
|
||||
</Button>
|
||||
</div>
|
||||
</FadeIn>
|
||||
</div>
|
||||
</section>
|
||||
</main>
|
||||
<Footer />
|
||||
</>
|
||||
);
|
||||
}
|
||||
186
src/app/services/page.tsx
Normal file
186
src/app/services/page.tsx
Normal file
|
|
@ -0,0 +1,186 @@
|
|||
import type { Metadata } from 'next';
|
||||
import Link from 'next/link';
|
||||
import { Header } from '@/components/layout/Header';
|
||||
import { Footer } from '@/components/layout/Footer';
|
||||
import { Button } from '@/components/ui/Button';
|
||||
import { FadeIn } from '@/components/ui/FadeIn';
|
||||
import { SpotlightCard } from '@/components/ui/SpotlightCard';
|
||||
import {
|
||||
CheckCircleIcon,
|
||||
BookkeepingIcon,
|
||||
TaxIcon,
|
||||
PayrollIcon,
|
||||
VATIcon,
|
||||
} from '@/components/ui/icons';
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: 'Services — Axil Accountants',
|
||||
description:
|
||||
'Bookkeeping, tax returns, payroll and VAT returns for UK businesses. Fixed monthly fees, dedicated account manager.',
|
||||
};
|
||||
|
||||
const SERVICES = [
|
||||
{
|
||||
slug: 'bookkeeping',
|
||||
icon: BookkeepingIcon,
|
||||
title: 'Bookkeeping',
|
||||
tagline: 'Accurate records, zero stress',
|
||||
desc: 'We keep your books up to date every month so you always know exactly where your business stands financially.',
|
||||
perks: [
|
||||
'Monthly reconciliation',
|
||||
'Real-time reports',
|
||||
'MTD-ready records',
|
||||
'Cloud accounting setup',
|
||||
],
|
||||
color: 'bg-emerald-mist',
|
||||
accent: 'text-emerald',
|
||||
},
|
||||
{
|
||||
slug: 'tax-returns',
|
||||
icon: TaxIcon,
|
||||
title: 'Tax Returns',
|
||||
tagline: 'Every allowance claimed',
|
||||
desc: "From self-assessment to corporation tax, we handle it all — and we proactively find every allowance you're entitled to.",
|
||||
perks: ['Self-assessment filing', 'Corporation tax', 'Capital allowances', 'R&D tax credits'],
|
||||
color: 'bg-blue-mist',
|
||||
accent: 'text-blue',
|
||||
},
|
||||
{
|
||||
slug: 'payroll',
|
||||
icon: PayrollIcon,
|
||||
title: 'Payroll',
|
||||
tagline: 'On time, every time',
|
||||
desc: 'Fully managed payroll for teams of any size. We handle PAYE, National Insurance, pension auto-enrolment and RTI filings.',
|
||||
perks: ['PAYE & NI management', 'Auto-enrolment', 'RTI submissions', 'Payslips & P60s'],
|
||||
color: 'bg-emerald-mist',
|
||||
accent: 'text-emerald',
|
||||
},
|
||||
{
|
||||
slug: 'vat-returns',
|
||||
icon: VATIcon,
|
||||
title: 'VAT Returns',
|
||||
tagline: 'MTD-compliant filing',
|
||||
desc: 'Making Tax Digital-compliant VAT returns filed on time, every quarter. We also advise on the right VAT scheme for your business.',
|
||||
perks: ['Quarterly VAT returns', 'MTD compliance', 'VAT scheme advice', 'HMRC correspondence'],
|
||||
color: 'bg-blue-mist',
|
||||
accent: 'text-blue',
|
||||
},
|
||||
];
|
||||
|
||||
export default function ServicesPage() {
|
||||
return (
|
||||
<>
|
||||
<Header />
|
||||
<main>
|
||||
{/* Hero */}
|
||||
<section className="bg-bg relative overflow-hidden pt-32 pb-20">
|
||||
<div className="pointer-events-none absolute inset-0 bg-[radial-gradient(ellipse_60%_50%_at_50%_0%,var(--color-emerald-mist)_0%,transparent_70%)]" />
|
||||
<div className="relative mx-auto max-w-[1440px] px-4 sm:px-6 lg:px-8 xl:px-16">
|
||||
<FadeIn>
|
||||
<div className="mx-auto max-w-3xl text-center">
|
||||
<p className="text-emerald mb-3 text-sm font-semibold tracking-widest uppercase">
|
||||
What we offer
|
||||
</p>
|
||||
<h1 className="font-display text-charcoal mb-6 text-4xl font-bold tracking-tight sm:text-5xl lg:text-6xl">
|
||||
Everything your business needs, nothing it doesn't
|
||||
</h1>
|
||||
<p className="text-muted mb-8 text-xl leading-relaxed">
|
||||
Fixed monthly fees. No surprise invoices. Just expert accounting that keeps your
|
||||
business compliant and growing.
|
||||
</p>
|
||||
<div className="flex flex-wrap justify-center gap-3">
|
||||
<Button size="lg" trailingArrow>
|
||||
Book Free Consultation
|
||||
</Button>
|
||||
<Button size="lg" variant="secondary">
|
||||
<Link href="/contact">Talk to us</Link>
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</FadeIn>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Services grid */}
|
||||
<section className="bg-white py-24">
|
||||
<div className="mx-auto max-w-[1440px] px-4 sm:px-6 lg:px-8 xl:px-16">
|
||||
<div className="grid grid-cols-1 gap-8 md:grid-cols-2">
|
||||
{SERVICES.map((svc, i) => {
|
||||
const Icon = svc.icon;
|
||||
return (
|
||||
<FadeIn key={svc.slug} delay={i * 0.1}>
|
||||
<SpotlightCard className="h-full p-8" glowColor="green" customSize>
|
||||
<div
|
||||
className={`rounded-card mb-5 inline-flex size-14 items-center justify-center ${svc.color}`}
|
||||
>
|
||||
<Icon size={28} />
|
||||
</div>
|
||||
<h2 className="font-display text-charcoal mb-1 text-2xl font-bold">
|
||||
{svc.title}
|
||||
</h2>
|
||||
<p className={`mb-3 text-sm font-semibold ${svc.accent}`}>{svc.tagline}</p>
|
||||
<p className="text-muted mb-6 text-base leading-relaxed">{svc.desc}</p>
|
||||
<ul className="mb-6 space-y-2">
|
||||
{svc.perks.map((p) => (
|
||||
<li key={p} className="flex items-center gap-2.5">
|
||||
<CheckCircleIcon size={15} color="var(--emerald)" />
|
||||
<span className="text-charcoal text-sm">{p}</span>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
<Link
|
||||
href={`/services/${svc.slug}`}
|
||||
className="text-emerald hover:text-emerald-dark inline-flex items-center gap-1.5 text-sm font-semibold transition-colors"
|
||||
>
|
||||
Learn more →
|
||||
</Link>
|
||||
</SpotlightCard>
|
||||
</FadeIn>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Why fixed fees */}
|
||||
<section className="bg-bg py-20">
|
||||
<div className="mx-auto max-w-[1440px] px-4 sm:px-6 lg:px-8 xl:px-16">
|
||||
<FadeIn>
|
||||
<div className="rounded-hero border-emerald/20 border bg-white p-10 text-center shadow-sm">
|
||||
<h2 className="font-display text-charcoal mb-4 text-2xl font-bold sm:text-3xl">
|
||||
All services. One fixed monthly fee.
|
||||
</h2>
|
||||
<p className="text-muted mx-auto mb-6 max-w-xl text-lg">
|
||||
No hourly billing, no surprise invoices, no extra charges for phone calls. Just
|
||||
clear, predictable pricing so you can budget with confidence.
|
||||
</p>
|
||||
<Button size="lg" trailingArrow>
|
||||
Get your quote
|
||||
</Button>
|
||||
</div>
|
||||
</FadeIn>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* CTA */}
|
||||
<section className="bg-charcoal py-20">
|
||||
<div className="mx-auto max-w-[1440px] px-4 text-center sm:px-6 lg:px-8 xl:px-16">
|
||||
<FadeIn>
|
||||
<h2 className="font-display mb-4 text-3xl font-bold text-white sm:text-4xl">
|
||||
Not sure which service you need?
|
||||
</h2>
|
||||
<p className="mx-auto mb-8 max-w-xl text-lg text-white/70">
|
||||
Book a free 30-minute consultation. We'll assess your situation and recommend
|
||||
exactly what your business needs.
|
||||
</p>
|
||||
<Button size="lg" trailingArrow>
|
||||
Book Free Consultation
|
||||
</Button>
|
||||
</FadeIn>
|
||||
</div>
|
||||
</section>
|
||||
</main>
|
||||
<Footer />
|
||||
</>
|
||||
);
|
||||
}
|
||||
139
src/components/layout/Footer.tsx
Normal file
139
src/components/layout/Footer.tsx
Normal file
|
|
@ -0,0 +1,139 @@
|
|||
import Link from 'next/link';
|
||||
import { TextHoverEffect, FooterBackgroundGradient } from '@/components/ui/TextHoverEffect';
|
||||
|
||||
const SERVICES = [
|
||||
{ label: 'Bookkeeping', href: '/services/bookkeeping' },
|
||||
{ label: 'Tax Returns', href: '/services/tax-returns' },
|
||||
{ label: 'Payroll', href: '/services/payroll' },
|
||||
{ label: 'VAT Returns', href: '/services/vat-returns' },
|
||||
];
|
||||
const COMPANY = [
|
||||
{ label: 'About Us', href: '/about' },
|
||||
{ label: 'Our Team', href: '/about#team' },
|
||||
{ label: 'Blog', href: '/blog' },
|
||||
{ label: 'Contact', href: '/contact' },
|
||||
];
|
||||
const LEGAL = [
|
||||
{ label: 'Privacy Policy', href: '/privacy-policy' },
|
||||
{ label: 'Cookie Policy', href: '/cookie-policy' },
|
||||
{ label: 'Terms of Use', href: '/terms' },
|
||||
];
|
||||
|
||||
function FooterCol({
|
||||
heading,
|
||||
links,
|
||||
}: {
|
||||
heading: string;
|
||||
links: { label: string; href: string }[];
|
||||
}) {
|
||||
return (
|
||||
<div>
|
||||
<h4 className="mb-4 text-sm font-semibold tracking-wider text-white/50 uppercase">
|
||||
{heading}
|
||||
</h4>
|
||||
<ul className="space-y-2">
|
||||
{links.map((l) => (
|
||||
<li key={l.label}>
|
||||
<Link
|
||||
href={l.href}
|
||||
className="hover:text-emerald text-sm text-white/70 transition-colors"
|
||||
>
|
||||
{l.label}
|
||||
</Link>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export function Footer() {
|
||||
return (
|
||||
<footer className="bg-charcoal relative overflow-hidden text-white">
|
||||
{/* Radial gradient overlay */}
|
||||
<FooterBackgroundGradient />
|
||||
|
||||
{/* TextHoverEffect brand name */}
|
||||
<div className="relative z-10 flex h-28 items-center justify-center border-b border-white/8 sm:h-36">
|
||||
<TextHoverEffect text="AXIL ACCOUNTANTS" duration={0} />
|
||||
</div>
|
||||
|
||||
{/* Main grid */}
|
||||
<div className="relative z-10 mx-auto max-w-[1440px] px-4 sm:px-6 lg:px-8 xl:px-16">
|
||||
<div className="grid grid-cols-2 gap-10 py-14 sm:grid-cols-4">
|
||||
{/* Brand column */}
|
||||
<div className="col-span-2 sm:col-span-1">
|
||||
{/* SVG logo — light version for dark background */}
|
||||
<div className="mb-4 flex items-center gap-2">
|
||||
<svg width="52" height="32" viewBox="0 0 76 44" fill="none" aria-hidden="true">
|
||||
<rect x="0" y="2" width="38" height="40" rx="5" fill="#1B9AD6" />
|
||||
<path d="M19 6 L34 40 H4 L19 6Z" fill="white" />
|
||||
<path d="M19 14 L27 32 H11 L19 14Z" fill="#1B9AD6" />
|
||||
<rect x="5" y="33" width="28" height="6" rx="1.5" fill="#3CC68A" />
|
||||
<rect x="45" y="30" width="7" height="14" rx="2" fill="#3CC68A" />
|
||||
<rect x="56" y="22" width="7" height="22" rx="2" fill="#3CC68A" />
|
||||
<rect x="67" y="11" width="7" height="33" rx="2" fill="#3CC68A" />
|
||||
</svg>
|
||||
<div className="flex flex-col leading-none">
|
||||
<div className="flex items-baseline gap-1">
|
||||
<span className="font-display text-blue text-base font-black tracking-[0.08em]">
|
||||
AXIL
|
||||
</span>
|
||||
<span className="font-display text-emerald text-base font-bold tracking-[0.04em]">
|
||||
ACCOUNTANTS
|
||||
</span>
|
||||
</div>
|
||||
<div className="bg-blue/50 mt-0.5 h-[1px] rounded-full" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<p className="mb-6 max-w-[220px] text-sm leading-relaxed text-white/60">
|
||||
Smart accounting for growing British businesses. Fixed fees, dedicated manager, zero
|
||||
surprises.
|
||||
</p>
|
||||
|
||||
<div className="flex gap-3">
|
||||
<a
|
||||
href="https://linkedin.com"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
aria-label="LinkedIn"
|
||||
className="rounded-card hover:border-emerald/50 hover:text-emerald flex size-9 items-center justify-center border border-white/10 text-white/50 transition-colors"
|
||||
>
|
||||
<svg width="16" height="16" viewBox="0 0 24 24" fill="currentColor">
|
||||
<path d="M16 8a6 6 0 016 6v7h-4v-7a2 2 0 00-2-2 2 2 0 00-2 2v7h-4v-7a6 6 0 016-6zM2 9h4v12H2z" />
|
||||
<circle cx="4" cy="4" r="2" />
|
||||
</svg>
|
||||
</a>
|
||||
<a
|
||||
href="https://facebook.com"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
aria-label="Facebook"
|
||||
className="rounded-card hover:border-emerald/50 hover:text-emerald flex size-9 items-center justify-center border border-white/10 text-white/50 transition-colors"
|
||||
>
|
||||
<svg width="16" height="16" viewBox="0 0 24 24" fill="currentColor">
|
||||
<path d="M18 2h-3a5 5 0 00-5 5v3H7v4h3v8h4v-8h3l1-4h-4V7a1 1 0 011-1h3z" />
|
||||
</svg>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<FooterCol heading="Services" links={SERVICES} />
|
||||
<FooterCol heading="Company" links={COMPANY} />
|
||||
<FooterCol heading="Legal" links={LEGAL} />
|
||||
</div>
|
||||
|
||||
{/* Bottom bar */}
|
||||
<div className="flex flex-col items-center justify-between gap-4 border-t border-white/10 py-6 sm:flex-row">
|
||||
<p className="text-xs text-white/40">
|
||||
© {new Date().getFullYear()} Axil Accountants Ltd. All rights reserved.
|
||||
</p>
|
||||
<p className="text-xs text-white/40">
|
||||
ICAEW Member · ACCA Certified · Registered in England & Wales
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
);
|
||||
}
|
||||
206
src/components/sections/home/HeroSection.tsx
Normal file
206
src/components/sections/home/HeroSection.tsx
Normal file
|
|
@ -0,0 +1,206 @@
|
|||
import { Button } from '@/components/ui/Button';
|
||||
import { StarRating } from '@/components/ui/StarRating';
|
||||
import { CheckCircleIcon } from '@/components/ui/icons';
|
||||
import { ContainerScroll } from '@/components/ui/ContainerScroll';
|
||||
|
||||
const TRUST_ITEMS = [
|
||||
'ICAEW Member',
|
||||
'ACCA Certified',
|
||||
'500+ UK Businesses',
|
||||
'No lock-in contracts',
|
||||
];
|
||||
|
||||
/** Financial dashboard mockup shown inside the ContainerScroll 3D card */
|
||||
function DashboardMockup() {
|
||||
const bars = [40, 58, 44, 76, 52, 88, 68, 82, 96, 72, 90, 100];
|
||||
|
||||
return (
|
||||
<div className="bg-bg h-full w-full overflow-auto p-4 sm:p-6">
|
||||
{/* Dashboard header */}
|
||||
<div className="mb-5 flex items-center justify-between border-b border-black/6 pb-4">
|
||||
<div className="flex items-center gap-2">
|
||||
<svg width="28" height="18" viewBox="0 0 76 44" fill="none">
|
||||
<rect x="0" y="2" width="38" height="40" rx="5" fill="#1B9AD6" />
|
||||
<path d="M19 6 L34 40 H4 L19 6Z" fill="white" />
|
||||
<path d="M19 14 L27 32 H11 L19 14Z" fill="#1B9AD6" />
|
||||
<rect x="5" y="33" width="28" height="6" rx="1.5" fill="#3CC68A" />
|
||||
<rect x="45" y="30" width="7" height="14" rx="2" fill="#3CC68A" />
|
||||
<rect x="56" y="22" width="7" height="22" rx="2" fill="#3CC68A" />
|
||||
<rect x="67" y="11" width="7" height="33" rx="2" fill="#3CC68A" />
|
||||
</svg>
|
||||
<span className="font-display text-charcoal text-sm font-bold">Axil Client Portal</span>
|
||||
</div>
|
||||
<div className="flex items-center gap-2">
|
||||
<span className="text-muted text-xs">Tax Year 2024/25</span>
|
||||
<span className="bg-emerald size-2 animate-pulse rounded-full" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Stats row */}
|
||||
<div className="mb-5 grid grid-cols-3 gap-3">
|
||||
<div className="rounded-card bg-emerald-mist p-3">
|
||||
<p className="text-muted mb-1 text-[10px] font-medium tracking-wide uppercase">
|
||||
Revenue YTD
|
||||
</p>
|
||||
<p className="font-display text-emerald text-xl font-bold">£84,200</p>
|
||||
<p className="text-emerald mt-0.5 text-[10px] font-medium">↑ 18% YOY</p>
|
||||
</div>
|
||||
<div className="rounded-card bg-blue-mist p-3">
|
||||
<p className="text-muted mb-1 text-[10px] font-medium tracking-wide uppercase">
|
||||
Tax Saved
|
||||
</p>
|
||||
<p className="font-display text-blue text-xl font-bold">£12,400</p>
|
||||
<p className="text-blue mt-0.5 text-[10px] font-medium">This year</p>
|
||||
</div>
|
||||
<div className="rounded-card border border-black/6 bg-white p-3">
|
||||
<p className="text-muted mb-1 text-[10px] font-medium tracking-wide uppercase">
|
||||
Net Profit
|
||||
</p>
|
||||
<p className="font-display text-charcoal text-xl font-bold">£51,800</p>
|
||||
<p className="text-emerald mt-0.5 text-[10px] font-medium">↑ 24% YOY</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Monthly bar chart */}
|
||||
<div className="rounded-card mb-5 border border-black/6 bg-white p-4">
|
||||
<div className="mb-3 flex items-center justify-between">
|
||||
<p className="text-charcoal text-xs font-semibold">Monthly Revenue</p>
|
||||
<span className="rounded-pill bg-emerald-mist text-emerald px-2 py-0.5 text-[10px] font-medium">
|
||||
Apr 24 – Mar 25
|
||||
</span>
|
||||
</div>
|
||||
<div className="flex h-20 items-end gap-1">
|
||||
{bars.map((h, i) => (
|
||||
<div
|
||||
key={i}
|
||||
className="flex-1 rounded-t-sm transition-all"
|
||||
style={{
|
||||
height: `${h}%`,
|
||||
background:
|
||||
i === 11
|
||||
? 'var(--emerald)'
|
||||
: i >= 9
|
||||
? 'var(--emerald-light)'
|
||||
: 'var(--emerald-mist)',
|
||||
}}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
<div className="mt-1.5 flex justify-between">
|
||||
<span className="text-muted text-[9px]">Apr</span>
|
||||
<span className="text-muted text-[9px]">Mar</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Upcoming tasks */}
|
||||
<div className="space-y-2">
|
||||
{[
|
||||
{ label: 'VAT Return Q4', date: '7 May', done: false },
|
||||
{ label: 'Payroll — April', date: '30 Apr', done: true },
|
||||
{ label: 'Corporation Tax filed', date: '15 Apr', done: true },
|
||||
{ label: 'Self Assessment review', date: '31 Jan', done: true },
|
||||
].map((t) => (
|
||||
<div
|
||||
key={t.label}
|
||||
className="rounded-card flex items-center justify-between border border-black/5 bg-white px-3 py-2"
|
||||
>
|
||||
<div className="flex items-center gap-2">
|
||||
<span className={`size-1.5 rounded-full ${t.done ? 'bg-emerald' : 'bg-blue'}`} />
|
||||
<span className="text-charcoal text-xs">{t.label}</span>
|
||||
</div>
|
||||
<span
|
||||
className={`rounded-pill px-2.5 py-0.5 text-[10px] font-medium ${
|
||||
t.done ? 'bg-emerald-mist text-emerald' : 'bg-blue-mist text-blue'
|
||||
}`}
|
||||
>
|
||||
{t.date}
|
||||
</span>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function HeroTitle() {
|
||||
return (
|
||||
<div className="px-4 pt-24 pb-10">
|
||||
{/* Eyebrow */}
|
||||
<div className="animate-fade-in-up mb-6 flex justify-center">
|
||||
<div className="rounded-pill border-emerald/25 bg-emerald/8 flex items-center gap-1.5 border px-3.5 py-1.5">
|
||||
<span className="bg-emerald size-1.5 rounded-full" />
|
||||
<span className="text-emerald-dark text-xs font-semibold">
|
||||
Trusted by 500+ UK Businesses
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h1 className="animate-fade-in-up-d1 font-display text-charcoal mx-auto mb-6 max-w-3xl text-center text-[clamp(2.4rem,5vw,4.5rem)] leading-[1.04] font-bold tracking-tight">
|
||||
Smart Accounting for
|
||||
<br />
|
||||
Growing <span className="gradient-text">British Businesses</span>
|
||||
</h1>
|
||||
|
||||
<p className="animate-fade-in-up-d2 text-muted mx-auto mb-8 max-w-xl text-center text-lg leading-relaxed">
|
||||
ICAEW-certified accountants with fixed monthly fees, a dedicated account manager, and zero
|
||||
HMRC surprises. You focus on growth — we handle the numbers.
|
||||
</p>
|
||||
|
||||
<div className="animate-fade-in-up-d3 mb-8 flex flex-wrap justify-center gap-3">
|
||||
<Button size="lg" trailingArrow>
|
||||
Book a Free Consultation
|
||||
</Button>
|
||||
<Button size="lg" variant="secondary">
|
||||
See Our Services
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
{/* Trust indicators */}
|
||||
<div className="animate-fade-in-up-d4 flex flex-wrap items-center justify-center gap-x-5 gap-y-2">
|
||||
<div className="flex items-center gap-1.5">
|
||||
<StarRating rating={5} size="sm" />
|
||||
<span className="text-charcoal text-sm font-semibold">4.9/5</span>
|
||||
<span className="text-muted text-sm">Google</span>
|
||||
</div>
|
||||
<div className="hidden h-3.5 w-px bg-black/12 sm:block" />
|
||||
{TRUST_ITEMS.map((item) => (
|
||||
<span key={item} className="text-muted flex items-center gap-1.5 text-sm">
|
||||
<CheckCircleIcon size={13} color="var(--emerald)" />
|
||||
{item}
|
||||
</span>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export function HeroSection() {
|
||||
return (
|
||||
<section className="bg-bg relative mt-18 overflow-hidden">
|
||||
{/* Background gradients */}
|
||||
<div className="pointer-events-none absolute inset-0 bg-[radial-gradient(ellipse_70%_60%_at_50%_20%,var(--color-emerald-mist)_0%,transparent_70%)]" />
|
||||
<div className="pointer-events-none absolute inset-0">
|
||||
<div className="dot-grid h-full w-full opacity-30" />
|
||||
</div>
|
||||
|
||||
<div className="relative">
|
||||
<ContainerScroll titleComponent={<HeroTitle />}>
|
||||
<DashboardMockup />
|
||||
</ContainerScroll>
|
||||
</div>
|
||||
|
||||
{/* Trust strip */}
|
||||
<div className="relative z-10 border-t border-black/6 bg-white/70 backdrop-blur-sm">
|
||||
<div className="mx-auto flex max-w-[1440px] flex-wrap items-center justify-between gap-4 px-4 py-4 sm:px-6 lg:px-8 xl:px-16">
|
||||
<span className="text-charcoal text-sm font-semibold">🇬🇧 UK-Based Team</span>
|
||||
<div className="hidden h-4 w-px bg-black/10 sm:block" />
|
||||
<span className="text-muted text-sm">ICAEW Member · ACCA Certified</span>
|
||||
<div className="hidden h-4 w-px bg-black/10 sm:block" />
|
||||
<span className="text-muted text-sm">Fixed monthly fees — no hidden charges</span>
|
||||
<div className="hidden h-4 w-px bg-black/10 sm:block" />
|
||||
<span className="text-muted text-sm">Serving UK businesses since 2012</span>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
78
src/components/ui/TestimonialsColumn.tsx
Normal file
78
src/components/ui/TestimonialsColumn.tsx
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
'use client';
|
||||
|
||||
import React from 'react';
|
||||
import { motion } from 'framer-motion';
|
||||
|
||||
export interface TestimonialItem {
|
||||
text: string;
|
||||
image: string;
|
||||
name: string;
|
||||
role: string;
|
||||
rating?: number;
|
||||
}
|
||||
|
||||
export const TestimonialsColumn = ({
|
||||
className = '',
|
||||
testimonials,
|
||||
duration = 12,
|
||||
}: {
|
||||
className?: string;
|
||||
testimonials: TestimonialItem[];
|
||||
duration?: number;
|
||||
}) => (
|
||||
<div className={`overflow-hidden ${className}`}>
|
||||
<motion.div
|
||||
animate={{ translateY: '-50%' }}
|
||||
transition={{
|
||||
duration,
|
||||
repeat: Infinity,
|
||||
ease: 'linear',
|
||||
repeatType: 'loop',
|
||||
}}
|
||||
className="flex flex-col gap-5 pb-5"
|
||||
>
|
||||
{[...Array(2)].fill(0).map((_, dupIdx) => (
|
||||
<React.Fragment key={dupIdx}>
|
||||
{testimonials.map(({ text, image, name, role }, i) => (
|
||||
<div
|
||||
key={i}
|
||||
className="rounded-hero shadow-emerald/5 w-full max-w-xs border border-black/8 bg-white p-7 shadow-sm"
|
||||
>
|
||||
{/* Stars */}
|
||||
<div className="mb-3 flex gap-0.5">
|
||||
{[...Array(5)].map((_, s) => (
|
||||
<svg
|
||||
key={s}
|
||||
width="12"
|
||||
height="12"
|
||||
viewBox="0 0 12 12"
|
||||
fill="currentColor"
|
||||
className="text-emerald"
|
||||
>
|
||||
<path d="M6 0.5l1.5 3 3.3.5-2.4 2.3.6 3.2L6 7.9l-3 1.6.6-3.2L1.2 4l3.3-.5z" />
|
||||
</svg>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<p className="text-charcoal mb-5 text-sm leading-relaxed">“{text}”</p>
|
||||
|
||||
<div className="flex items-center gap-3">
|
||||
<img
|
||||
width={40}
|
||||
height={40}
|
||||
src={image}
|
||||
alt={name}
|
||||
className="size-10 rounded-full object-cover"
|
||||
/>
|
||||
<div>
|
||||
<p className="text-charcoal text-sm leading-tight font-semibold">{name}</p>
|
||||
<p className="text-muted text-xs leading-tight">{role}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</React.Fragment>
|
||||
))}
|
||||
</motion.div>
|
||||
</div>
|
||||
);
|
||||
130
src/components/ui/TextHoverEffect.tsx
Normal file
130
src/components/ui/TextHoverEffect.tsx
Normal file
|
|
@ -0,0 +1,130 @@
|
|||
'use client';
|
||||
|
||||
import React, { useEffect, useRef, useState } from 'react';
|
||||
import { motion } from 'framer-motion';
|
||||
import { cn } from '@/lib/utils';
|
||||
|
||||
export const TextHoverEffect = ({
|
||||
text,
|
||||
duration,
|
||||
className,
|
||||
}: {
|
||||
text: string;
|
||||
duration?: number;
|
||||
automatic?: boolean;
|
||||
className?: string;
|
||||
}) => {
|
||||
const svgRef = useRef<SVGSVGElement>(null);
|
||||
const [cursor, setCursor] = useState({ x: 0, y: 0 });
|
||||
const [hovered, setHovered] = useState(false);
|
||||
const [maskPosition, setMaskPosition] = useState({ cx: '50%', cy: '50%' });
|
||||
|
||||
useEffect(() => {
|
||||
if (svgRef.current && cursor.x !== null && cursor.y !== null) {
|
||||
const svgRect = svgRef.current.getBoundingClientRect();
|
||||
const cxPercentage = ((cursor.x - svgRect.left) / svgRect.width) * 100;
|
||||
const cyPercentage = ((cursor.y - svgRect.top) / svgRect.height) * 100;
|
||||
setMaskPosition({
|
||||
cx: `${cxPercentage}%`,
|
||||
cy: `${cyPercentage}%`,
|
||||
});
|
||||
}
|
||||
}, [cursor]);
|
||||
|
||||
return (
|
||||
<svg
|
||||
ref={svgRef}
|
||||
width="100%"
|
||||
height="100%"
|
||||
viewBox="0 0 300 100"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
onMouseEnter={() => setHovered(true)}
|
||||
onMouseLeave={() => setHovered(false)}
|
||||
onMouseMove={(e) => setCursor({ x: e.clientX, y: e.clientY })}
|
||||
className={cn('cursor-pointer uppercase select-none', className)}
|
||||
>
|
||||
<defs>
|
||||
<linearGradient id="textGradient" gradientUnits="userSpaceOnUse" cx="50%" cy="50%" r="25%">
|
||||
{hovered && (
|
||||
<>
|
||||
<stop offset="0%" stopColor="var(--color-emerald)" />
|
||||
<stop offset="35%" stopColor="var(--color-blue)" />
|
||||
<stop offset="65%" stopColor="var(--color-emerald)" />
|
||||
<stop offset="100%" stopColor="var(--color-emerald-dark)" />
|
||||
</>
|
||||
)}
|
||||
</linearGradient>
|
||||
|
||||
{/* @ts-expect-error — motion.radialGradient is valid framer-motion SVG element */}
|
||||
<motion.radialGradient
|
||||
id="revealMask"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
r="20%"
|
||||
initial={{ cx: '50%', cy: '50%' }}
|
||||
animate={maskPosition}
|
||||
transition={{ duration: duration ?? 0, ease: 'easeOut' }}
|
||||
>
|
||||
<stop offset="0%" stopColor="white" />
|
||||
<stop offset="100%" stopColor="black" />
|
||||
</motion.radialGradient>
|
||||
|
||||
<mask id="textMask">
|
||||
<rect x="0" y="0" width="100%" height="100%" fill="url(#revealMask)" />
|
||||
</mask>
|
||||
</defs>
|
||||
|
||||
{/* Stroke outline — visible on hover */}
|
||||
<text
|
||||
x="50%"
|
||||
y="50%"
|
||||
textAnchor="middle"
|
||||
dominantBaseline="middle"
|
||||
strokeWidth="0.3"
|
||||
className="fill-transparent stroke-white/20 font-[helvetica] text-7xl font-bold"
|
||||
style={{ opacity: hovered ? 0.7 : 0 }}
|
||||
>
|
||||
{text}
|
||||
</text>
|
||||
|
||||
{/* Animated draw-on stroke */}
|
||||
<motion.text
|
||||
x="50%"
|
||||
y="50%"
|
||||
textAnchor="middle"
|
||||
dominantBaseline="middle"
|
||||
strokeWidth="0.3"
|
||||
className="fill-transparent font-[helvetica] text-7xl font-bold"
|
||||
style={{ stroke: 'var(--color-emerald)' }}
|
||||
initial={{ strokeDashoffset: 1000, strokeDasharray: 1000 }}
|
||||
animate={{ strokeDashoffset: 0, strokeDasharray: 1000 }}
|
||||
transition={{ duration: 4, ease: 'easeInOut' }}
|
||||
>
|
||||
{text}
|
||||
</motion.text>
|
||||
|
||||
{/* Colour reveal on mouse move */}
|
||||
<text
|
||||
x="50%"
|
||||
y="50%"
|
||||
textAnchor="middle"
|
||||
dominantBaseline="middle"
|
||||
stroke="url(#textGradient)"
|
||||
strokeWidth="0.3"
|
||||
mask="url(#textMask)"
|
||||
className="fill-transparent font-[helvetica] text-7xl font-bold"
|
||||
>
|
||||
{text}
|
||||
</text>
|
||||
</svg>
|
||||
);
|
||||
};
|
||||
|
||||
export const FooterBackgroundGradient = () => (
|
||||
<div
|
||||
className="absolute inset-0 z-0"
|
||||
style={{
|
||||
background:
|
||||
'radial-gradient(125% 125% at 50% 10%, rgba(22,37,32,0.6) 50%, rgba(27,154,214,0.15) 100%)',
|
||||
}}
|
||||
/>
|
||||
);
|
||||
30
src/components/ui/icons/StarIcon.tsx
Normal file
30
src/components/ui/icons/StarIcon.tsx
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
interface StarIconProps {
|
||||
size?: number;
|
||||
color?: string;
|
||||
className?: string;
|
||||
filled?: boolean;
|
||||
}
|
||||
|
||||
export function StarIcon({
|
||||
size = 16,
|
||||
color = 'currentColor',
|
||||
className = '',
|
||||
filled = false,
|
||||
}: StarIconProps) {
|
||||
return (
|
||||
<svg
|
||||
width={size}
|
||||
height={size}
|
||||
viewBox="0 0 24 24"
|
||||
fill={filled ? 'var(--color-emerald)' : 'none'}
|
||||
stroke={filled ? 'var(--color-emerald)' : color}
|
||||
strokeWidth="2"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
className={className}
|
||||
aria-hidden="true"
|
||||
>
|
||||
<polygon points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2" />
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue