feat(portfolio): mise à jour du site avec de nouvelles sections et améliorations SEO

- Révision des métadonnées dans index.html pour un meilleur référencement.
- Ajout de nouvelles sections : FAQ, Témoignages, Services, et CTA.
- Intégration de données structurées pour les FAQ et les témoignages.
- Amélioration du fichier robots.txt pour un meilleur contrôle d'indexation.
- Mise à jour du sitemap.xml avec de nouvelles URLs.
- Ajout de nouveaux composants Vue.js pour les sections de témoignages et de services.
- Amélioration des styles CSS pour une meilleure présentation des sections.
- Ajout de la gestion des dates et des témoignages dans le composant testimonials.
This commit is contained in:
Mr¤KayJayDee
2025-06-25 23:25:51 +02:00
parent af1f47dbf3
commit 542c468eb3
35 changed files with 2712 additions and 472 deletions

View File

@@ -6,34 +6,40 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<!-- Primary Meta Tags --> <!-- Primary Meta Tags -->
<title>Killian - Full Stack Developer | Vue.js, React, Node.js Expert</title> <title>Full Stack Developer Freelance Vue.js React Node.js | Killian Dalcin</title>
<meta name="title" content="Killian - Full Stack Developer | Vue.js, React, Node.js Expert"> <meta name="title" content="Full Stack Developer Freelance Vue.js React Node.js | Killian Dalcin">
<meta name="description" <meta name="description"
content="Full Stack Developer specializing in Vue.js, React, Node.js. Expert in Discord bots, web apps & custom solutions. Available for freelance."> content="Expert Full Stack Developer freelance specialized in Vue.js, React and Node.js. ✅ Custom web application development ✅ Professional Discord bots ✅ High-performance APIs. Free quote within 24h.">
<meta name="keywords" <meta name="keywords"
content="full stack developer, web developer, Vue.js developer, React developer, Node.js developer, JavaScript developer, Discord bot developer, freelance developer, web development services, custom software solutions"> content="full stack developer freelance, vue.js developer freelance, react developer freelance, node.js developer freelance, custom discord bot development, enterprise web application development, javascript typescript expert, rest api graphql developer, freelance web developer france, saas mvp startup development">
<meta name="author" content="Killian"> <meta name="author" content="Killian Dalcin">
<meta name="robots" content="index, follow"> <meta name="robots" content="index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1">
<meta name="language" content="English"> <meta name="language" content="English">
<meta name="revisit-after" content="7 days"> <meta name="revisit-after" content="3 days">
<meta name="geo.region" content="FR">
<meta name="geo.placename" content="France">
<!-- Open Graph / Facebook --> <!-- Open Graph / Facebook -->
<meta property="og:type" content="website"> <meta property="og:type" content="website">
<meta property="og:url" content="https://killiandalcin.fr"> <meta property="og:url" content="https://killiandalcin.fr">
<meta property="og:title" content="Killian - Full Stack Developer | Vue.js, React, Node.js Expert"> <meta property="og:title" content="Full Stack Developer Freelance Vue.js React Node.js | Killian Dalcin">
<meta property="og:description" <meta property="og:description"
content="Professional Full Stack Developer specializing in modern web development. Expert in Discord bots, web applications, and custom solutions."> content="Need an expert Full Stack Developer? I create custom web applications, Discord bots and high-performance APIs. Modern technologies, clean code, fast delivery. Free consultation.">
<meta property="og:image" content="/portfolio-preview.webp"> <meta property="og:image" content="https://killiandalcin.fr/portfolio-preview.webp">
<meta property="og:image:width" content="1200">
<meta property="og:image:height" content="630">
<meta property="og:locale" content="en_US"> <meta property="og:locale" content="en_US">
<meta property="og:site_name" content="Killian Portfolio"> <meta property="og:locale:alternate" content="fr_FR">
<meta property="og:site_name" content="Killian Dalcin - Full Stack Developer">
<!-- Twitter --> <!-- Twitter -->
<meta property="twitter:card" content="summary_large_image"> <meta property="twitter:card" content="summary_large_image">
<meta property="twitter:url" content="https://killiandalcin.fr"> <meta property="twitter:url" content="https://killiandalcin.fr">
<meta property="twitter:title" content="Killian - Full Stack Developer | Vue.js, React, Node.js Expert"> <meta property="twitter:title" content="Full Stack Developer Freelance Vue.js React Node.js | Killian Dalcin">
<meta property="twitter:description" <meta property="twitter:description"
content="Professional Full Stack Developer specializing in modern web development. Expert in Discord bots, web applications, and custom solutions."> content="Expert Full Stack Developer freelance. Custom web application development, Discord bots, high-performance APIs. Vue.js, React, Node.js. Free quote within 24h.">
<meta property="twitter:image" content="/portfolio-preview.webp"> <meta property="twitter:image" content="https://killiandalcin.fr/portfolio-preview.webp">
<meta property="twitter:creator" content="@killiandalcin">
<!-- Canonical URL --> <!-- Canonical URL -->
<link rel="canonical" href="https://killiandalcin.fr"> <link rel="canonical" href="https://killiandalcin.fr">
@@ -54,25 +60,165 @@
<script type="application/ld+json"> <script type="application/ld+json">
{ {
"@context": "https://schema.org", "@context": "https://schema.org",
"@type": "Person", "@type": "ProfessionalService",
"name": "Killian", "@id": "https://killiandalcin.fr/#organization",
"jobTitle": "Full Stack Developer", "name": "Killian Dalcin - Full Stack Developer Freelance",
"description": "Professional Full Stack Developer specializing in Vue.js, React, Node.js, and modern web technologies", "alternateName": "Killian Dev",
"url": "https://killiandalcin.fr", "url": "https://killiandalcin.fr",
"sameAs": [ "logo": "https://killiandalcin.fr/logo.webp",
"https://github.com/killian", "image": "https://killiandalcin.fr/portfolio-preview.webp",
"https://linkedin.com/in/killian", "description": "Full Stack Developer freelance expert in Vue.js, React and Node.js. Specialized in custom web application development, professional Discord bots and high-performance APIs.",
"https://www.fiverr.com/users/mr_kayjaydee" "priceRange": "€€€",
], "telephone": "+33-649-193-816",
"knowsAbout": ["Vue.js", "React", "Node.js", "JavaScript", "TypeScript", "Web Development", "Discord Bot Development", "API Development"], "email": "contact@killiandalcin.fr",
"offers": { "address": {
"@type": "Offer", "@type": "PostalAddress",
"itemOffered": { "addressCountry": "FR",
"@type": "Service", "addressRegion": "France"
"name": "Web Development Services", },
"description": "Custom web development, Discord bots, and software solutions" "openingHoursSpecification": {
"@type": "OpeningHoursSpecification",
"dayOfWeek": ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday"],
"opens": "09:00",
"closes": "18:00"
},
"founder": {
"@type": "Person",
"name": "Killian Dalcin",
"jobTitle": "Senior Full Stack Developer",
"alumniOf": "Computer Engineering School",
"knowsAbout": ["Vue.js", "React", "Node.js", "TypeScript", "JavaScript", "MongoDB", "PostgreSQL", "Docker", "REST API", "GraphQL", "Discord.js", "Web Development", "Software Architecture"],
"sameAs": [
"https://github.com/killiandalcin",
"https://linkedin.com/in/killian-dalcin",
"https://www.fiverr.com/users/mr_kayjaydee",
"https://twitter.com/killiandalcin"
]
},
"hasOfferCatalog": {
"@type": "OfferCatalog",
"name": "Web Development Services",
"itemListElement": [
{
"@type": "Offer",
"itemOffered": {
"@type": "Service",
"name": "Vue.js/React Web Application Development",
"description": "Creation of modern and high-performance web applications with Vue.js or React. Responsive user interface, SEO optimization, scalable architecture."
}
},
{
"@type": "Offer",
"itemOffered": {
"@type": "Service",
"name": "Node.js Backend Development & API",
"description": "Design of robust REST and GraphQL APIs with Node.js. Microservices architecture, secure authentication, optimal performance."
}
},
{
"@type": "Offer",
"itemOffered": {
"@type": "Service",
"name": "Custom Discord Bot Development",
"description": "Development of professional Discord bots with advanced features. Moderation, music, games, API integrations, web dashboard."
}
},
{
"@type": "Offer",
"itemOffered": {
"@type": "Service",
"name": "Maintenance & Technical Support",
"description": "Continuous maintenance, security updates and technical support for your applications. 24/7 monitoring and rapid interventions."
}
}
]
},
"aggregateRating": {
"@type": "AggregateRating",
"ratingValue": "5",
"bestRating": "5",
"worstRating": "1",
"ratingCount": "47",
"reviewCount": "47"
},
"review": [
{
"@type": "Review",
"reviewRating": {
"@type": "Rating",
"ratingValue": "5",
"bestRating": "5"
},
"author": {
"@type": "Person",
"name": "Marie L."
},
"reviewBody": "Excellent developer! Vue.js application delivered on time with exceptional code quality. I highly recommend."
},
{
"@type": "Review",
"reviewRating": {
"@type": "Rating",
"ratingValue": "5",
"bestRating": "5"
},
"author": {
"@type": "Person",
"name": "Thomas B."
},
"reviewBody": "Discord bot working perfectly with all requested features. Responsive and professional support. Thank you!"
} }
} ]
}
</script>
<!-- Breadcrumb Schema -->
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "BreadcrumbList",
"itemListElement": [
{
"@type": "ListItem",
"position": 1,
"name": "Home",
"item": "https://killiandalcin.fr"
}
]
}
</script>
<!-- FAQ Schema -->
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "FAQPage",
"mainEntity": [
{
"@type": "Question",
"name": "What are your rates for custom web development?",
"acceptedAnswer": {
"@type": "Answer",
"text": "My rates vary according to project complexity. A simple web application starts from €2000, while a complex platform can go up to €15000+. I always provide a detailed free quote within 24h after analyzing your needs."
}
},
{
"@type": "Question",
"name": "How long does it take to develop a Vue.js application?",
"acceptedAnswer": {
"@type": "Answer",
"text": "The timeline depends on complexity: a simple application (3-5 pages) takes 2-3 weeks, a medium application (10-15 pages with backend) 4-8 weeks, and a complex platform 2-4 months. I always provide a detailed schedule."
}
},
{
"@type": "Question",
"name": "Do you offer maintenance after delivery?",
"acceptedAnswer": {
"@type": "Answer",
"text": "Yes, I offer monthly maintenance contracts including: security updates, bug fixes, small evolutions, 24/7 monitoring and technical support. Rates start from €300/month depending on your needs."
}
}
]
} }
</script> </script>
<script defer src="https://umami.killiandalcin.fr/script.js" <script defer src="https://umami.killiandalcin.fr/script.js"

View File

@@ -1,33 +1,30 @@
# Robots.txt for Killian Portfolio # Robots.txt pour killiandalcin.fr
# https://killiandalcin.fr # Optimisé pour un crawling Google efficace
# Allow all crawlers # Googlebot
User-agent: *
Allow: /
Disallow: /api/
Disallow: /admin/
Disallow: /.git/
Disallow: /node_modules/
# Sitemap location
Sitemap: https://killiandalcin.fr/sitemap.xml
# Crawl-delay for respectful crawling
Crawl-delay: 1
# Special rules for major search engines
User-agent: Googlebot User-agent: Googlebot
Allow: / Allow: /
Crawl-delay: 0 Crawl-delay: 0
# Bingbot
User-agent: Bingbot User-agent: Bingbot
Allow: / Allow: /
Crawl-delay: 0
User-agent: Slurp
Allow: /
Crawl-delay: 1 Crawl-delay: 1
User-agent: DuckDuckBot # Tous les bots légitimes
User-agent: *
Allow: / Allow: /
Crawl-delay: 1 Disallow: /api/
Disallow: /admin/
Disallow: /*.json$
Disallow: /*?*
Allow: /*.css$
Allow: /*.js$
Allow: /*.webp$
Allow: /*.jpg$
Allow: /*.png$
Allow: /*.svg$
Allow: /*.woff2$
# Sitemap
Sitemap: https://killiandalcin.fr/sitemap.xml

View File

@@ -3,87 +3,129 @@
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.sitemaps.org/schemas/sitemap/0.9 http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd"> xsi:schemaLocation="http://www.sitemaps.org/schemas/sitemap/0.9 http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd">
<!-- Homepage --> <!-- Page d'accueil - Priorité maximale -->
<url> <url>
<loc>https://killiandalcin.fr/</loc> <loc>https://killiandalcin.fr/</loc>
<lastmod>2025-06-22T00:00:00+00:00</lastmod> <lastmod>2025-06-25</lastmod>
<changefreq>weekly</changefreq> <changefreq>weekly</changefreq>
<priority>1.0</priority> <priority>1.0</priority>
</url> </url>
<!-- Projects Page --> <!-- Page Services Fiverr - Haute priorité (conversions) -->
<url> <url>
<loc>https://killiandalcin.fr/projects</loc> <loc>https://killiandalcin.fr/fiverr</loc>
<lastmod>2025-06-22T00:00:00+00:00</lastmod> <lastmod>2025-06-25</lastmod>
<changefreq>weekly</changefreq> <changefreq>weekly</changefreq>
<priority>0.9</priority> <priority>0.9</priority>
</url> </url>
<!-- About Page --> <!-- Page Projets/Portfolio -->
<url> <url>
<loc>https://killiandalcin.fr/about</loc> <loc>https://killiandalcin.fr/projects</loc>
<lastmod>2025-06-22T00:00:00+00:00</lastmod> <lastmod>2025-06-25</lastmod>
<changefreq>monthly</changefreq>
<priority>0.8</priority>
</url>
<!-- Contact Page -->
<url>
<loc>https://killiandalcin.fr/contact</loc>
<lastmod>2025-06-22T00:00:00+00:00</lastmod>
<changefreq>monthly</changefreq>
<priority>0.8</priority>
</url>
<!-- Fiverr Services Page -->
<url>
<loc>https://killiandalcin.fr/fiverr</loc>
<lastmod>2025-06-22T00:00:00+00:00</lastmod>
<changefreq>weekly</changefreq> <changefreq>weekly</changefreq>
<priority>0.8</priority> <priority>0.8</priority>
</url> </url>
<!-- Individual Project Pages --> <!-- Page Contact -->
<url> <url>
<loc>https://killiandalcin.fr/project/virtual-tour</loc> <loc>https://killiandalcin.fr/contact</loc>
<lastmod>2025-06-22T00:00:00+00:00</lastmod> <lastmod>2025-06-25</lastmod>
<changefreq>monthly</changefreq>
<priority>0.8</priority>
</url>
<!-- Page À Propos -->
<url>
<loc>https://killiandalcin.fr/about</loc>
<lastmod>2025-06-25</lastmod>
<changefreq>monthly</changefreq>
<priority>0.7</priority>
</url>
<!-- Pages de projets individuels -->
<url>
<loc>https://killiandalcin.fr/projects/xinko</loc>
<lastmod>2025-06-25</lastmod>
<changefreq>monthly</changefreq>
<priority>0.6</priority>
</url>
<url>
<loc>https://killiandalcin.fr/projects/flowboard</loc>
<lastmod>2025-06-25</lastmod>
<changefreq>monthly</changefreq>
<priority>0.6</priority>
</url>
<url>
<loc>https://killiandalcin.fr/projects/virtual-tour</loc>
<lastmod>2025-06-25</lastmod>
<changefreq>monthly</changefreq>
<priority>0.6</priority>
</url>
<url>
<loc>https://killiandalcin.fr/projects/image-manipulation</loc>
<lastmod>2025-06-25</lastmod>
<changefreq>monthly</changefreq>
<priority>0.6</priority>
</url>
<url>
<loc>https://killiandalcin.fr/projects/primate-web-admin</loc>
<lastmod>2025-06-25</lastmod>
<changefreq>monthly</changefreq>
<priority>0.6</priority>
</url>
<url>
<loc>https://killiandalcin.fr/projects/instagram-bot</loc>
<lastmod>2025-06-25</lastmod>
<changefreq>monthly</changefreq>
<priority>0.6</priority>
</url>
<url>
<loc>https://killiandalcin.fr/projects/crowdin-status-bot</loc>
<lastmod>2025-06-25</lastmod>
<changefreq>monthly</changefreq>
<priority>0.6</priority>
</url>
<!-- Version anglaise -->
<url>
<loc>https://killiandalcin.fr/en</loc>
<lastmod>2025-06-25</lastmod>
<changefreq>weekly</changefreq>
<priority>0.9</priority>
</url>
<url>
<loc>https://killiandalcin.fr/en/fiverr</loc>
<lastmod>2025-06-25</lastmod>
<changefreq>weekly</changefreq>
<priority>0.8</priority>
</url>
<url>
<loc>https://killiandalcin.fr/en/projects</loc>
<lastmod>2025-06-25</lastmod>
<changefreq>weekly</changefreq>
<priority>0.7</priority>
</url>
<url>
<loc>https://killiandalcin.fr/en/contact</loc>
<lastmod>2025-06-25</lastmod>
<changefreq>monthly</changefreq> <changefreq>monthly</changefreq>
<priority>0.7</priority> <priority>0.7</priority>
</url> </url>
<url> <url>
<loc>https://killiandalcin.fr/project/xinko</loc> <loc>https://killiandalcin.fr/en/about</loc>
<lastmod>2025-06-22T00:00:00+00:00</lastmod> <lastmod>2025-06-25</lastmod>
<changefreq>monthly</changefreq> <changefreq>monthly</changefreq>
<priority>0.7</priority> <priority>0.6</priority>
</url> </url>
<url>
<loc>https://killiandalcin.fr/project/image-manipulation</loc>
<lastmod>2025-06-22T00:00:00+00:00</lastmod>
<changefreq>monthly</changefreq>
<priority>0.7</priority>
</url>
<url>
<loc>https://killiandalcin.fr/project/primate-web-admin</loc>
<lastmod>2025-06-22T00:00:00+00:00</lastmod>
<changefreq>monthly</changefreq>
<priority>0.7</priority>
</url>
<url>
<loc>https://killiandalcin.fr/project/instagram-bot</loc>
<lastmod>2025-06-22T00:00:00+00:00</lastmod>
<changefreq>monthly</changefreq>
<priority>0.7</priority>
</url>
<url>
<loc>https://killiandalcin.fr/project/crowdin-status-bot</loc>
<lastmod>2025-06-22T00:00:00+00:00</lastmod>
<changefreq>monthly</changefreq>
<priority>0.7</priority>
</url>
</urlset> </urlset>

View File

@@ -0,0 +1,70 @@
<template>
<section class="faq-section">
<div class="container">
<div class="faq-header text-center mb-2xl">
<h2 class="section-title">{{ title }}</h2>
<p class="section-subtitle">{{ subtitle }}</p>
</div>
<div class="faq-grid">
<div v-for="(faq, index) in faqs" :key="index" class="faq-item" :class="{ 'active': activeIndex === index }">
<button class="faq-question" @click="toggleFAQ(index)" :aria-expanded="activeIndex === index">
<span class="question-text">{{ faq.question }}</span>
<svg class="faq-icon" :class="{ 'rotated': activeIndex === index }" fill="none" stroke="currentColor"
viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7">
</path>
</svg>
</button>
<div class="faq-answer" :class="{ 'open': activeIndex === index }">
<div class="answer-content">
<p v-html="faq.answer"></p>
<div v-if="faq.features" class="faq-features">
<h4>{{ t('faq.keyPoints') }}</h4>
<ul>
<li v-for="feature in faq.features" :key="feature">{{ feature }}</li>
</ul>
</div>
</div>
</div>
</div>
</div>
</div>
</section>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { useI18n } from '@/composables/useI18n'
const { t } = useI18n()
interface FAQ {
question: string
answer: string
features?: string[]
}
interface Props {
title: string
subtitle: string
faqs: FAQ[]
ctaTitle: string
ctaSubtitle: string
ctaText: string
ctaLink: string
}
defineProps<Props>()
const activeIndex = ref<number | null>(null)
const toggleFAQ = (index: number) => {
activeIndex.value = activeIndex.value === index ? null : index
}
</script>
<style scoped>
@import './styles/ServiceFAQ.css';
</style>

View File

@@ -0,0 +1,76 @@
<template>
<section class="testimonials-section">
<div class="container">
<!-- Header -->
<div class="testimonials-header">
<h2 class="section-title">{{ title }}</h2>
<p class="section-subtitle">{{ subtitle }}</p>
<!-- Stats -->
<TestimonialsStats :stats="stats" :labels="statsLabels" />
</div>
<!-- Testimonials Grid -->
<div class="testimonials-grid">
<TestimonialCard v-for="(testimonial, index) in testimonials" :key="index" :testimonial="testimonial"
:class="{ 'featured': testimonial.featured }" />
</div>
<!-- CTA -->
<TestimonialsCTA :title="ctaTitle" :subtitle="ctaSubtitle" :text="ctaText" :link="ctaLink"
:reviews-link="reviewsLink" :reviews-text="reviewsText" />
</div>
</section>
</template>
<script setup lang="ts">
import TestimonialsStats from '@/components/testimonials/TestimonialsStats.vue'
import TestimonialCard from '@/components/testimonials/TestimonialCard.vue'
import TestimonialsCTA from '@/components/testimonials/TestimonialsCTA.vue'
interface Testimonial {
name: string
role: string
company: string
avatar: string
rating: number
content: string
date: string
platform: string
featured?: boolean
project_type: string
results?: string[]
}
interface Stats {
totalReviews: number
averageRating: number
projectsCompleted: number
}
interface StatsLabels {
clients: string
rating: string
projects: string
}
interface Props {
title: string
subtitle: string
testimonials: Testimonial[]
stats: Stats
statsLabels: StatsLabels
ctaTitle: string
ctaSubtitle: string
ctaText: string
ctaLink: string
reviewsLink: string
reviewsText: string
}
defineProps<Props>()
</script>
<style scoped>
@import '@/components/styles/TestimonialsSection.css';
</style>

View File

@@ -0,0 +1,16 @@
<template>
<section class="section">
<div class="container">
<SectionCTA :question="t('home.cta2.title')" :description="t('home.cta2.subtitle')"
:primary-text="t('home.cta2.startProject')" primary-link="/contact" :secondary-text="t('home.cta2.learnMore')"
secondary-link="/about" />
</div>
</section>
</template>
<script setup lang="ts">
import { useI18n } from '@/composables/useI18n'
import SectionCTA from '@/components/shared/SectionCTA.vue'
const { t } = useI18n()
</script>

View File

@@ -0,0 +1,48 @@
<template>
<section class="section">
<div class="container">
<div class="text-center mb-2xl">
<h2 class="mb-lg">{{ t('home.featuredProjects.title') }}</h2>
<p class="text-xl text-secondary max-w-2xl mx-auto">
{{ t('home.featuredProjects.subtitle') }}
</p>
</div>
<div class="projects-grid">
<ProjectCard v-for="project in featuredProjects" :key="project.id" :project="project"
class="animate-fade-in-up" />
</div>
<div class="text-center">
<CTAButtons layout="stack">
<RouterLink to="/projects" class="btn btn-secondary">
{{ t('home.featuredProjects.viewAll') }}
<svg class="btn-icon" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M17 8l4 4m0 0l-4 4m4-4H3"></path>
</svg>
</RouterLink>
</CTAButtons>
</div>
</div>
</section>
</template>
<script setup lang="ts">
import { computed } from 'vue'
import { useI18n } from '@/composables/useI18n'
import { useProjects } from '@/composables/useProjects'
import ProjectCard from '@/components/ProjectCard.vue'
import CTAButtons from '@/components/shared/CTAButtons.vue'
const { t } = useI18n()
const { projects } = useProjects()
// Featured projects
const featuredProjects = computed(() => {
return projects.value.filter(project => project.featured).slice(0, 3)
})
</script>
<style scoped>
@import '@/components/styles/FeaturedProjectsSection.css';
</style>

View File

@@ -0,0 +1,46 @@
<template>
<section class="hero">
<div class="container">
<div class="hero-content animate-fade-in-up">
<h1 class="hero-title">
{{ t('home.title') }}
</h1>
<p class="hero-subtitle">
{{ t('home.subtitle') }}
</p>
<CTAButtons layout="columns">
<RouterLink to="/projects" class="btn btn-primary btn-lg">
{{ t('home.cta.viewProjects') }}
<svg class="btn-icon" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 7l5 5m0 0l-5 5m5-5H6">
</path>
</svg>
</RouterLink>
<RouterLink to="/fiverr" class="btn btn-secondary btn-lg">
{{ t('nav.fiverr') }}
<svg class="btn-icon" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
d="M12 8c-1.657 0-3 .895-3 2s1.343 2 3 2 3 .895 3 2-1.343 2-3 2m0-8c1.11 0 2.08.402 2.599 1M12 8V7m0 1v8m0 0v1m0-1c-1.11 0-2.08-.402-2.599-1M21 12a9 9 0 11-18 0 9 9 0 0118 0z">
</path>
</svg>
</RouterLink>
<RouterLink to="/contact" class="btn btn-secondary btn-lg">
{{ t('home.cta.contactMe') }}
<svg class="btn-icon" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
d="M8 12h.01M12 12h.01M16 12h.01M21 12c0 4.418-4.03 8-9 8a9.863 9.863 0 01-4.255-.949L3 20l1.395-3.72C3.512 15.042 3 13.574 3 12c0-4.418 4.03-8 9-8s9 3.582 9 8z">
</path>
</svg>
</RouterLink>
</CTAButtons>
</div>
</div>
</section>
</template>
<script setup lang="ts">
import { useI18n } from '@/composables/useI18n'
import CTAButtons from '@/components/shared/CTAButtons.vue'
const { t } = useI18n()
</script>

View File

@@ -0,0 +1,70 @@
<template>
<section class="services-section">
<div class="container">
<div class="text-center mb-2xl">
<h2 class="mb-lg">{{ t('home.services.title') }}</h2>
<p class="text-xl text-secondary max-w-2xl mx-auto">
{{ t('home.services.subtitle') }}
</p>
</div>
<div class="services-grid">
<div v-for="(service, index) in services" :key="index" class="card animate-fade-in-up"
:style="{ 'animation-delay': `${index * 0.1}s` }">
<div class="card-body">
<div class="flex items-start">
<div class="service-icon" :style="{ background: service.color, color: 'var(--text-inverse)' }">
<svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" :d="service.icon"></path>
</svg>
</div>
<div>
<h3 class="text-xl font-bold mb-md">{{ service.title }}</h3>
<p class="text-secondary">{{ service.description }}</p>
</div>
</div>
</div>
</div>
</div>
</div>
</section>
</template>
<script setup lang="ts">
import { computed } from 'vue'
import { useI18n } from '@/composables/useI18n'
const { t } = useI18n()
// Services data
const services = computed(() => [
{
icon: 'M9.75 17L9 20l-1 1h8l-1-1-.75-3M3 13h18M5 17h14a2 2 0 002-2V5a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z',
color: 'var(--color-primary)',
title: t('home.services.webDev.title'),
description: t('home.services.webDev.description')
},
{
icon: 'M12 18h.01M8 21h8a2 2 0 002-2V5a2 2 0 00-2-2H8a2 2 0 00-2 2v14a2 2 0 002 2z',
color: 'var(--color-secondary)',
title: t('home.services.mobileApps.title'),
description: t('home.services.mobileApps.description')
},
{
icon: 'M13 10V3L4 14h7v7l9-11h-7z',
color: 'var(--color-success)',
title: t('home.services.optimization.title'),
description: t('home.services.optimization.description')
},
{
icon: 'M10.325 4.317c.426-1.756 2.924-1.756 3.35 0a1.724 1.724 0 002.573 1.066c1.543-.94 3.31.826 2.37 2.37a1.724 1.724 0 001.065 2.572c1.756.426 1.756 2.924 0 3.35a1.724 1.724 0 00-1.066 2.573c.94 1.543-.826 3.31-2.37 2.37a1.724 1.724 0 00-2.572 1.065c-.426 1.756-2.924 1.756-3.35 0a1.724 1.724 0 00-2.573-1.066c-1.543.94-3.31-.826-2.37-2.37a1.724 1.724 0 00-1.065-2.572c-1.756-.426-1.756-2.924 0-3.35a1.724 1.724 0 001.066-2.573c-.94-1.543.826-3.31 2.37-2.37.996.608 2.296.07 2.572-1.065z',
color: 'var(--color-warning)',
title: t('home.services.maintenance.title'),
description: t('home.services.maintenance.description')
}
])
</script>
<style scoped>
@import '@/components/styles/ServicesSection.css';
</style>

View File

@@ -0,0 +1,36 @@
<template>
<div class="cta-buttons-container">
<div class="cta-buttons" :class="layoutClass">
<slot></slot>
</div>
</div>
</template>
<script setup lang="ts">
import { computed } from 'vue'
interface Props {
layout?: 'columns' | 'row' | 'stack'
maxButtons?: number
}
const props = withDefaults(defineProps<Props>(), {
layout: 'columns',
maxButtons: 3
})
const layoutClass = computed(() => {
switch (props.layout) {
case 'row':
return 'cta-buttons--row'
case 'stack':
return 'cta-buttons--stack'
default:
return 'cta-buttons--columns'
}
})
</script>
<style scoped>
@import '@/components/styles/CTAButtons.css';
</style>

View File

@@ -0,0 +1,58 @@
<template>
<div class="section-cta">
<div class="cta-content">
<h3 class="cta-question">{{ question }}</h3>
<p class="cta-description">{{ description }}</p>
<CTAButtons layout="columns">
<RouterLink :to="primaryLink" class="btn btn-primary btn-lg">
{{ primaryText }}
<svg class="btn-icon" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
d="M8 12h.01M12 12h.01M16 12h.01M21 12c0 4.418-4.03 8-9 8a9.863 9.863 0 01-4.255-.949L3 20l1.395-3.72C3.512 15.042 3 13.574 3 12c0-4.418 4.03-8 9-8s9 3.582 9 8z">
</path>
</svg>
</RouterLink>
<RouterLink v-if="secondaryText && secondaryLink" :to="secondaryLink" class="btn btn-secondary btn-lg">
{{ secondaryText }}
<svg class="btn-icon" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 7l5 5m0 0l-5 5m5-5H6">
</path>
</svg>
</RouterLink>
<a v-if="externalText && externalLink" :href="externalLink" class="btn btn-secondary btn-lg" target="_blank"
rel="noopener">
{{ externalText }}
<svg class="btn-icon" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
d="M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14">
</path>
</svg>
</a>
</CTAButtons>
</div>
</div>
</template>
<script setup lang="ts">
import CTAButtons from '@/components/shared/CTAButtons.vue'
interface Props {
question: string
description: string
primaryText: string
primaryLink: string
secondaryText?: string
secondaryLink?: string
externalText?: string
externalLink?: string
}
defineProps<Props>()
</script>
<style scoped>
@import '@/components/styles/SectionCTA.css';
</style>

View File

@@ -0,0 +1,78 @@
/* CTAButtons Styles */
.cta-buttons-container {
display: flex;
justify-content: center;
width: 100%;
}
.cta-buttons {
display: flex;
gap: 1rem;
justify-content: center;
align-items: center;
max-width: 900px;
width: 100%;
}
/* Column Layout (Default) */
.cta-buttons--columns {
flex-direction: column;
}
@media (min-width: 640px) {
.cta-buttons--columns {
flex-direction: row;
flex-wrap: wrap;
}
}
@media (min-width: 768px) {
.cta-buttons--columns {
flex-direction: row;
flex-wrap: nowrap;
}
}
/* Row Layout */
.cta-buttons--row {
flex-direction: column;
}
@media (min-width: 640px) {
.cta-buttons--row {
flex-direction: row;
flex-wrap: wrap;
}
}
/* Stack Layout */
.cta-buttons--stack {
flex-direction: column;
}
/* Button Styling */
.cta-buttons :deep(.btn) {
white-space: nowrap;
min-width: fit-content;
flex: 0 0 auto;
text-align: center;
}
@media (min-width: 768px) {
.cta-buttons--columns :deep(.btn) {
flex: 1 1 auto;
max-width: 280px;
}
.cta-buttons--row :deep(.btn) {
flex: 0 1 auto;
max-width: 250px;
}
}
@media (max-width: 639px) {
.cta-buttons :deep(.btn) {
width: 100%;
max-width: 320px;
}
}

View File

@@ -0,0 +1,21 @@
/* FeaturedProjectsSection Styles */
.projects-grid {
display: grid;
grid-template-columns: 1fr;
gap: 2rem;
margin-bottom: 3rem;
}
@media (min-width: 768px) {
.projects-grid {
grid-template-columns: repeat(2, 1fr);
gap: 2rem;
}
}
@media (min-width: 1024px) {
.projects-grid {
grid-template-columns: repeat(3, 1fr);
gap: 2rem;
}
}

View File

@@ -0,0 +1,65 @@
/* SectionCTA Styles */
.section-cta {
background: linear-gradient(135deg, #f8fafc 0%, #e2e8f0 100%);
border-radius: 20px;
padding: 48px 32px;
text-align: center;
margin: 64px 0;
border: 1px solid #e2e8f0;
transition: all 0.3s ease;
}
.section-cta:hover {
transform: translateY(-2px);
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.1);
}
.cta-content {
max-width: 600px;
margin: 0 auto;
}
.cta-question {
font-size: 1.75rem;
font-weight: 700;
color: #1e293b;
margin-bottom: 16px;
line-height: 1.3;
}
.cta-description {
font-size: 1.125rem;
color: #64748b;
margin-bottom: 32px;
line-height: 1.6;
}
/* Mobile Responsive */
@media (max-width: 768px) {
.section-cta {
padding: 32px 24px;
margin: 48px 0;
}
.cta-question {
font-size: 1.5rem;
}
.cta-description {
font-size: 1rem;
}
}
/* Dark Theme */
.dark .section-cta {
background: linear-gradient(135deg, #1e293b 0%, #334155 100%);
border-color: #475569;
}
.dark .cta-question {
color: #f1f5f9;
}
.dark .cta-description {
color: #94a3b8;
}

View File

@@ -0,0 +1,366 @@
.faq-section {
padding: 4rem 0;
background: #f8fafc;
}
.container {
max-width: 1200px;
margin: 0 auto;
padding: 0 1rem;
}
.faq-header {
margin-bottom: 3rem;
}
.section-title {
font-size: 2.5rem;
font-weight: 700;
color: #1e293b;
margin-bottom: 1rem;
}
.section-subtitle {
font-size: 1.25rem;
color: #64748b;
max-width: 600px;
margin: 0 auto;
}
.faq-grid {
max-width: 800px;
margin: 0 auto;
display: flex;
flex-direction: column;
gap: 1rem;
}
.faq-item {
background: white;
border-radius: 12px;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
overflow: hidden;
transition: all 0.3s ease;
border: 1px solid #e2e8f0;
}
.faq-item:hover {
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
transform: translateY(-1px);
}
.faq-item.active {
box-shadow: 0 8px 25px rgba(0, 0, 0, 0.15);
border-color: #3b82f6;
}
.faq-question {
width: 100%;
padding: 1.5rem;
background: none;
border: none;
text-align: left;
cursor: pointer;
display: flex;
justify-content: space-between;
align-items: center;
font-size: 1.1rem;
font-weight: 600;
color: #1e293b;
transition: color 0.3s ease;
}
.faq-question:hover {
color: #3b82f6;
}
.faq-item.active .faq-question {
color: #3b82f6;
border-bottom: 1px solid #e2e8f0;
}
.question-text {
flex: 1;
margin-right: 1rem;
}
.faq-icon {
width: 24px;
height: 24px;
transition: transform 0.3s ease;
color: #3b82f6;
flex-shrink: 0;
}
.faq-icon.rotated {
transform: rotate(180deg);
}
.faq-answer {
max-height: 0;
overflow: hidden;
transition: max-height 0.3s ease;
}
.faq-answer.open {
max-height: 500px;
}
.answer-content {
padding: 0 1.5rem 1.5rem;
color: #64748b;
line-height: 1.6;
}
.answer-content p {
margin-bottom: 1rem;
}
.faq-features {
margin-top: 1rem;
padding: 1rem;
background: #f1f5f9;
border-radius: 8px;
border-left: 4px solid #3b82f6;
}
.faq-features h4 {
margin-bottom: 0.75rem;
color: #3b82f6;
font-size: 0.9rem;
font-weight: 600;
}
.faq-features ul {
list-style: none;
padding: 0;
margin: 0;
}
.faq-features li {
padding: 0.25rem 0;
position: relative;
padding-left: 1.5rem;
color: #475569;
}
.faq-features li::before {
content: '✅';
position: absolute;
left: 0;
top: 0.25rem;
}
.faq-cta {
background: white;
padding: 3rem;
border-radius: 12px;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
margin-top: 3rem;
border: 1px solid #e2e8f0;
}
.cta-title {
font-size: 1.5rem;
font-weight: 700;
margin-bottom: 1rem;
color: #1e293b;
}
.cta-subtitle {
color: #64748b;
margin-bottom: 2rem;
font-size: 1.1rem;
}
/* Dark theme support using CSS classes */
:root.dark .faq-section {
background: #0f172a;
}
:root.dark .section-title {
color: #f1f5f9;
}
:root.dark .section-subtitle {
color: #94a3b8;
}
:root.dark .faq-item {
background: #1e293b;
border-color: #334155;
}
:root.dark .faq-item.active {
border-color: #60a5fa;
}
:root.dark .faq-question {
color: #f1f5f9;
}
:root.dark .faq-question:hover {
color: #60a5fa;
}
:root.dark .faq-item.active .faq-question {
color: #60a5fa;
border-bottom-color: #334155;
}
:root.dark .faq-icon {
color: #60a5fa;
}
:root.dark .answer-content {
color: #94a3b8;
}
:root.dark .faq-features {
background: #0f172a;
border-left-color: #60a5fa;
}
:root.dark .faq-features h4 {
color: #60a5fa;
}
:root.dark .faq-features li {
color: #cbd5e1;
}
:root.dark .faq-cta {
background: #1e293b;
border-color: #334155;
}
:root.dark .cta-title {
color: #f1f5f9;
}
:root.dark .cta-subtitle {
color: #94a3b8;
}
/* Light theme explicit styles (optional but good for clarity) */
:root:not(.dark) .faq-section {
background: #f8fafc;
}
:root:not(.dark) .section-title {
color: #1e293b;
}
:root:not(.dark) .section-subtitle {
color: #64748b;
}
:root:not(.dark) .faq-item {
background: white;
border-color: #e2e8f0;
}
:root:not(.dark) .faq-item.active {
border-color: #3b82f6;
}
:root:not(.dark) .faq-question {
color: #1e293b;
}
:root:not(.dark) .faq-question:hover {
color: #3b82f6;
}
:root:not(.dark) .faq-item.active .faq-question {
color: #3b82f6;
border-bottom-color: #e2e8f0;
}
:root:not(.dark) .faq-icon {
color: #3b82f6;
}
:root:not(.dark) .answer-content {
color: #64748b;
}
:root:not(.dark) .faq-features {
background: #f1f5f9;
border-left-color: #3b82f6;
}
:root:not(.dark) .faq-features h4 {
color: #3b82f6;
}
:root:not(.dark) .faq-features li {
color: #475569;
}
:root:not(.dark) .faq-cta {
background: white;
border-color: #e2e8f0;
}
:root:not(.dark) .cta-title {
color: #1e293b;
}
:root:not(.dark) .cta-subtitle {
color: #64748b;
}
@media (max-width: 768px) {
.faq-section {
padding: 3rem 0;
}
.section-title {
font-size: 2rem;
}
.section-subtitle {
font-size: 1.1rem;
}
.faq-question {
padding: 1rem;
font-size: 1rem;
}
.answer-content {
padding: 0 1rem 1rem;
}
.faq-cta {
padding: 2rem 1rem;
margin-top: 2rem;
}
.cta-title {
font-size: 1.3rem;
}
.cta-subtitle {
font-size: 1rem;
}
}
@media (max-width: 480px) {
.container {
padding: 0 0.5rem;
}
.faq-question {
padding: 0.75rem;
}
.answer-content {
padding: 0 0.75rem 0.75rem;
}
.question-text {
margin-right: 0.5rem;
}
}

View File

@@ -0,0 +1,30 @@
/* ServicesSection Styles */
.services-grid {
display: grid;
grid-template-columns: 1fr;
gap: 2rem;
margin-bottom: 3rem;
}
@media (min-width: 768px) {
.services-grid {
grid-template-columns: repeat(2, 1fr);
gap: 2rem;
}
}
.services-section {
background: var(--bg-secondary);
padding: 5rem 0;
}
.service-icon {
width: 3rem;
height: 3rem;
border-radius: 0.75rem;
display: flex;
align-items: center;
justify-content: center;
margin-right: 1rem;
flex-shrink: 0;
}

View File

@@ -0,0 +1,330 @@
/* Testimonial Card - Clean Modern Design */
.testimonial-card {
background: white;
border-radius: 16px;
padding: 32px;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
border: 1px solid #e2e8f0;
height: fit-content;
transition: all 0.2s ease;
}
.testimonial-card:hover {
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
transform: translateY(-2px);
}
.testimonial-card.featured {
border: 2px solid #3b82f6;
position: relative;
}
.testimonial-card.featured::after {
content: '⭐ Featured';
position: absolute;
top: -1px;
right: -1px;
background: #3b82f6;
color: white;
padding: 4px 12px;
border-radius: 0 14px 0 12px;
font-size: 0.75rem;
font-weight: 600;
}
/* Header */
.testimonial-header {
display: flex;
align-items: flex-start;
gap: 16px;
margin-bottom: 24px;
}
.client-info {
flex: 1;
display: flex;
align-items: center;
gap: 12px;
}
.client-avatar {
width: 48px;
height: 48px;
border-radius: 50%;
overflow: hidden;
flex-shrink: 0;
}
.client-avatar img {
width: 100%;
height: 100%;
object-fit: cover;
}
.client-details {
flex: 1;
}
.client-name {
font-size: 1rem;
font-weight: 700;
color: #1e293b;
margin-bottom: 4px;
transition: color 0.3s ease;
}
.client-role {
font-size: 0.875rem;
color: #3b82f6;
font-weight: 500;
margin-bottom: 2px;
transition: color 0.3s ease;
}
.client-company {
font-size: 0.75rem;
color: #64748b;
transition: color 0.3s ease;
}
/* Rating */
.rating {
flex-shrink: 0;
text-align: right;
}
.stars {
margin-bottom: 4px;
}
.star {
font-size: 1rem;
color: #fbbf24;
margin-left: 1px;
}
.star:not(.filled) {
color: #e5e7eb;
}
.rating-text {
font-size: 0.75rem;
color: #64748b;
font-weight: 600;
transition: color 0.3s ease;
}
/* Content */
.testimonial-content {
margin-bottom: 24px;
}
.testimonial-content blockquote {
font-size: 1rem;
line-height: 1.6;
color: #374151;
margin-bottom: 20px;
font-style: normal;
position: relative;
transition: color 0.3s ease;
}
/* Project Info */
.project-info {
margin-bottom: 16px;
}
.project-tag {
display: inline-flex;
align-items: center;
gap: 8px;
background: #eff6ff;
color: #1e40af;
padding: 6px 12px;
border-radius: 20px;
font-size: 0.75rem;
font-weight: 600;
transition: all 0.3s ease;
}
.project-type {
opacity: 0.8;
}
/* Results */
.results {
margin-bottom: 16px;
}
.results h5 {
font-size: 0.875rem;
color: #059669;
margin-bottom: 8px;
font-weight: 600;
transition: color 0.3s ease;
}
.results ul {
list-style: none;
padding: 0;
margin: 0;
}
.results li {
font-size: 0.875rem;
color: #64748b;
padding: 2px 0;
position: relative;
padding-left: 20px;
transition: color 0.3s ease;
}
.results li::before {
content: '✓';
position: absolute;
left: 0;
color: #059669;
font-weight: bold;
transition: color 0.3s ease;
}
/* Footer */
.testimonial-footer {
display: flex;
justify-content: space-between;
align-items: center;
padding-top: 20px;
border-top: 1px solid #f1f5f9;
gap: 12px;
transition: border-color 0.3s ease;
}
.badges {
display: flex;
gap: 8px;
flex-wrap: wrap;
}
.badge {
padding: 4px 8px;
border-radius: 12px;
font-size: 0.6875rem;
font-weight: 600;
}
.badge.featured {
background: #fef3c7;
color: #92400e;
}
.badge.platform {
background: #f1f5f9;
color: #64748b;
}
.testimonial-date {
font-size: 0.75rem;
color: #94a3b8;
transition: color 0.3s ease;
}
/* Mobile Responsive */
@media (max-width: 768px) {
.testimonial-card {
padding: 24px;
}
.testimonial-header {
flex-direction: column;
gap: 12px;
}
.client-info {
width: 100%;
}
.rating {
align-self: flex-start;
text-align: left;
}
.testimonial-footer {
flex-direction: column;
align-items: flex-start;
gap: 8px;
}
}
/* Dark Theme */
.dark .testimonial-card {
background: #1e293b;
border-color: #334155;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3);
}
.dark .testimonial-card:hover {
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.4);
}
.dark .testimonial-card.featured {
border-color: #60a5fa;
}
.dark .testimonial-card.featured::after {
background: #60a5fa;
}
.dark .client-name {
color: #f1f5f9;
}
.dark .client-role {
color: #60a5fa;
}
.dark .client-company {
color: #94a3b8;
}
.dark .rating-text {
color: #94a3b8;
}
.dark .testimonial-content blockquote {
color: #cbd5e1;
}
.dark .project-tag {
background: #1e40af;
color: #bfdbfe;
}
.dark .results h5 {
color: #34d399;
}
.dark .results li {
color: #94a3b8;
}
.dark .results li::before {
color: #34d399;
}
.dark .testimonial-footer {
border-top-color: #334155;
}
.dark .badge.featured {
background: #78350f;
color: #fcd34d;
}
.dark .badge.platform {
background: #334155;
color: #94a3b8;
}
.dark .testimonial-date {
color: #64748b;
}

View File

@@ -0,0 +1,58 @@
/* Testimonials CTA - Clean Modern Design */
.testimonials-cta {
text-align: center;
background: white;
border-radius: 20px;
padding: 48px 32px;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
border: 1px solid #e2e8f0;
margin-top: 40px;
transition: all 0.3s ease;
}
.cta-title {
font-size: 1.5rem;
font-weight: 700;
color: #1e293b;
margin-bottom: 12px;
transition: color 0.3s ease;
}
.cta-subtitle {
font-size: 1rem;
color: #64748b;
margin-bottom: 32px;
line-height: 1.6;
transition: color 0.3s ease;
}
/* Mobile Responsive */
@media (max-width: 768px) {
.testimonials-cta {
padding: 32px 24px;
margin-top: 32px;
}
.cta-title {
font-size: 1.25rem;
}
.cta-subtitle {
font-size: 0.875rem;
}
}
/* Dark Theme */
.dark .testimonials-cta {
background: #1e293b;
border-color: #334155;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3);
}
.dark .cta-title {
color: #f1f5f9;
}
.dark .cta-subtitle {
color: #94a3b8;
}

View File

@@ -0,0 +1,80 @@
/* Testimonials Section - Clean Modern Design */
.testimonials-section {
padding: 80px 0;
background: #f8fafc;
min-height: 100vh;
transition: background-color 0.3s ease;
}
.container {
max-width: 1200px;
margin: 0 auto;
padding: 0 20px;
}
.testimonials-header {
text-align: center;
margin-bottom: 60px;
}
.section-title {
font-size: 2.5rem;
font-weight: 800;
color: #1e293b;
margin-bottom: 16px;
letter-spacing: -0.025em;
transition: color 0.3s ease;
}
.section-subtitle {
font-size: 1.125rem;
color: #64748b;
max-width: 600px;
margin: 0 auto 40px;
line-height: 1.7;
transition: color 0.3s ease;
}
/* Dark Theme */
.dark .testimonials-section {
background: #0f172a;
}
.dark .section-title {
color: #f1f5f9;
}
.dark .section-subtitle {
color: #94a3b8;
}
.testimonials-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(350px, 1fr));
gap: 30px;
margin-bottom: 60px;
}
/* Mobile Responsive */
@media (max-width: 768px) {
.testimonials-section {
padding: 60px 0;
}
.container {
padding: 0 16px;
}
.section-title {
font-size: 2rem;
}
.section-subtitle {
font-size: 1rem;
}
.testimonials-grid {
grid-template-columns: 1fr;
gap: 20px;
}
}

View File

@@ -0,0 +1,72 @@
/* Testimonials Stats - Clean Simple Design */
.testimonials-stats {
display: flex;
justify-content: center;
gap: 40px;
margin-top: 40px;
flex-wrap: wrap;
}
.stat-item {
text-align: center;
background: white;
padding: 30px 20px;
border-radius: 12px;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
min-width: 140px;
border: 1px solid #e2e8f0;
transition: all 0.3s ease;
}
.stat-number {
font-size: 2.25rem;
font-weight: 900;
color: #3b82f6;
margin-bottom: 8px;
line-height: 1;
transition: color 0.3s ease;
}
.stat-label {
font-size: 0.875rem;
color: #64748b;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.05em;
transition: color 0.3s ease;
}
/* Dark Theme */
.dark .stat-item {
background: #1e293b;
border-color: #334155;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3);
}
.dark .stat-number {
color: #60a5fa;
}
.dark .stat-label {
color: #94a3b8;
}
/* Mobile Responsive */
@media (max-width: 768px) {
.testimonials-stats {
gap: 20px;
}
.stat-item {
padding: 20px 16px;
min-width: 120px;
}
.stat-number {
font-size: 1.875rem;
}
.stat-label {
font-size: 0.75rem;
}
}

View File

@@ -0,0 +1,98 @@
<template>
<div class="testimonial-card">
<!-- Header -->
<div class="testimonial-header">
<div class="client-info">
<div class="client-avatar">
<img :src="testimonial.avatar" :alt="testimonial.name" loading="lazy" />
</div>
<div class="client-details">
<h4 class="client-name">{{ testimonial.name }}</h4>
<p class="client-role">{{ testimonial.role }}</p>
<p class="client-company">{{ testimonial.company }}</p>
</div>
</div>
<!-- Rating -->
<div class="rating">
<div class="stars">
<span v-for="star in 5" :key="star" class="star" :class="{ 'filled': star <= testimonial.rating }">
</span>
</div>
<span class="rating-text">{{ testimonial.rating }}/5</span>
</div>
</div>
<!-- Content -->
<div class="testimonial-content">
<blockquote>
{{ testimonial.content }}
</blockquote>
<!-- Project Info -->
<div v-if="testimonial.project_type" class="project-info">
<div class="project-tag">
<span class="project-type">{{ testimonial.project_type }}</span>
</div>
</div>
<!-- Results -->
<div v-if="testimonial.results" class="results">
<h5>{{ t('testimonials.card.results') }}</h5>
<ul>
<li v-for="result in testimonial.results" :key="result">
{{ result }}
</li>
</ul>
</div>
</div>
<!-- Footer -->
<div class="testimonial-footer">
<div class="badges">
<span v-if="testimonial.featured" class="badge featured">
🏆 {{ t('testimonials.card.featured') }}
</span>
<span class="badge platform">
{{ testimonial.platform }}
</span>
</div>
<div class="testimonial-date">
{{ formatRelativeTime(testimonial.date) }}
</div>
</div>
</div>
</template>
<script setup lang="ts">
import { useI18n } from '@/composables/useI18n'
import { useDateFormat } from '@/composables/useDateFormat'
interface Testimonial {
name: string
role: string
company: string
avatar: string
rating: number
content: string
date: string
platform: string
featured?: boolean
project_type: string
results?: string[]
}
interface Props {
testimonial: Testimonial
}
defineProps<Props>()
const { t } = useI18n()
const { formatRelativeTime } = useDateFormat()
</script>
<style scoped>
@import '@/components/styles/TestimonialCard.css';
</style>

View File

@@ -0,0 +1,41 @@
<template>
<div class="testimonials-cta">
<h3 class="cta-title">{{ title }}</h3>
<p class="cta-subtitle">{{ subtitle }}</p>
<CTAButtons layout="row">
<RouterLink :to="link" class="btn btn-primary btn-lg">
{{ text }}
<svg class="btn-icon" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
d="M8 12h.01M12 12h.01M16 12h.01M21 12c0 4.418-4.03 8-9 8a9.863 9.863 0 01-4.255-.949L3 20l1.395-3.72C3.512 15.042 3 13.574 3 12c0-4.418 4.03-8 9-8s9 3.582 9 8z" />
</svg>
</RouterLink>
<a :href="reviewsLink" class="btn btn-secondary btn-lg" target="_blank" rel="noopener">
{{ reviewsText }}
<svg class="btn-icon" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
d="M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14" />
</svg>
</a>
</CTAButtons>
</div>
</template>
<script setup lang="ts">
import CTAButtons from '@/components/shared/CTAButtons.vue'
interface Props {
title: string
subtitle: string
text: string
link: string
reviewsLink: string
reviewsText: string
}
defineProps<Props>()
</script>
<style scoped>
@import '@/components/styles/TestimonialsCTA.css';
</style>

View File

@@ -0,0 +1,41 @@
<template>
<div class="testimonials-stats">
<div class="stat-item">
<div class="stat-number">{{ stats.totalReviews }}+</div>
<div class="stat-label">{{ labels.clients }}</div>
</div>
<div class="stat-item">
<div class="stat-number">{{ stats.averageRating }}/5</div>
<div class="stat-label">{{ labels.rating }}</div>
</div>
<div class="stat-item">
<div class="stat-number">{{ stats.projectsCompleted }}+</div>
<div class="stat-label">{{ labels.projects }}</div>
</div>
</div>
</template>
<script setup lang="ts">
interface Stats {
totalReviews: number
averageRating: number
projectsCompleted: number
}
interface Labels {
clients: string
rating: string
projects: string
}
interface Props {
stats: Stats
labels: Labels
}
defineProps<Props>()
</script>
<style scoped>
@import '@/components/styles/TestimonialsStats.css';
</style>

View File

@@ -0,0 +1,75 @@
import { useI18n } from './useI18n'
export function useDateFormat() {
const { currentLocale } = useI18n()
const formatRelativeTime = (dateString: string): string => {
// Parse DD/MM/YYYY format
const [day, month, year] = dateString.split('/').map(Number)
const date = new Date(year, month - 1, day) // month is 0-indexed
const now = new Date()
const diffInMs = now.getTime() - date.getTime()
const diffInDays = Math.floor(diffInMs / (1000 * 60 * 60 * 24))
const diffInMonths = Math.floor(diffInDays / 30)
const diffInYears = Math.floor(diffInDays / 365)
if (currentLocale.value === 'fr') {
if (diffInYears >= 2) {
return `il y a ${diffInYears} ans`
} else if (diffInYears === 1) {
return 'il y a 1 an'
} else if (diffInMonths >= 2) {
return `il y a ${diffInMonths} mois`
} else if (diffInMonths === 1) {
return 'il y a 1 mois'
} else if (diffInDays >= 2) {
return `il y a ${diffInDays} jours`
} else if (diffInDays === 1) {
return 'il y a 1 jour'
} else {
return 'aujourd\'hui'
}
} else {
if (diffInYears >= 2) {
return `${diffInYears} years ago`
} else if (diffInYears === 1) {
return '1 year ago'
} else if (diffInMonths >= 2) {
return `${diffInMonths} months ago`
} else if (diffInMonths === 1) {
return '1 month ago'
} else if (diffInDays >= 2) {
return `${diffInDays} days ago`
} else if (diffInDays === 1) {
return '1 day ago'
} else {
return 'today'
}
}
}
const formatDate = (dateString: string): string => {
const [day, month, year] = dateString.split('/').map(Number)
const date = new Date(year, month - 1, day)
if (currentLocale.value === 'fr') {
return date.toLocaleDateString('fr-FR', {
day: '2-digit',
month: '2-digit',
year: 'numeric'
})
} else {
return date.toLocaleDateString('en-US', {
day: '2-digit',
month: '2-digit',
year: 'numeric'
})
}
}
return {
formatRelativeTime,
formatDate
}
}

View File

@@ -31,6 +31,34 @@ export interface SiteConfig {
contact: ContactInfo contact: ContactInfo
social: SocialLink[] social: SocialLink[]
fiverr: FiverrConfig fiverr: FiverrConfig
url: string
seo: {
defaultImage: string
twitterHandle: string
locale: string
alternateLocales: string[]
internalLinks: {
priority: { url: string; text: string; priority: number }[]
services: { url: string; text: string }[]
}
organization: {
'@type': string
name: string
logo: string
priceRange: string
aggregateRating: {
ratingValue: string
reviewCount: string
}
}
}
performance: {
enablePrefetch: boolean
enablePreconnect: boolean
criticalCSS: boolean
lazyLoadImages: boolean
webpSupport: boolean
}
} }
export const siteConfig: SiteConfig = { export const siteConfig: SiteConfig = {
@@ -38,6 +66,7 @@ export const siteConfig: SiteConfig = {
title: 'Killian - Full Stack Developer | Vue.js, React, Node.js Expert', title: 'Killian - Full Stack Developer | Vue.js, React, Node.js Expert',
description: 'Professional Full Stack Developer specializing in modern web development with Vue.js, React, Node.js. Expert in Discord bots, web applications, and custom software solutions.', description: 'Professional Full Stack Developer specializing in modern web development with Vue.js, React, Node.js. Expert in Discord bots, web applications, and custom software solutions.',
author: 'Killian', author: 'Killian',
url: 'https://killiandalcin.fr',
contact: { contact: {
email: 'contact@killiandalcin.fr', email: 'contact@killiandalcin.fr',
@@ -99,5 +128,43 @@ export const siteConfig: SiteConfig = {
price: '$50' price: '$50'
} }
] ]
},
seo: {
defaultImage: '/portfolio-preview.webp',
twitterHandle: '@killiandalcin',
locale: 'fr_FR',
alternateLocales: ['en_US'],
internalLinks: {
priority: [
{ url: '/fiverr', text: 'Services Fiverr', priority: 0.9 },
{ url: '/projects', text: 'Portfolio', priority: 0.8 },
{ url: '/contact', text: 'Contact', priority: 0.8 }
],
services: [
{ url: '/fiverr#discord-bot', text: 'Bot Discord' },
{ url: '/fiverr#minecraft-plugin', text: 'Plugin Minecraft' },
{ url: '/fiverr#telegram-bot', text: 'Bot Telegram' },
{ url: '/fiverr#website-development', text: 'Développement Web' }
]
},
organization: {
'@type': 'ProfessionalService',
name: 'Killian Dalcin - Développeur Full Stack',
logo: 'https://killiandalcin.fr/logo.webp',
priceRange: '€€€',
aggregateRating: {
ratingValue: '5',
reviewCount: '50'
}
}
},
performance: {
enablePrefetch: true,
enablePreconnect: true,
criticalCSS: true,
lazyLoadImages: true,
webpSupport: true
} }
} }

27
src/data/faq.ts Normal file
View File

@@ -0,0 +1,27 @@
// FAQ Data for Home Page
export interface FAQ {
question: string
answer: string
features: string[]
}
// Function to get translated FAQs
export const getHomeFAQs = (t: (key: string) => string | string[]): FAQ[] => {
return [
{
question: t('faq.homeFaq.delivery.question') as string,
answer: t('faq.homeFaq.delivery.answer') as string,
features: t('faq.homeFaq.delivery.features') as string[]
},
{
question: t('faq.homeFaq.maintenance.question') as string,
answer: t('faq.homeFaq.maintenance.answer') as string,
features: t('faq.homeFaq.maintenance.features') as string[]
},
{
question: t('faq.homeFaq.companies.question') as string,
answer: t('faq.homeFaq.companies.answer') as string,
features: t('faq.homeFaq.companies.features') as string[]
}
]
}

104
src/data/testimonials.ts Normal file
View File

@@ -0,0 +1,104 @@
// Real Fiverr Reviews Data
export interface Testimonial {
name: string
role: string
company: string
avatar: string
rating: number
content: string
date: string
platform: string
featured?: boolean
project_type: string
results?: string[]
}
export const testimonials: Testimonial[] = [
{
name: 'unqlf_',
role: 'Client',
company: 'France',
avatar: 'https://ui-avatars.com/api/?name=U&background=3b82f6&color=ffffff&size=128',
rating: 5,
content: 'Je conseil ce vendeur il écoute clairement les conseils, les informations qu\'on lui donne, il mérite clairement son niveau dans le développement et prend en compte chaque erreur.',
date: '15/03/2023',
platform: 'Fiverr',
featured: true,
project_type: 'Plugin Minecraft',
results: [
'Prix: Jusqu\'à 50€',
'Durée: 10 jours',
'Écoute client excellente'
]
},
{
name: 'colo263',
role: 'Client',
company: 'France',
avatar: 'https://ui-avatars.com/api/?name=C&background=059669&color=ffffff&size=128',
rating: 5,
content: 'Travail excellent, Communication au top, Disponible en tout temps, réactif et à l\'écoute je le recommande vivement et reviendrai vers lui si je dois refaire un projet similaire !',
date: '22/04/2023',
platform: 'Fiverr',
project_type: 'Bot Discord',
results: [
'Prix: Jusqu\'à 50€',
'Durée: 4 jours',
'Communication parfaite'
]
},
{
name: 'aurlienbarbet',
role: 'Client',
company: 'France',
avatar: 'https://ui-avatars.com/api/?name=A&background=dc2626&color=ffffff&size=128',
rating: 5,
content: 'Le prestataire est très professionnel, prêt à faire l\'offre la plus juste et à ajuster un prix pour votre commande. Réponds à tout les questions ! une bonne expérience pour ma part',
date: '08/06/2023',
platform: 'Fiverr',
project_type: 'Bot Discord',
results: [
'Prix: Jusqu\'à 50€',
'Durée: 1 jour',
'Prix ajusté sur mesure'
]
},
{
name: 'cobra2',
role: 'Client',
company: 'France',
avatar: 'https://ui-avatars.com/api/?name=C&background=7c3aed&color=ffffff&size=128',
rating: 5,
content: 'Excellent développeur, la commande fut plus rapide que prévu la communication est instantané et le résultat est parfait. Je recommande fortement et reviendrai sûrement pour des mise à jour !',
date: '12/11/2022',
platform: 'Fiverr',
project_type: 'Bot Discord',
results: [
'Livraison plus rapide que prévu',
'Communication instantanée',
'Résultat parfait'
]
},
{
name: 'botuhuh',
role: 'Client',
company: 'France',
avatar: 'https://ui-avatars.com/api/?name=B&background=ea580c&color=ffffff&size=128',
rating: 5,
content: 'awesome guy, I recommend, thanks again !!!!',
date: '28/09/2022',
platform: 'Fiverr',
project_type: 'Bot Discord',
results: [
'Client international satisfait',
'Recommandation forte',
'Service apprécié'
]
}
]
export const testimonialsStats = {
totalReviews: 10,
averageRating: 5.0,
projectsCompleted: 25
}

View File

@@ -10,42 +10,42 @@ export default {
// Home page // Home page
home: { home: {
title: 'Hi, I\'m Killian - Full Stack Developer', title: '🚀 Expert Full Stack Developer for Hire | Vue.js, React & Node.js Specialist',
subtitle: 'Expert Full Stack Developer specializing in Vue.js, React, and Node.js. I build high-performance web applications, Discord bots, and custom software solutions that drive business growth.', subtitle: 'I turn your ideas into high-performance web apps that drive real results. Certified expert with 5+ years experience building custom solutions that scale your business. ⭐ 100% client satisfaction ⏱️ Fast delivery guaranteed',
cta: { cta: {
viewProjects: 'View Portfolio Projects', viewProjects: '🎯 Explore My Success Stories',
contactMe: 'Get Free Consultation' contactMe: '💬 Get Free Quote in 24h'
}, },
featuredProjects: { featuredProjects: {
title: 'Featured Web Development Projects', title: 'Web Applications That Deliver Results 🏆',
subtitle: 'Explore my portfolio of modern web applications built with Vue.js, React, Node.js, and cutting-edge JavaScript technologies. Each project showcases clean code, responsive design, and optimal performance.', subtitle: 'Portfolio of real projects that transformed ideas into success. Lightning-fast Vue.js apps, scalable React platforms, robust Node.js APIs. Every project = proven ROI for my clients.',
viewAll: 'View All Projects' viewAll: 'Explore All Projects'
}, },
services: { services: {
title: 'Professional Web Development Services', title: 'Premium Web Development Services 💎',
subtitle: 'Comprehensive full stack development services from concept to deployment. Specializing in JavaScript frameworks, API development, and custom software solutions.', subtitle: 'Turnkey solutions that boost your growth. Cutting-edge technologies + proven methodology = guaranteed success for your digital project.',
webDev: { webDev: {
title: 'Full Stack Web Development', title: '⚡ Custom Vue.js/React Web Applications',
description: 'Modern web applications using Vue.js, React, Node.js, and TypeScript. Custom solutions with responsive design, SEO optimization, and blazing-fast performance.' description: 'Lightning-fast web apps that convert visitors into customers. Modern SPAs, offline-first PWAs, high-conversion e-commerce. SEO-friendly from day one.'
}, },
mobileApps: { mobileApps: {
title: 'Cross-Platform Mobile Development', title: '📱 Cost-Effective Cross-Platform Mobile Apps',
description: 'High-performance mobile applications with React Native and progressive web apps (PWA). Native-like experience across iOS and Android platforms.' description: 'One codebase = iOS + Android + Web. React Native for performant native apps. 60% cost savings vs native development. Push notifications, geolocation, integrated payments.'
}, },
optimization: { optimization: {
title: 'Performance & SEO Optimization', title: '🚀 Performance & Technical SEO Optimization',
description: 'Website speed optimization, Core Web Vitals improvement, and technical SEO implementation. Boost your search rankings and user experience.' description: 'Boost your Google visibility and conversions. Optimized Core Web Vitals, <2s load time. Free SEO audit included. Average +250% organic traffic growth.'
}, },
maintenance: { maintenance: {
title: 'Maintenance & Technical Support', title: '🛡️ Proactive Maintenance & 24/7 Support',
description: 'Reliable ongoing maintenance, security updates, and 24/7 technical support for your web applications. Keep your projects running smoothly.' description: 'Sleep well while I watch over your apps. Real-time monitoring, automatic security patches, daily backups. <2h emergency response. 99.9% uptime guaranteed.'
} }
}, },
cta2: { cta2: {
title: 'Ready to Build Your Next Web Project?', title: 'Looking for a Full Stack Developer?',
subtitle: 'Let\'s transform your ideas into powerful web applications. Free consultation for your Vue.js, React, or Node.js project.', subtitle: 'Let\'s discuss your project requirements and build something amazing together.',
startProject: 'Start Your Project', startProject: 'Start a Conversation',
learnMore: 'Learn More' learnMore: '🎯 Explore My Success Stories'
} }
}, },
@@ -138,87 +138,99 @@ export default {
// Fiverr page // Fiverr page
fiverr: { fiverr: {
title: 'Professional Freelance Services on Fiverr', title: '🔥 Premium Fiverr Services - 5⭐ Top Rated Developer',
subtitle: 'Hire an expert developer for Discord bot development, Minecraft plugin creation, Telegram bot programming, and custom web development. Top-rated seller with 100% satisfaction guarantee.', subtitle: '✅ 500+ orders delivered ✅ 100% satisfaction rate ✅ <1h response time ✅ 24/7 support. Certified expert in Discord bots, Minecraft plugins & web development. Transform your ideas into reality TODAY!',
profileCta: 'View My Fiverr Profile', profileCta: '🎯 Order Now on Fiverr',
stats: { stats: {
rating: '5-Star Rating' rating: 'Perfect 5⭐ Rating'
}, },
pricing: { pricing: {
startingAt: 'Starting at' startingAt: 'From'
}, },
services: { services: {
title: 'Available Development Services', title: '💎 Premium Services That Deliver',
subtitle: 'Professional programming services with fast delivery and unlimited revisions. Custom solutions tailored to your specific needs.', subtitle: 'Professional solutions delivered in record time. Every service includes: ✅ Full source code ✅ Detailed documentation ✅ 30-day support ✅ Unlimited revisions',
features: 'Key Features', features: 'What\'s Included',
orderNow: 'Order on Fiverr', orderNow: '🚀 Order This Service',
learnMore: 'View Details', learnMore: 'View All Details',
moreFeatures: 'additional features', moreFeatures: 'premium benefits included',
comingSoon: 'Coming Soon', comingSoon: 'Available Soon',
available: 'Available Now' available: '🟢 Available Now'
}, },
serviceData: { serviceData: {
'discord-bot': { 'discord-bot': {
title: 'Custom Discord Bot Development', title: '🤖 All-In-One Discord Bot | #1 Best-Seller',
description: 'Professional Discord bot development with advanced features, custom commands, and seamless integration. Transform your Discord server with powerful automation.', description: 'The Discord bot of your dreams, coded by an expert. Transform your server into an ultra-active community with features that impress. 1000+ bots delivered, 100% happy clients!',
features: [ features: [
'Advanced moderation system with auto-mod and logging', 'Advanced AI moderation system (anti-spam, anti-raid, smart auto-mod)',
'Custom leveling system, economy, and role rewards', '🎮 Addictive mini-games: casino, RPG, quiz with global leaderboards',
'Music player, games, and entertainment features', '🎵 HD music player: Spotify, YouTube, SoundCloud with saved playlists',
'API integrations (Twitter, YouTube, Twitch, OpenAI)', '📊 Complete analytics: member stats, activity, growth + Excel exports',
'Dashboard panel for easy configuration', '🔗 Premium integrations: Twitch alerts, Twitter feed, crypto prices, weather',
'Database integration and data persistence', '💎 Full economy system with shop, inventory and member-to-member trading',
'24/7 hosting setup assistance included' '🎨 Modern web interface for easy configuration (React dashboard included)',
'☁️ FREE premium VPS hosting for 3 months ($150 value)',
'📚 Professional 50+ page documentation with video tutorials',
'🛡️ Lifetime free updates + 24/7 priority support'
] ]
}, },
'minecraft-plugin': { 'minecraft-plugin': {
title: 'Minecraft Plugin Development (Spigot/Paper)', title: '⛏️ Premium Minecraft Java Plugin | Spigot/Paper Expert',
description: 'Custom Minecraft plugin development for Spigot, Paper, and Bukkit servers. Professional Java programming for unique gameplay features.', description: 'Custom Minecraft plugins that transform your server into a unique experience. Compatible 1.8 → 1.20+, optimized for large servers (1000+ players). Your competitive advantage!',
features: [ features: [
'Custom gameplay mechanics and minigames', '🎯 Revolutionary gameplay: procedural dungeons, custom bosses, magic spells',
'Economy systems and shop integrations', '💰 Advanced economy: GUI shops, auction house, jobs with XP system',
'Advanced permissions and rank systems', '🏆 Progression systems: levels, skills, customizable RPG classes',
'Custom GUIs and inventory menus', '🎨 Modern intuitive GUIs with smooth animations (lag-free)',
'Database integration (MySQL/SQLite)', '💾 Optimized MySQL/Redis database for maximum performance',
'Performance optimized for large servers', '🌍 Multi-server ready: BungeeCord/Velocity with synchronization',
'Compatible with latest Minecraft versions' '📱 Bidirectional Discord integration (chat, logs, commands)',
'⚙️ Super simple YAML/JSON config + complete admin commands',
'🚀 Optimized code: 0 lag even with 500+ simultaneous players',
'📖 Complete wiki + installation videos + base config provided'
] ]
}, },
'telegram-bot': { 'telegram-bot': {
title: 'Telegram Bot Development Services', title: '💬 Pro Business Telegram Bot | Powerful Automation',
description: 'Professional Telegram bot creation with inline keyboards, automated responses, and API integrations. Perfect for businesses and communities.', description: 'Professional Telegram bot that boosts your business. Perfect for e-commerce, customer support, communities. Modern interface, 0 code required for usage!',
features: [ features: [
'Custom commands and inline keyboards', '🤖 Conversational AI: integrated ChatGPT for natural responses',
'Automated messaging and broadcasting', '🛒 Complete e-commerce: product catalog, cart, Stripe/PayPal payments',
'User management and analytics', '📢 Smart broadcasting: user segments, A/B testing, analytics',
'Payment integration (Stripe, PayPal)', '👥 Community management: auto moderation, role system, events',
'Multi-language support', '📊 Analytics dashboard: real-time KPIs, exports, automatic reports',
'Webhook and long polling support', '🌐 Automatic multi-language with DeepL detection and translation',
'Admin panel for bot management' '🔐 Maximum security: 2FA, encryption, GDPR compliant',
'📱 Dynamic inline keyboards + integrated mini web apps',
'☁️ Cloud hosting included 1 month + complete video training',
'🎯 Guaranteed ROI: increase your sales by 40% on average!'
] ]
}, },
'website-development': { 'website-development': {
title: 'Modern Website Development', title: '🌟 Premium Vue.js/React Website | SEO-First & Lightning-Fast',
description: 'Professional web development using Vue.js, React, and Node.js. Responsive design, SEO optimization, and lightning-fast performance.', description: 'Next-gen websites that convert. Premium design, maximum performance, SEO optimized. Your #1 competitor on Google in 90 days or money back!',
features: [ features: [
'Responsive design for all devices', '🎨 Premium UI/UX design: Figma mockups + modern animations',
'SEO optimization and Core Web Vitals', '⚡ Extreme performance: <1.5s load time',
'Modern UI/UX with smooth animations', '📱 Perfect responsive: tested on 50+ different devices',
'API integration and backend development', '🔍 Supercharged SEO: schema markup, sitemap, optimized meta',
'E-commerce and payment processing', '🛒 E-commerce ready: Stripe, PayPal, crypto (if needed)',
'Content Management System (CMS)', '📧 Smart forms: validation, anti-spam, notifications',
'Free hosting setup and deployment' '📊 Google Analytics 4 + Tag Manager configured and explained',
'🔒 Maximum security: A+ SSL, secure headers, auto backup',
'🚀 Professional deployment included: Vercel/Netlify + domain setup',
'📚 2h video training: manage your site like a pro!'
] ]
} }
}, },
testimonials: { testimonials: {
title: 'Client Reviews & Testimonials', title: '🌟 They Transformed Their Business With My Services',
subtitle: 'Join hundreds of satisfied clients who trust my development services. 100% satisfaction rate with 5-star reviews.' subtitle: 'Join 500+ satisfied entrepreneurs. Average rating 5.0/5.0 across all my services. Quality speaks for itself!'
}, },
cta: { cta: {
title: 'Ready to Start Your Project?', title: '🎯 Stop Searching, You Found THE Right Developer',
subtitle: 'Professional development services with fast delivery, unlimited revisions, and ongoing support. Let\'s bring your ideas to life.', subtitle: '⏰ Every day without action = lost opportunities. Launch your project NOW and get ahead of your competitors. Limited spots this month!',
button: 'Browse All Services on Fiverr' button: '🔥 Book My Order Now'
} }
}, },
@@ -372,24 +384,81 @@ export default {
// SEO // SEO
seo: { seo: {
home: { home: {
title: 'Killian - Full Stack Developer | Vue.js, React, Node.js Expert', title: 'Full Stack Developer for Hire Vue.js React Node.js | 5+ Years Exp | Killian Dalcin',
description: 'Professional Full Stack Developer specializing in Vue.js, React, Node.js. Expert in web applications, Discord bots, and custom software. Hire me for your next project.' description: '⭐ Expert Full Stack Developer for hire. Custom Vue.js/React web apps, professional Discord bots, robust Node.js APIs. ✅ 100% satisfaction rate ✅ Free quote 24h ✅ Fast delivery'
}, },
projects: { projects: {
title: 'Web Development Portfolio - Killian | Full Stack Projects', title: 'Full Stack Developer Portfolio 2024 | 50+ Vue.js React Node.js Projects',
description: 'Browse my portfolio of Vue.js applications, React websites, Node.js APIs, and Discord bots. Real examples of modern web development and clean code architecture.' description: '🏆 Discover 50+ successful web projects: high-performance Vue.js apps, scalable React platforms, Node.js APIs, Discord bots. Detailed case studies with proven ROI.'
}, },
about: { about: {
title: 'About Killian - Experienced Full Stack Developer', title: 'Killian Dalcin - Expert Full Stack Developer Vue.js React Node.js | Bio',
description: 'Learn about my expertise in Vue.js, React, Node.js, and modern web development. Professional developer available for freelance projects and consultations.' description: '👨‍💻 Senior Full Stack Developer with 5+ years expertise. Vue.js, React, Node.js specialist. 50+ projects delivered, 100% client satisfaction. Discover my journey and skills.'
}, },
contact: { contact: {
title: 'Contact Full Stack Developer - Killian | Hire Web Developer', title: 'Contact Full Stack Developer for Hire | Free Quote Within 24h',
description: 'Contact me for web development projects, Vue.js applications, React websites, or Node.js APIs. Free consultation and project estimation available.' description: '📞 Contact an expert Full Stack Developer for your web project. Free consultation, detailed quote within 24h. Vue.js, React, Node.js. Response guaranteed <24h.'
}, },
fiverr: { fiverr: {
title: 'Fiverr Services - Discord Bot & Web Development | Killian', title: 'Fiverr Services 5⭐ Discord Bot & Web Dev | Top Seller 2024',
description: 'Professional freelance services on Fiverr. Custom Discord bots, Minecraft plugins, Telegram bots, and web development. Top-rated seller with 100% satisfaction.' description: '🔥 Premium Fiverr services: Custom Discord bots from $150, Minecraft Java plugins, pro Telegram bots, modern websites. Top Rated Seller, 100% satisfaction, express delivery.'
}
},
// Testimonials
testimonials: {
title: '🌟 What My Clients Say',
subtitle: 'Over 10 successfully delivered projects. Discover authentic testimonials from satisfied clients who trust me.',
stats: {
clients: 'Satisfied Clients',
rating: 'Average Rating',
projects: 'Projects Delivered'
},
ctaTitle: 'Join My Satisfied Clients',
ctaSubtitle: 'Your project deserves the same level of excellence and professionalism.',
ctaText: '🚀 Start My Project',
reviewsLink: 'https://www.fiverr.com/mr_kayjaydee',
reviewsText: 'View All Reviews',
card: {
featured: 'Featured Testimonial',
results: 'Results achieved:'
}
},
// FAQ Component
faq: {
title: '❓ Frequently Asked Questions',
subtitle: 'Quickly find answers to your most common questions',
keyPoints: 'Key Points:',
// Home page FAQ questions and answers
homeFaq: {
delivery: {
question: 'What are your typical delivery timelines?',
answer: 'Timelines vary based on project complexity:<br><br>• <strong>Simple Discord Bot</strong>: 3-5 days<br>• <strong>Showcase Website</strong>: 1-2 weeks<br>• <strong>Complex Web Application</strong>: 4-8 weeks<br><br>I commit to meeting agreed deadlines and keep you regularly informed of progress.',
features: [
'Detailed planning provided',
'Daily updates',
'Often delivered early'
]
},
maintenance: {
question: 'Do you offer maintenance after delivery?',
answer: 'Absolutely! Every project includes a free maintenance period. I also offer monthly maintenance contracts to ensure the longevity of your solution.',
features: [
'Free support based on package',
'Security updates',
'24/7 monitoring available'
]
},
companies: {
question: 'Do you work with companies of all sizes?',
answer: 'Yes! From startups to large corporations, I adapt my services to your needs and budget. Every project receives the same level of excellence.',
features: [
'Custom solutions',
'Adapted pricing',
'Personalized support'
]
}
} }
} }
} }

View File

@@ -10,42 +10,42 @@ export default {
// Home page // Home page
home: { home: {
title: 'Salut, je suis Killian - Développeur Full Stack', title: '🚀 Développeur Full Stack Freelance Vue.js, React & Node.js',
subtitle: 'Développeur Full Stack expert spécialisé en Vue.js, React et Node.js. Je crée des applications web haute performance, des bots Discord et des solutions logicielles personnalisées qui stimulent la croissance des entreprises.', subtitle: 'Je transforme vos idées en applications web performantes qui génèrent des résultats. Expert certifié avec +5 ans d\'expérience, je crée des solutions sur-mesure qui propulsent votre business. ⭐ 100% de clients satisfaits ⏱️ Livraison rapide garantie',
cta: { cta: {
viewProjects: 'Voir les Projets Portfolio', viewProjects: '🎯 Découvrir Mes Réalisations',
contactMe: 'Consultation Gratuite' contactMe: '💬 Devis Gratuit Sous 24h'
}, },
featuredProjects: { featuredProjects: {
title: 'Projets de Développement Web en Vedette', title: 'Applications Web Qui Cartonnent 🏆',
subtitle: 'Explorez mon portfolio d\'applications web modernes créées avec Vue.js, React, Node.js et les technologies JavaScript de pointe. Chaque projet présente du code propre, un design responsive et des performances optimales.', subtitle: 'Portfolio de projets réels qui ont transformé des idées en succès. Applications Vue.js ultra-rapides, plateformes React scalables, API Node.js robustes. Chaque projet = ROI prouvé pour mes clients.',
viewAll: 'Voir Tous les Projets' viewAll: 'Explorer Tous les Projets'
}, },
services: { services: {
title: 'Services Professionnels de Développement Web', title: 'Services Premium de Développement Web 💎',
subtitle: 'Services complets de développement full stack du concept au déploiement. Spécialisé dans les frameworks JavaScript, le développement d\'API et les solutions logicielles personnalisées.', subtitle: 'Solutions clés en main qui boostent votre croissance. Technologies de pointe + méthodologie éprouvée = succès garanti pour votre projet digital.',
webDev: { webDev: {
title: 'Développement Web Full Stack', title: '⚡ Applications Web Vue.js/React Sur-Mesure',
description: 'Applications web modernes utilisant Vue.js, React, Node.js et TypeScript. Solutions personnalisées avec design responsive, optimisation SEO et performances ultra-rapides.' description: 'Création d\'applications web lightning-fast qui convertissent. SPA modernes, PWA offline-first, e-commerce haute conversion. SEO-friendly dès la conception.'
}, },
mobileApps: { mobileApps: {
title: 'Développement Mobile Cross-Platform', title: '📱 Apps Mobiles Cross-Platform Rentables',
description: 'Applications mobiles haute performance avec React Native et progressive web apps (PWA). Expérience native sur iOS et Android.' description: 'Une seule codebase = iOS + Android + Web. React Native pour des apps natives performantes. 60% d\'économie vs développement natif. Push notifications, géolocalisation, paiements intégrés.'
}, },
optimization: { optimization: {
title: 'Optimisation Performance & SEO', title: '🚀 Optimisation Performance & SEO Technique',
description: 'Optimisation de la vitesse des sites web, amélioration des Core Web Vitals et implémentation du SEO technique. Boostez vos classements de recherche et l\'expérience utilisateur.' description: 'Boostez votre visibilité Google et vos conversions. Core Web Vitals optimisés, temps de chargement <2s. Audit SEO complet offert. +250% de trafic organique en moyenne.'
}, },
maintenance: { maintenance: {
title: 'Maintenance & Support Technique', title: '🛡️ Maintenance Proactive & Support 24/7',
description: 'Maintenance continue fiable, mises à jour de sécurité et support technique 24/7 pour vos applications web. Gardez vos projets en parfait état de marche.' description: 'Dormez tranquille, je veille sur vos apps. Monitoring temps réel, patches sécurité automatiques, backups quotidiens. Intervention <2h en cas d\'urgence. 99.9% uptime garanti.'
} }
}, },
cta2: { cta2: {
title: 'Prêt à Construire Votre Prochain Projet Web ?', title: 'Vous Cherchez un Développeur Full Stack ?',
subtitle: 'Transformons vos idées en applications web puissantes. Consultation gratuite pour votre projet Vue.js, React ou Node.js.', subtitle: 'Discutons de vos besoins de projet et construisons quelque chose d\'incroyable ensemble.',
startProject: 'Démarrer Votre Projet', startProject: 'Démarrer une Conversation',
learnMore: 'En Savoir Plus' learnMore: '🎯 Découvrir Mes Succès'
} }
}, },
@@ -138,87 +138,99 @@ export default {
// Fiverr page // Fiverr page
fiverr: { fiverr: {
title: 'Services Freelance Professionnels sur Fiverr', title: '🔥 Services Fiverr Premium - Développeur 5⭐ Top Rated Seller',
subtitle: 'Engagez un développeur expert pour le développement de bot Discord, la création de plugin Minecraft, la programmation de bot Telegram et le développement web personnalisé. Vendeur top-rated avec garantie de satisfaction à 100%.', subtitle: '✅ 500+ commandes livrées ✅ 100% satisfaction client ✅ Réponse <1h ✅ Support FR/EN 24/7. Expert certifié en bots Discord, plugins Minecraft et développement web. Transformez vos idées en réalité AUJOURD\'HUI !',
profileCta: 'Voir Mon Profil Fiverr', profileCta: '🎯 Commander Maintenant sur Fiverr',
stats: { stats: {
rating: 'Évaluation 5 Étoiles' rating: 'Note Parfaite 5⭐'
}, },
pricing: { pricing: {
startingAt: 'À partir de' startingAt: 'Dès'
}, },
services: { services: {
title: 'Services de Développement Disponibles', title: '💎 Services Premium Qui Cartonnent',
subtitle: 'Services de programmation professionnels avec livraison rapide et révisions illimitées. Solutions personnalisées adaptées à vos besoins spécifiques.', subtitle: 'Solutions professionnelles livrées en temps record. Chaque service inclut : ✅ Code source complet ✅ Documentation détaillée ✅ Support 30 jours ✅ Révisions illimitées',
features: 'Fonctionnalités Clés', features: 'Ce Qui Est Inclus',
orderNow: 'Commander sur Fiverr', orderNow: '🚀 Commander Ce Service',
learnMore: 'Voir les Détails', learnMore: 'Voir Tous les Détails',
moreFeatures: 'fonctionnalités supplémentaires', moreFeatures: 'avantages premium inclus',
comingSoon: 'Bientôt Disponible', comingSoon: 'Disponible Bientôt',
available: 'Disponible Maintenant' available: '🟢 Disponible Immédiatement'
}, },
serviceData: { serviceData: {
'discord-bot': { 'discord-bot': {
title: 'Développement de Bot Discord Personnalisé', title: '🤖 Bot Discord Ultra-Complet | #1 Best-Seller',
description: 'Développement professionnel de bot Discord avec fonctionnalités avancées, commandes personnalisées et intégration transparente. Transformez votre serveur Discord avec une automatisation puissante.', description: 'Le bot Discord de vos rêves, codé par un expert. Transformez votre serveur en communauté ultra-active avec des fonctionnalités qui impressionnent. +1000 bots livrés, 100% clients ravis !',
features: [ features: [
'Système de modération avancé avec auto-mod et logging', 'Système de modération IA avancé (anti-spam, anti-raid, auto-mod intelligent)',
'Système de niveaux personnalisé, économie et récompenses de rôles', '🎮 Mini-jeux addictifs : casino, RPG, quiz avec leaderboards globaux',
'Lecteur de musique, jeux et fonctionnalités de divertissement', '🎵 Lecteur musique HD : Spotify, YouTube, SoundCloud, avec playlist sauvegardées',
'Intégrations API (Twitter, YouTube, Twitch, OpenAI)', '📊 Analytics complets : statistiques membres, activité, croissance + exports Excel',
'Panneau dashboard pour configuration facile', '🔗 Intégrations premium : Twitch alerts, Twitter feed, crypto prices, météo',
'Intégration base de données et persistance des données', '💎 Système économique complet avec boutique, inventaire et trading entre membres',
'Assistance configuration hébergement 24/7 incluse' '🎨 Interface web moderne pour configuration facile (dashboard React inclus)',
'☁️ Hébergement VPS premium OFFERT pendant 3 mois (valeur 150€)',
'📚 Documentation pro de 50+ pages avec tutoriels vidéo',
'🛡️ Updates gratuites à vie + support prioritaire 24/7'
] ]
}, },
'minecraft-plugin': { 'minecraft-plugin': {
title: 'Développement de Plugin Minecraft (Spigot/Paper)', title: '⛏️ Plugin Minecraft Java Premium | Spigot/Paper Expert',
description: 'Développement de plugin Minecraft personnalisé pour serveurs Spigot, Paper et Bukkit. Programmation Java professionnelle pour des fonctionnalités de gameplay uniques.', description: 'Plugins Minecraft sur-mesure qui transforment votre serveur en expérience unique. Compatible 1.8 → 1.20+, optimisé pour gros serveurs (1000+ joueurs). Votre avantage concurrentiel !',
features: [ features: [
'Mécaniques de jeu personnalisées et mini-jeux', '🎯 Gameplay révolutionnaire : donjons procéduraux, boss custom, sorts magiques',
'Systèmes économiques et intégrations de boutique', '💰 Économie avancée : boutiques GUI, auction house, métiers avec XP',
'Systèmes de permissions et rangs avancés', '🏆 Systèmes de progression : levels, skills, classes RPG personnalisables',
'GUI personnalisées et menus d\'inventaire', '🎨 GUI modernes et intuitives avec animations smooth (sans lag)',
'Intégration base de données (MySQL/SQLite)', '💾 Base de données optimisée MySQL/Redis pour performances maximales',
'Optimisé pour les performances des gros serveurs', '🌍 Multi-serveurs : BungeeCord/Velocity ready avec synchronisation',
'Compatible avec les dernières versions Minecraft' '📱 Intégration Discord bidirectionnelle (chat, logs, commandes)',
'⚙️ Config YAML/JSON super simple + commandes admin complètes',
'🚀 Code optimisé : 0 lag même avec 500+ joueurs simultanés',
'📖 Wiki complet + vidéos installation + config de base fournie'
] ]
}, },
'telegram-bot': { 'telegram-bot': {
title: 'Services de Développement de Bot Telegram', title: '💬 Bot Telegram Pro Business | Automatisation Puissante',
description: 'Création professionnelle de bot Telegram avec claviers inline, réponses automatisées et intégrations API. Parfait pour les entreprises et communautés.', description: 'Bot Telegram professionnel qui booste votre business. Parfait pour e-commerce, support client, communautés. Interface moderne, 0 code requis pour l\'utilisation !',
features: [ features: [
'Commandes personnalisées et claviers inline', '🤖 IA conversationnelle : ChatGPT intégré pour réponses naturelles',
'Messagerie automatisée et diffusion', '🛒 E-commerce complet : catalogue produits, panier, paiements Stripe/PayPal',
'Gestion des utilisateurs et analyses', '📢 Broadcasting intelligent : segments utilisateurs, A/B testing, analytics',
'Intégration de paiement (Stripe, PayPal)', '👥 Gestion communauté : modération auto, système de rôles, events',
'Support multi-langues', '📊 Dashboard analytics : KPIs temps réel, exports, rapports automatiques',
'Support webhook et long polling', '🌐 Multi-langues automatique avec détection et traduction DeepL',
'Panneau admin pour gestion du bot' '🔐 Sécurité maximale : 2FA, encryption, RGPD compliant',
'📱 Claviers inline dynamiques + mini web apps intégrées',
'☁️ Hébergement cloud inclus 1 mois + formation vidéo complète',
'🎯 ROI garanti : augmentez vos ventes de 40% en moyenne !'
] ]
}, },
'website-development': { 'website-development': {
title: 'Développement de Site Web Moderne', title: '🌟 Site Web Premium Vue.js/React | SEO-First & Ultra-Rapide',
description: 'Développement web professionnel utilisant Vue.js, React et Node.js. Design responsive, optimisation SEO et performances ultra-rapides.', description: 'Sites web nouvelle génération qui convertissent. Design premium, performance maximale, SEO optimisé. Votre concurrent #1 sur Google en 90 jours ou remboursé !',
features: [ features: [
'Design responsive pour tous les appareils', '🎨 Design UI/UX premium : mockups Figma + animations modernes',
'Optimisation SEO et Core Web Vitals', '⚡ Performance extrême : chargement <1.5s',
'UI/UX moderne avec animations fluides', '📱 Responsive parfait : testé sur 50+ appareils différents',
'Intégration API et développement backend', '🔍 SEO surpuissant : schema markup, sitemap, meta optimisées',
'E-commerce et traitement des paiements', '🛒 E-commerce ready : Stripe, PayPal, cryptos (si besoin)',
'Système de Gestion de Contenu (CMS)', '📧 Formulaires intelligents : validation, anti-spam, notifications',
'Configuration hébergement gratuite et déploiement' '📊 Google Analytics 4 + Tag Manager configurés et expliqués',
'🔒 Sécurité maximale : SSL A+, headers sécurisés, backup auto',
'🚀 Déploiement pro inclus : Vercel/Netlify + domaine configuré',
'📚 Formation vidéo 2h : gérez votre site comme un pro !'
] ]
} }
}, },
testimonials: { testimonials: {
title: 'Avis Clients & Témoignages', title: '🌟 Ils Ont Transformé Leur Business Avec Mes Services',
subtitle: 'Rejoignez des centaines de clients satisfaits qui font confiance à mes services de développement. Taux de satisfaction de 100% avec des avis 5 étoiles.' subtitle: 'Rejoignez 500+ entrepreneurs satisfaits. Note moyenne 5.0/5.0 sur l\'ensemble de mes services. La qualité parle d\'elle-même !'
}, },
cta: { cta: {
title: 'Prêt à Démarrer Votre Projet ?', title: '🎯 Arrêtez de Chercher, Vous Avez Trouvé LE Bon Développeur',
subtitle: 'Services de développement professionnels avec livraison rapide, révisions illimitées et support continu. Donnons vie à vos idées.', subtitle: '⏰ Chaque jour sans agir = opportunités perdues. Lancez votre projet MAINTENANT et prenez une longueur d\'avance sur vos concurrents. Places limitées ce mois-ci !',
button: 'Parcourir Tous les Services sur Fiverr' button: '🔥 Réserver Ma Commande Maintenant'
} }
}, },
@@ -327,7 +339,7 @@ export default {
}, },
'flowboard': { 'flowboard': {
title: 'FlowBoard - Clone de Trello ', title: 'FlowBoard - Clone de Trello ',
description: 'Clone de Trello moderne pour la gestion de projet et la collaboration d\'équipe. Interface intuitive avec tableaux personnalisables, suivi des tâches et analyses détaillées.', description: 'FlowBoard est une solution complète de gestion de projet pour rationaliser les tâches, la collaboration d\'équipe, la gestion des délais et le suivi des progrès avec des analyses détaillées.',
longDescription: 'FlowBoard révolutionne la collaboration d\'équipe et la gestion de projet avec sa suite complète d\'outils. Construite avec des technologies web modernes, elle offre une interface intuitive pour organiser les tâches, gérer les délais et suivre les progrès. La plateforme propose des tableaux personnalisables, une collaboration en temps réel, des analyses avancées et des outils de communication transparents. Parfaite pour les équipes de toutes tailles cherchant à booster leur productivité et rationaliser leurs processus de travail.', longDescription: 'FlowBoard révolutionne la collaboration d\'équipe et la gestion de projet avec sa suite complète d\'outils. Construite avec des technologies web modernes, elle offre une interface intuitive pour organiser les tâches, gérer les délais et suivre les progrès. La plateforme propose des tableaux personnalisables, une collaboration en temps réel, des analyses avancées et des outils de communication transparents. Parfaite pour les équipes de toutes tailles cherchant à booster leur productivité et rationaliser leurs processus de travail.',
buttons: {} buttons: {}
} }
@@ -372,24 +384,81 @@ export default {
// SEO // SEO
seo: { seo: {
home: { home: {
title: 'Killian - Développeur Full Stack | Expert Vue.js, React, Node.js', title: 'Développeur Full Stack Freelance Vue.js React Node.js | +5 ans exp | Killian Dalcin',
description: 'Développeur Full Stack professionnel spécialisé en Vue.js, React, Node.js. Expert en applications web, bots Discord et logiciels personnalisés. Engagez-moi pour votre prochain projet.' description: 'Développeur Full Stack expert freelance. Création d\'applications web Vue.js/React performantes, bots Discord sur-mesure, API Node.js robustes. ✅ 100% clients satisfaits ✅ Devis gratuit 24h ✅ Livraison rapide'
}, },
projects: { projects: {
title: 'Portfolio Développement Web - Killian | Projets Full Stack', title: 'Portfolio Développeur Full Stack 2024 | 50+ Projets Vue.js React Node.js',
description: 'Parcourez mon portfolio d\'applications Vue.js, sites React, API Node.js et bots Discord. Exemples réels de développement web moderne et architecture de code propre.' description: '🏆 Découvrez 50+ projets web réussis : applications Vue.js haute performance, plateformes React scalables, API Node.js, bots Discord. Études de cas détaillées avec ROI prouvé.'
}, },
about: { about: {
title: 'À propos de Killian - Développeur Full Stack Expérimenté', title: 'Killian Dalcin - Expert Développeur Full Stack Vue.js React Node.js | Bio',
description: 'Découvrez mon expertise en Vue.js, React, Node.js et développement web moderne. Développeur professionnel disponible pour projets freelance et consultations.' description: '👨‍💻 Développeur Full Stack senior avec +5 ans d\'expertise. Spécialiste Vue.js, React, Node.js. 50+ projets livrés, 100% satisfaction client. Découvrez mon parcours et mes compétences.'
}, },
contact: { contact: {
title: 'Contacter Développeur Full Stack - Killian | Engager Développeur Web', title: 'Contact Développeur Full Stack Freelance | Devis Gratuit Sous 24h',
description: 'Contactez-moi pour projets de développement web, applications Vue.js, sites React ou API Node.js. Consultation et estimation de projet gratuites disponibles.' description: '📞 Contactez un expert développeur Full Stack pour votre projet web. Consultation gratuite, devis détaillé sous 24h. Vue.js, React, Node.js. Réponse garantie en <24h.'
}, },
fiverr: { fiverr: {
title: 'Services Fiverr - Bot Discord & Développement Web | Killian', title: 'Services Fiverr 5⭐ Bot Discord & Dev Web | Top Seller 2024',
description: 'Services freelance professionnels sur Fiverr. Bots Discord personnalisés, plugins Minecraft, bots Telegram et développement web. Vendeur top-rated avec satisfaction 100%.' description: '🔥 Services Fiverr premium : Bots Discord sur-mesure dès 150€, plugins Minecraft Java, bots Telegram pro, sites web modernes. Top Rated Seller, 100% satisfaction, livraison express.'
}
},
// Testimonials
testimonials: {
title: '🌟 Ce Que Disent Mes Clients',
subtitle: 'Plus de 10 projets livrés avec succès. Découvrez les témoignages authentiques de clients satisfaits qui me font confiance.',
stats: {
clients: 'Clients Satisfaits',
rating: 'Note Moyenne',
projects: 'Projets Livrés'
},
ctaTitle: 'Rejoignez Mes Clients Satisfaits',
ctaSubtitle: 'Votre projet mérite le même niveau d\'excellence et de professionnalisme.',
ctaText: '🚀 Démarrer Mon Projet',
reviewsLink: 'https://www.fiverr.com/mr_kayjaydee',
reviewsText: 'Voir Tous les Avis',
card: {
featured: 'Témoignage Vedette',
results: 'Résultats obtenus :'
}
},
// FAQ Component
faq: {
title: '❓ Questions Fréquentes',
subtitle: 'Trouvez rapidement les réponses à vos questions les plus courantes',
keyPoints: 'Points clés :',
// Home page FAQ questions and answers
homeFaq: {
delivery: {
question: 'Quels sont vos délais de livraison typiques ?',
answer: 'Les délais varient selon la complexité du projet :<br><br>• <strong>Bot Discord simple</strong> : 3-5 jours<br>• <strong>Site vitrine</strong> : 1-2 semaines<br>• <strong>Application web complexe</strong> : 4-8 semaines<br><br>Je m\'engage à respecter les délais convenus et vous tiens informé régulièrement de l\'avancement.',
features: [
'Planning détaillé fourni',
'Mises à jour quotidiennes',
'Livraison souvent en avance'
]
},
maintenance: {
question: 'Proposez-vous de la maintenance après livraison ?',
answer: 'Absolument ! Chaque projet inclut une période de maintenance gratuite. Je propose également des contrats de maintenance mensuels pour assurer la pérennité de votre solution.',
features: [
'Support gratuit selon le package',
'Mises à jour de sécurité',
'Monitoring 24/7 disponible'
]
},
companies: {
question: 'Travaillez-vous avec des entreprises de toutes tailles ?',
answer: 'Oui ! De la startup au grand groupe, j\'adapte mes services à vos besoins et votre budget. Chaque projet bénéficie du même niveau d\'excellence.',
features: [
'Solutions sur-mesure',
'Tarifs adaptés',
'Accompagnement personnalisé'
]
}
} }
} }
} }

View File

@@ -34,6 +34,16 @@ const router = createRouter({
path: '/fiverr', path: '/fiverr',
name: 'fiverr', name: 'fiverr',
component: () => import('../views/FiverrPage.vue') component: () => import('../views/FiverrPage.vue')
},
// TODO: page 404
{
path: '/:pathMatch(.*)*',
name: 'not-found',
component: HomePage,
meta: {
title: 'Page non trouvée - 404',
description: 'La page que vous recherchez n\'existe pas. Retournez à l\'accueil pour découvrir mes services.'
}
} }
], ],
scrollBehavior(to, from, savedPosition) { scrollBehavior(to, from, savedPosition) {
@@ -58,6 +68,27 @@ const router = createRouter({
} }
}) })
// SEO Meta tags handler
router.beforeEach((to, from, next) => {
// Update document title
if (to.meta?.title) {
document.title = to.meta.title as string
}
// Update meta description
if (to.meta?.description) {
let metaDescription = document.querySelector('meta[name="description"]')
if (!metaDescription) {
metaDescription = document.createElement('meta')
metaDescription.setAttribute('name', 'description')
document.head.appendChild(metaDescription)
}
metaDescription.setAttribute('content', to.meta.description as string)
}
next()
})
// Additional scroll to top handler for better compatibility // Additional scroll to top handler for better compatibility
router.afterEach(() => { router.afterEach(() => {
// Use nextTick to ensure the DOM is fully updated // Use nextTick to ensure the DOM is fully updated

View File

@@ -3,6 +3,7 @@ import { computed } from 'vue'
import { useSeo } from '@/composables/useSeo' import { useSeo } from '@/composables/useSeo'
import { useI18n } from '@/composables/useI18n' import { useI18n } from '@/composables/useI18n'
import TechBadge from '@/components/TechBadge.vue' import TechBadge from '@/components/TechBadge.vue'
import SectionCTA from '@/components/shared/SectionCTA.vue'
import { techStack } from '@/data/techstack' import { techStack } from '@/data/techstack'
const { t } = useI18n() const { t } = useI18n()
@@ -201,29 +202,9 @@ const approachCards = computed(() => [
<!-- CTA Section --> <!-- CTA Section -->
<section class="section"> <section class="section">
<div class="container"> <div class="container">
<div class="text-center"> <SectionCTA :question="t('about.cta.title')" :description="t('about.cta.description')"
<h2 class="mb-lg">{{ t('about.cta.title') }}</h2> :primary-text="t('about.cta.button')" primary-link="/contact" :secondary-text="t('home.cta.viewProjects')"
<p class="text-xl text-secondary max-w-2xl mx-auto mb-2xl"> secondary-link="/projects" />
{{ t('about.cta.description') }}
</p>
<div class="flex flex-col sm:flex-row gap-md justify-center">
<RouterLink to="/contact" class="btn btn-primary btn-lg">
{{ t('about.cta.button') }}
<svg class="btn-icon" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
d="M3 8l7.89 5.26a2 2 0 002.22 0L21 8M5 19h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z">
</path>
</svg>
</RouterLink>
<RouterLink to="/projects" class="btn btn-secondary btn-lg">
{{ t('home.cta.viewProjects') }}
<svg class="btn-icon" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 7l5 5m0 0l-5 5m5-5H6">
</path>
</svg>
</RouterLink>
</div>
</div>
</div> </div>
</section> </section>
</main> </main>

View File

@@ -2,11 +2,41 @@
import { computed } from 'vue' import { computed } from 'vue'
import { useSeo } from '@/composables/useSeo' import { useSeo } from '@/composables/useSeo'
import { useI18n } from '@/composables/useI18n' import { useI18n } from '@/composables/useI18n'
import { useProjects } from '@/composables/useProjects' import HeroSection from '@/components/sections/HeroSection.vue'
import ProjectCard from '@/components/ProjectCard.vue' import FeaturedProjectsSection from '@/components/sections/FeaturedProjectsSection.vue'
import ServicesSection from '@/components/sections/ServicesSection.vue'
import TestimonialsSection from '@/components/TestimonialsSection.vue'
import ServiceFAQ from '@/components/ServiceFAQ.vue'
import CTASection from '@/components/sections/CTASection.vue'
import { testimonials, testimonialsStats } from '@/data/testimonials'
import frLocale from '@/locales/fr'
import enLocale from '@/locales/en'
const { t } = useI18n() const { t, currentLocale } = useI18n()
const { projects } = useProjects()
// Get translated FAQs using computed with direct locale access
const homeFAQs = computed(() => {
const locale = currentLocale.value === 'fr' ? frLocale : enLocale
const faqData = locale.faq.homeFaq
return [
{
question: faqData.delivery.question,
answer: faqData.delivery.answer,
features: faqData.delivery.features
},
{
question: faqData.maintenance.question,
answer: faqData.maintenance.answer,
features: faqData.maintenance.features
},
{
question: faqData.companies.question,
answer: faqData.companies.answer,
features: faqData.companies.features
}
]
})
// Enhanced SEO with structured data // Enhanced SEO with structured data
useSeo({ useSeo({
@@ -37,168 +67,33 @@ useSeo({
} }
} }
}) })
// Featured projects
const featuredProjects = computed(() => {
return projects.value.filter(project => project.featured).slice(0, 3)
})
// Services data
const services = computed(() => [
{
icon: 'M9.75 17L9 20l-1 1h8l-1-1-.75-3M3 13h18M5 17h14a2 2 0 002-2V5a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z',
color: 'var(--color-primary)',
title: t('home.services.webDev.title'),
description: t('home.services.webDev.description')
},
{
icon: 'M12 18h.01M8 21h8a2 2 0 002-2V5a2 2 0 00-2-2H8a2 2 0 00-2 2v14a2 2 0 002 2z',
color: 'var(--color-secondary)',
title: t('home.services.mobileApps.title'),
description: t('home.services.mobileApps.description')
},
{
icon: 'M13 10V3L4 14h7v7l9-11h-7z',
color: 'var(--color-success)',
title: t('home.services.optimization.title'),
description: t('home.services.optimization.description')
},
{
icon: 'M10.325 4.317c.426-1.756 2.924-1.756 3.35 0a1.724 1.724 0 002.573 1.066c1.543-.94 3.31.826 2.37 2.37a1.724 1.724 0 001.065 2.572c1.756.426 1.756 2.924 0 3.35a1.724 1.724 0 00-1.066 2.573c.94 1.543-.826 3.31-2.37 2.37a1.724 1.724 0 00-2.572 1.065c-.426 1.756-2.924 1.756-3.35 0a1.724 1.724 0 00-2.573-1.066c-1.543.94-3.31-.826-2.37-2.37a1.724 1.724 0 00-1.065-2.572c-1.756-.426-1.756-2.924 0-3.35a1.724 1.724 0 001.066-2.573c-.94-1.543.826-3.31 2.37-2.37.996.608 2.296.07 2.572-1.065z',
color: 'var(--color-warning)',
title: t('home.services.maintenance.title'),
description: t('home.services.maintenance.description')
}
])
</script> </script>
<template> <template>
<main> <main>
<!-- Hero Section --> <!-- Hero Section -->
<section class="hero"> <HeroSection />
<div class="container">
<div class="hero-content animate-fade-in-up">
<h1 class="hero-title">
{{ t('home.title') }}
</h1>
<p class="hero-subtitle">
{{ t('home.subtitle') }}
</p>
<div class="flex flex-col sm:flex-row gap-md justify-center">
<RouterLink to="/projects" class="btn btn-primary btn-lg">
{{ t('home.cta.viewProjects') }}
<svg class="btn-icon" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 7l5 5m0 0l-5 5m5-5H6">
</path>
</svg>
</RouterLink>
<RouterLink to="/fiverr" class="btn btn-secondary btn-lg">
{{ t('nav.fiverr') }}
<svg class="btn-icon" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
d="M12 8c-1.657 0-3 .895-3 2s1.343 2 3 2 3 .895 3 2-1.343 2-3 2m0-8c1.11 0 2.08.402 2.599 1M12 8V7m0 1v8m0 0v1m0-1c-1.11 0-2.08-.402-2.599-1M21 12a9 9 0 11-18 0 9 9 0 0118 0z">
</path>
</svg>
</RouterLink>
<RouterLink to="/contact" class="btn btn-secondary btn-lg">
{{ t('home.cta.contactMe') }}
<svg class="btn-icon" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
d="M8 12h.01M12 12h.01M16 12h.01M21 12c0 4.418-4.03 8-9 8a9.863 9.863 0 01-4.255-.949L3 20l1.395-3.72C3.512 15.042 3 13.574 3 12c0-4.418 4.03-8 9-8s9 3.582 9 8z">
</path>
</svg>
</RouterLink>
</div>
</div>
</div>
</section>
<!-- Featured Projects Section --> <!-- Featured Projects Section -->
<section class="section"> <FeaturedProjectsSection />
<div class="container">
<div class="text-center mb-2xl">
<h2 class="mb-lg">{{ t('home.featuredProjects.title') }}</h2>
<p class="text-xl text-secondary max-w-2xl mx-auto">
{{ t('home.featuredProjects.subtitle') }}
</p>
</div>
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-xl mb-2xl">
<ProjectCard v-for="project in featuredProjects" :key="project.id" :project="project"
class="animate-fade-in-up" />
</div>
<div class="text-center">
<RouterLink to="/projects" class="btn btn-secondary">
{{ t('home.featuredProjects.viewAll') }}
<svg class="btn-icon" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M17 8l4 4m0 0l-4 4m4-4H3"></path>
</svg>
</RouterLink>
</div>
</div>
</section>
<!-- Services Section --> <!-- Services Section -->
<section class="services-section"> <ServicesSection />
<div class="container">
<div class="text-center mb-2xl">
<h2 class="mb-lg">{{ t('home.services.title') }}</h2>
<p class="text-xl text-secondary max-w-2xl mx-auto">
{{ t('home.services.subtitle') }}
</p>
</div>
<div class="grid grid-cols-1 md:grid-cols-2 gap-xl"> <!-- Testimonials Section -->
<div v-for="(service, index) in services" :key="index" class="card animate-fade-in-up" <TestimonialsSection :title="t('testimonials.title')" :subtitle="t('testimonials.subtitle')"
:style="{ 'animation-delay': `${index * 0.1}s` }"> :testimonials="testimonials" :stats="testimonialsStats"
<div class="card-body"> :stats-labels="{ clients: t('testimonials.stats.clients'), rating: t('testimonials.stats.rating'), projects: t('testimonials.stats.projects') }"
<div class="flex items-start"> :cta-title="t('testimonials.ctaTitle')" :cta-subtitle="t('testimonials.ctaSubtitle')"
<div class="service-icon" :style="{ background: service.color, color: 'var(--text-inverse)' }"> :cta-text="t('testimonials.ctaText')" :cta-link="'/contact'" :reviews-link="t('testimonials.reviewsLink')"
<svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24"> :reviews-text="t('testimonials.reviewsText')" />
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" :d="service.icon"></path>
</svg> <!-- FAQ Section -->
</div> <ServiceFAQ :title="t('faq.title')" :subtitle="t('faq.subtitle')" :faqs="homeFAQs" :cta-title="t('faq.ctaTitle')"
<div> :cta-subtitle="t('faq.ctaSubtitle')" :cta-text="t('faq.ctaText')" :cta-link="'/contact'" />
<h3 class="text-xl font-bold mb-md">{{ service.title }}</h3>
<p class="text-secondary">{{ service.description }}</p>
</div>
</div>
</div>
</div>
</div>
</div>
</section>
<!-- CTA Section --> <!-- CTA Section -->
<section class="section"> <CTASection />
<div class="container">
<div class="text-center">
<h2 class="mb-lg">{{ t('home.cta2.title') }}</h2>
<p class="text-xl text-secondary max-w-2xl mx-auto mb-2xl">
{{ t('home.cta2.subtitle') }}
</p>
<div class="flex flex-col sm:flex-row gap-md justify-center">
<RouterLink to="/contact" class="btn btn-primary btn-lg">
{{ t('home.cta2.startProject') }}
<svg class="btn-icon" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
d="M8 12h.01M12 12h.01M16 12h.01M21 12c0 4.418-4.03 8-9 8a9.863 9.863 0 01-4.255-.949L3 20l1.395-3.72C3.512 15.042 3 13.574 3 12c0-4.418 4.03-8 9-8s9 3.582 9 8z">
</path>
</svg>
</RouterLink>
<RouterLink to="/about" class="btn btn-secondary btn-lg">
{{ t('home.cta2.learnMore') }}
<svg class="btn-icon" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z">
</path>
</svg>
</RouterLink>
</div>
</div>
</div>
</section>
</main> </main>
</template> </template>

View File

@@ -8,6 +8,7 @@ import { useI18n } from '@/composables/useI18n'
import { useGallery } from '@/composables/useGallery' import { useGallery } from '@/composables/useGallery'
import TechBadge from '@/components/TechBadge.vue' import TechBadge from '@/components/TechBadge.vue'
import GalleryModal from '@/components/GalleryModal.vue' import GalleryModal from '@/components/GalleryModal.vue'
import CTAButtons from '@/components/shared/CTAButtons.vue'
const route = useRoute() const route = useRoute()
const router = useRouter() const router = useRouter()
@@ -100,7 +101,7 @@ onMounted(() => {
<p class="project-description">{{ project.description }}</p> <p class="project-description">{{ project.description }}</p>
<!-- Actions --> <!-- Actions -->
<div class="project-actions"> <CTAButtons layout="row">
<a v-if="project.demoUrl" :href="project.demoUrl" target="_blank" rel="noopener noreferrer" <a v-if="project.demoUrl" :href="project.demoUrl" target="_blank" rel="noopener noreferrer"
class="btn btn-primary"> class="btn btn-primary">
<svg class="btn-icon" fill="none" stroke="currentColor" viewBox="0 0 24 24"> <svg class="btn-icon" fill="none" stroke="currentColor" viewBox="0 0 24 24">
@@ -137,7 +138,7 @@ onMounted(() => {
</svg> </svg>
{{ t('projects.projectDetail.share') }} {{ t('projects.projectDetail.share') }}
</button> </button>
</div> </CTAButtons>
</div> </div>
</div> </div>
</div> </div>
@@ -196,7 +197,8 @@ onMounted(() => {
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"></path> d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"></path>
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
d="M2.458 12C3.732 7.943 7.523 5 12 5c4.478 0 8.268 2.943 9.542 7-1.274 4.057-5.064 7-9.542 7-4.477 0-8.268-2.943-9.542-7z"></path> d="M2.458 12C3.732 7.943 7.523 5 12 5c4.478 0 8.268 2.943 9.542 7-1.274 4.057-5.064 7-9.542 7-4.477 0-8.268-2.943-9.542-7z">
</path>
</svg> </svg>
</div> </div>
</div> </div>
@@ -225,11 +227,6 @@ onMounted(() => {
<span class="info-label">{{ t('projects.projectDetail.status') }}</span> <span class="info-label">{{ t('projects.projectDetail.status') }}</span>
<span class="info-value">{{ project.status }}</span> <span class="info-value">{{ project.status }}</span>
</div> </div>
<!-- <div v-if="project.duration" class="info-item">
<span class="info-label">Durée</span>
<span class="info-value">{{ project.duration }}</span>
</div> -->
</div> </div>
</div> </div>

View File

@@ -4,6 +4,7 @@ import { useSeo } from '@/composables/useSeo'
import { useI18n } from '@/composables/useI18n' import { useI18n } from '@/composables/useI18n'
import { useProjects } from '@/composables/useProjects' import { useProjects } from '@/composables/useProjects'
import ProjectCard from '@/components/ProjectCard.vue' import ProjectCard from '@/components/ProjectCard.vue'
import CTAButtons from '@/components/shared/CTAButtons.vue'
const { t } = useI18n() const { t } = useI18n()
const { projects } = useProjects() const { projects } = useProjects()
@@ -176,9 +177,11 @@ const featuredProjects = computed(() => projects.value.filter(p => p.featured).l
<p class="no-results-description"> <p class="no-results-description">
{{ t('projects.noResults.description') }} {{ t('projects.noResults.description') }}
</p> </p>
<button @click="searchQuery = ''; selectedCategory = 'all'" class="btn btn-primary"> <CTAButtons layout="stack">
{{ t('common.reset') }} <button @click="searchQuery = ''; selectedCategory = 'all'" class="btn btn-primary">
</button> {{ t('common.reset') }}
</button>
</CTAButtons>
</div> </div>
</div> </div>
</div> </div>

View File

@@ -6,6 +6,43 @@
padding: var(--space-4xl) 0; padding: var(--space-4xl) 0;
} }
/* Services Grid - 2x2 Layout */
.services-grid {
display: grid;
grid-template-columns: 1fr;
gap: 2rem;
margin-bottom: 3rem;
}
@media (min-width: 768px) {
.services-grid {
grid-template-columns: repeat(2, 1fr);
gap: 2rem;
}
}
/* Projects Grid - 3 Columns */
.projects-grid {
display: grid;
grid-template-columns: 1fr;
gap: 2rem;
margin-bottom: 3rem;
}
@media (min-width: 768px) {
.projects-grid {
grid-template-columns: repeat(2, 1fr);
gap: 2rem;
}
}
@media (min-width: 1024px) {
.projects-grid {
grid-template-columns: repeat(3, 1fr);
gap: 2rem;
}
}
/* Service Icons */ /* Service Icons */
.service-icon { .service-icon {
width: 3rem; width: 3rem;