Compare commits

..

9 Commits

9 changed files with 7188 additions and 240 deletions

View File

@@ -167,3 +167,5 @@ Pour que Coolify puisse nettoyer les environnements de PR automatiquement :
Cliquez sur **Deploy**. 🚀 Cliquez sur **Deploy**. 🚀
<!-- Webhook test mar. 30 déc. 2025 09:27:22 CET -->

6860
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

View File

@@ -1,9 +1,16 @@
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 128 128"> <svg width="128" height="128" viewBox="0 0 128 128" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M50.4 78.5a75.1 75.1 0 0 0-28.5 6.9l24.2-65.7c.7-2 1.9-3.2 3.4-3.2h29c1.5 0 2.7 1.2 3.4 3.2l24.2 65.7s-11.6-7-28.5-7L67 45.5c-.4-1.7-1.6-2.8-2.9-2.8-1.3 0-2.5 1.1-2.9 2.7L50.4 78.5Zm-1.1 28.2Zm-4.2-20.2c-2 6.6-.6 15.8 4.2 20.2a17.5 17.5 0 0 1 .2-.7 5.5 5.5 0 0 1 5.7-4.5c2.8.1 4.3 1.5 4.7 4.7.2 1.1.2 2.3.2 3.5v.4c0 2.7.7 5.2 2.2 7.4a13 13 0 0 0 5.7 4.9v-.3l-.2-.3c-1.8-5.6-.5-9.5 4.4-12.8l1.5-1a73 73 0 0 0 3.2-2.2 16 16 0 0 0 6.8-11.4c.3-2 .1-4-.6-6l-.8.6-1.6 1a37 37 0 0 1-22.4 2.7c-5-.7-9.7-2-13.2-6.2Z" /> <g clip-path="url(#clip0_1_40)">
<style> <rect width="107" height="21" fill="black"/>
path { fill: #000; } <rect y="107" width="128" height="21" fill="black"/>
@media (prefers-color-scheme: dark) { <rect y="53" width="128" height="21" fill="black"/>
path { fill: #FFF; } <rect x="5.59506e-06" y="128" width="128" height="21" transform="rotate(-90 5.59506e-06 128)" fill="black"/>
} <rect x="43" y="128" width="128" height="21" transform="rotate(-90 43 128)" fill="black"/>
</style> <rect x="86" y="74" width="74" height="21" transform="rotate(-90 86 74)" fill="black"/>
<rect x="107" y="127" width="74" height="21" transform="rotate(-90 107 127)" fill="black"/>
</g>
<defs>
<clipPath id="clip0_1_40">
<rect width="128" height="128" fill="white"/>
</clipPath>
</defs>
</svg> </svg>

Before

Width:  |  Height:  |  Size: 749 B

After

Width:  |  Height:  |  Size: 775 B

View File

@@ -4,11 +4,13 @@ import "../styles/global.css";
interface Props { interface Props {
title?: string; title?: string;
description?: string; description?: string;
image?: string;
} }
const { const {
title = "Astro Starter Kit", title = "Emmanuel Bernard - Consultant-formateur en AI Automation & expert n8n, Lausanne, Suisse Romande",
description = "Un starter kit Astro minimal et élégant", description = "Expert en automatisation n8n et intelligence artificielle basé à Lausanne. J'accompagne les agences et équipes pour décupler leur productivité.",
image = "https://cdn.avqn.ch/images/website/aussi-vite-que-necessaire.jpg",
} = Astro.props; } = Astro.props;
--- ---
@@ -24,20 +26,40 @@ const {
<title>{title}</title> <title>{title}</title>
<meta property="og:title" content={title} /> <meta property="og:title" content={title} />
<meta property="og:description" content={description} /> <meta property="og:description" content={description} />
<meta property="og:type" content="website" /> <meta property="og:type" content="profile" />
<meta property="og:image" content={image} />
<!-- Twitter -->
<meta property="twitter:card" content="summary_large_image" />
<meta property="twitter:title" content={title} />
<meta property="twitter:description" content={description} />
<meta property="twitter:image" content={image} />
<!-- Favicon --> <!-- Favicon -->
<link rel="icon" type="image/svg+xml" href="/favicon.svg" /> <link rel="icon" type="image/svg+xml" href="/favicon.svg" />
<!-- Google Fonts - Inter --> <!-- Font Optimization: Preload Critical Fonts -->
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link <link
href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="preload"
rel="stylesheet" href="https://cdn.avqn.ch/fonts/ClashDisplay-Bold.woff2"
as="font"
type="font/woff2"
crossorigin="anonymous"
/> />
<link
rel="preload"
href="https://cdn.avqn.ch/fonts/GeneralSans-Regular.woff2"
as="font"
type="font/woff2"
crossorigin="anonymous"
/>
<!-- Analytics -->
<script
defer
src="https://analytics.avqn.ch/script.js"
data-website-id="0446d79d-9348-418f-b990-3321e98f7fe4"></script>
</head> </head>
<body class="font-sans antialiased bg-white text-gray-900"> <body class="font-sans antialiased bg-white text-gray-900 min-h-screen">
<slot /> <slot />
</body> </body>
</html> </html>

View File

@@ -1,69 +0,0 @@
---
import BaseLayout from "../layouts/BaseLayout.astro";
import Navbar from "../components/Navbar.astro";
---
<BaseLayout
title="About - Astro Starter Kit"
description="À propos de ce starter kit Astro"
>
<Navbar />
<main class="max-w-4xl mx-auto px-6 py-16">
<div class="mb-16">
<h1 class="text-5xl font-bold tracking-tight mb-4">About ✨</h1>
<p class="text-xl text-gray-600 leading-relaxed">
Un starter kit pensé pour la simplicité et l'élégance.
</p>
<div class="mt-4">
<span
class="inline-block px-3 py-1 text-xs font-medium bg-gray-100 text-gray-700 rounded-full"
>
v2.0 - Test auto-deploy
</span>
</div>
</div>
<div class="prose prose-gray max-w-none">
<h2 class="text-2xl font-semibold mb-4">Philosophie</h2>
<p class="text-gray-600 leading-relaxed mb-8">
Ce starter kit adopte une approche minimaliste : fournir une
base solide et élégante sans superflu, avec les outils
essentiels pour démarrer rapidement un projet web moderne et
performant.
</p>
<h2 class="text-2xl font-semibold mb-4">Technologies</h2>
<ul class="space-y-3 text-gray-600">
<li class="flex items-start">
<span class="font-medium text-gray-900 mr-2">Astro</span>
<span>— Framework web moderne avec génération statique</span
>
</li>
<li class="flex items-start">
<span class="font-medium text-gray-900 mr-2">React</span>
<span
>— Bibliothèque UI pour les composants interactifs</span
>
</li>
<li class="flex items-start">
<span class="font-medium text-gray-900 mr-2"
>Tailwind CSS</span
>
<span>— Framework CSS utility-first</span>
</li>
<li class="flex items-start">
<span class="font-medium text-gray-900 mr-2">Docker</span>
<span>— Containerisation pour un déploiement simplifié</span
>
</li>
</ul>
<div class="mt-12 pt-8 border-t border-gray-200">
<p class="text-sm text-gray-500">
Construit avec soin pour la performance et l'élégance.
</p>
</div>
</div>
</main>
</BaseLayout>

View File

@@ -1,83 +0,0 @@
---
import BaseLayout from "../layouts/BaseLayout.astro";
import Navbar from "../components/Navbar.astro";
---
<BaseLayout
title="Contact - Astro Starter Kit"
description="Contactez-nous via ce formulaire"
>
<Navbar />
<main class="max-w-4xl mx-auto px-6 py-16">
<div class="mb-12">
<h1 class="text-5xl font-bold tracking-tight mb-4">Contact</h1>
<p class="text-xl text-gray-600 leading-relaxed">
Envoyez-nous un message, nous serons ravis de vous répondre.
</p>
</div>
<!-- Formulaire -->
<form class="max-w-2xl space-y-6">
<div>
<label
for="name"
class="block text-sm font-medium text-gray-900 mb-2"
>
Nom
</label>
<input
type="text"
id="name"
name="name"
class="w-full px-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-gray-900 focus:border-transparent outline-none transition-all"
placeholder="Votre nom"
/>
</div>
<div>
<label
for="email"
class="block text-sm font-medium text-gray-900 mb-2"
>
Email
</label>
<input
type="email"
id="email"
name="email"
class="w-full px-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-gray-900 focus:border-transparent outline-none transition-all"
placeholder="votre@email.com"
/>
</div>
<div>
<label
for="message"
class="block text-sm font-medium text-gray-900 mb-2"
>
Message
</label>
<textarea
id="message"
name="message"
rows="6"
class="w-full px-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-gray-900 focus:border-transparent outline-none transition-all resize-none"
placeholder="Votre message..."></textarea>
</div>
<button
type="button"
onclick="alert('Ceci est un formulaire de démonstration. Aucune donnée n\'est envoyée.')"
class="w-full px-6 py-3 bg-gray-900 text-white font-medium rounded-lg hover:bg-gray-800 transition-colors"
>
Envoyer le message
</button>
<p class="text-sm text-gray-500 text-center">
Note : Ce formulaire est une démonstration et n'envoie aucune
donnée.
</p>
</form>
</main>
</BaseLayout>

View File

@@ -1,80 +1,198 @@
--- ---
import BaseLayout from "../layouts/BaseLayout.astro"; import BaseLayout from "../layouts/BaseLayout.astro";
import Navbar from "../components/Navbar.astro";
const links = [
{
title: "Aussi Vite Que Nécessaire",
url: "https://avqn.ch",
icon: "🌐",
},
{
title: "LinkedIn",
url: "https://www.linkedin.com/in/emmbernard",
icon: "💼",
},
{
title: "YouTube",
url: "https://www.youtube.com/@emmanuelflux",
icon: "🎥",
},
];
--- ---
<BaseLayout <BaseLayout>
title="Astro Starter Kit" <!-- Main Container: Full screen height, centered content but with a grid layout -->
description="Un starter kit minimal et élégant avec Astro, React et Tailwind CSS" <main
> class="min-h-screen w-full flex items-center justify-center p-4 sm:p-8 bg-white selection:bg-black selection:text-white"
<Navbar /> >
<!-- Grid Wrapper: Max width restriction for large screens, grid on desktop -->
<div
class="w-full max-w-6xl grid grid-cols-1 lg:grid-cols-12 border border-black"
>
<!-- LEFT COLUMN: Profile & Bio (Spans 5 cols) -->
<div
class="lg:col-span-5 border-b lg:border-b-0 lg:border-r border-black flex flex-col justify-between min-h-[500px]"
>
<!-- Main Content Area -->
<div class="p-8 sm:p-12 flex-1 flex flex-col justify-between">
<!-- Header / Avatar -->
<div>
<div
class="w-48 mb-8 bg-gradient-to-br from-[#FFE4D9] to-[#FFD6CC] rounded-3xl overflow-hidden shadow-2xl shadow-rose-900/20"
>
<img
src="https://cdn.avqn.ch/photos/manu/manu-left.webp"
alt="Emmanuel Bernard"
class="w-full h-auto object-cover grayscale object-top mix-blend-multiply"
/>
</div>
<main class="max-w-4xl mx-auto px-6 py-16"> <h1
<!-- Hero Section --> class="text-4xl sm:text-5xl font-extrabold tracking-tighter text-black mb-4 uppercase leading-[0.9]"
<div class="mb-16"> >
<h1 class="text-5xl font-bold tracking-tight mb-4"> Emmanuel<br />Bernard
Astro Starter Kit </h1>
</h1> </div>
<p class="text-xl text-gray-600 leading-relaxed">
Un point de départ minimal et élégant pour vos projets web
modernes.
</p>
<div class="mt-3">
<span
class="inline-block px-2 py-1 text-xs font-medium bg-gray-100 text-gray-700 rounded"
>
⚡ Powered by pnpm
</span>
</div>
<p class="text-sm text-gray-500 mt-2 italic">
✨ Mise à jour de test — Version mobile ready 📱
</p>
</div>
<!-- Features --> <!-- Body -->
<div class="space-y-12"> <div class="space-y-6">
<div> <h2
<h2 class="text-2xl font-semibold mb-3">Performance</h2> class="text-xl font-bold border-l-4 border-black pl-4 py-1 leading-snug"
<p class="text-gray-600 leading-relaxed"> >
Génération statique ultra-rapide avec Astro. Zéro JavaScript Consultant-formateur<br />AI Automation &<br />Expert n8n à
par défaut, hydratation partielle intelligente uniquement Lausanne
quand nécessaire. </h2>
</p>
</div>
<div> <p
<h2 class="text-2xl font-semibold mb-3">Design System</h2> class="text-lg text-black font-medium leading-relaxed max-w-sm text-balance"
<p class="text-gray-600 leading-relaxed"> >
Tailwind CSS intégré pour un développement rapide et Avec 20 ans d'expérience technique, j'accompagne les équipes et
cohérent. Typographie soignée avec Inter, design épuré et agences pour automatiser leurs processus et prototyper leurs idées
moderne. grâce à l'IA.
</p> </p>
</div> </div>
</div>
<div> <!-- Footer (Moved from Right Col) -->
<h2 class="text-2xl font-semibold mb-3"> <div
Prêt pour la production class="border-t border-black bg-gray-50 p-6 flex items-center justify-between text-xs font-mono uppercase tracking-widest text-black/50"
</h2> >
<p class="text-gray-600 leading-relaxed"> <span>© {new Date().getFullYear()} Emmanuel Bernard</span>
Build Docker multi-stage optimisé, SEO configuré, structure <span>Lausanne, CH</span>
claire et extensible. </div>
</p> </div>
</div>
</div>
<!-- CTA --> <!-- RIGHT COLUMN: Links Broken Grid (Spans 7 cols) -->
<div class="mt-16 pt-12 border-t border-gray-200"> <div class="lg:col-span-7 grid grid-cols-1 sm:grid-cols-2">
<div class="flex items-center gap-2 mb-2"> <!-- Link Block 1: Agency Site (Full Width) -->
<span <a
class="inline-block px-2 py-1 text-xs font-medium bg-gray-900 text-white rounded" href="https://avqn.ch"
> target="_blank"
Nouveau rel="noopener noreferrer"
</span> class="group relative sm:col-span-2 border-b border-black p-8 sm:p-12 hover:bg-black hover:text-white transition-colors duration-300 flex flex-col justify-center min-h-[240px]"
<span class="text-sm text-gray-600">Prêt pour vos projets</span> >
</div> <span
<p class="text-sm text-gray-500"> class="text-sm font-bold uppercase tracking-widest mb-2 opacity-60 group-hover:opacity-80"
Commencez à construire votre projet dès maintenant. >AVQN.CH</span
</p> >
</div> <span
</main> class="text-3xl sm:text-4xl font-black uppercase leading-none tracking-tighter mb-4"
>Aussi Vite<br />Que Nécessaire</span
>
<p
class="text-sm sm:text-base font-medium max-w-sm mt-auto border-l-2 border-current pl-3 opacity-90"
>
Découvrez mes services en<br />AI Automation et n8n
</p>
<div class="absolute top-6 right-6">
<span class="text-4xl font-light">↗</span>
</div>
</a>
<!-- Link Block 2: The AI Atelier -->
<a
href="https://www.skool.com/the-ai-atelier/about"
target="_blank"
rel="noopener noreferrer"
class="group relative border-b sm:border-r border-black p-8 hover:bg-black hover:text-white transition-colors duration-300 flex flex-col justify-between min-h-[200px]"
>
<div class="absolute top-6 right-6">
<span class="text-2xl font-light">↗</span>
</div>
<div class="mt-auto">
<span class="block text-2xl font-bold mb-1">The AI Atelier</span>
<span class="text-xs uppercase opacity-60">Skool Community</span>
</div>
</a>
<!-- Link Block 3: Your Video Engine -->
<a
href="https://www.yourvideoengine.com/"
target="_blank"
rel="noopener noreferrer"
class="group relative border-b border-black p-8 hover:bg-black hover:text-white transition-colors duration-300 flex flex-col justify-between min-h-[200px]"
>
<div class="absolute top-6 right-6">
<span class="text-2xl font-light">↗</span>
</div>
<div class="mt-auto">
<span class="block text-2xl font-bold mb-1">Your Video Engine</span>
<span class="text-xs uppercase opacity-60"
>AI Avatar video Generator</span
>
</div>
</a>
<!-- Link Block 4: LinkedIn -->
<a
href="https://www.linkedin.com/in/emmbernard"
target="_blank"
rel="noopener noreferrer"
class="group relative border-b sm:border-r border-black p-8 hover:bg-black hover:text-white transition-colors duration-300 flex flex-col justify-between min-h-[200px]"
>
<div class="absolute top-6 right-6">
<span class="text-2xl font-light">↗</span>
</div>
<div class="mt-auto">
<span class="block text-2xl font-bold mb-1">LinkedIn</span>
<span class="text-xs uppercase opacity-60">Connectons-nous</span>
</div>
</a>
<!-- Link Block 5: YouTube -->
<a
href="https://www.youtube.com/@emmanuelflux"
target="_blank"
rel="noopener noreferrer"
class="group relative border-b border-black p-8 hover:bg-black hover:text-white transition-colors duration-300 flex flex-col justify-between min-h-[200px]"
>
<div class="absolute top-6 right-6">
<span class="text-2xl font-light">↗</span>
</div>
<div class="mt-auto">
<span class="block text-2xl font-bold mb-1">YouTube</span>
<span class="text-xs uppercase opacity-60">Tutoriels & Démos</span>
</div>
</a>
<!-- Link Block 6: n8n -->
<a
href="https://n8n.io/creators/n8ninja/"
target="_blank"
rel="noopener noreferrer"
class="group relative sm:col-span-2 p-8 hover:bg-black hover:text-white transition-colors duration-300 flex flex-col justify-between min-h-[200px]"
>
<div class="absolute top-6 right-6">
<span class="text-2xl font-light">↗</span>
</div>
<div class="mt-auto">
<span class="block text-2xl font-bold mb-1">Mes Workflows n8n</span>
<span class="text-xs uppercase opacity-60"
>Profil Créateur & Modèles</span
>
</div>
</a>
</div>
</div>
</main>
</BaseLayout> </BaseLayout>

View File

@@ -1,7 +1,98 @@
@import "tailwindcss"; @import "tailwindcss";
@theme {
--font-sans: "General Sans", "Inter", system-ui, -apple-system, sans-serif;
--font-display: "Clash Display", "Inter", system-ui, -apple-system, sans-serif;
--color-primary-50: #FFE5EF;
--color-primary-100: #FFCCE0;
--color-primary-200: #FF99C1;
--color-primary-300: #FF66A2;
--color-primary-400: #FF5C8A;
--color-primary-500: #FF5C8A;
--color-primary-600: #FF2E6E;
--color-primary-700: #FF0052;
--color-primary-800: #CC0042;
--color-primary-900: #990032;
}
/* Fonts Setup */
@font-face {
font-family: 'General Sans';
src: url('https://cdn.avqn.ch/fonts/GeneralSans-Regular.woff2') format('woff2');
font-weight: 400;
font-display: swap;
font-style: normal;
}
@font-face {
font-family: 'General Sans';
src: url('https://cdn.avqn.ch/fonts/GeneralSans-Medium.woff2') format('woff2');
font-weight: 500;
font-display: swap;
font-style: normal;
}
@font-face {
font-family: 'General Sans';
src: url('https://cdn.avqn.ch/fonts/GeneralSans-Semibold.woff2') format('woff2');
font-weight: 600;
font-display: swap;
font-style: normal;
}
@font-face {
font-family: 'General Sans';
src: url('https://cdn.avqn.ch/fonts/GeneralSans-Bold.woff2') format('woff2');
font-weight: 700;
font-display: swap;
font-style: normal;
}
@font-face {
font-family: 'Clash Display';
src: url('https://cdn.avqn.ch/fonts/ClashDisplay-Regular.woff2') format('woff2');
font-weight: 400;
font-display: swap;
font-style: normal;
}
@font-face {
font-family: 'Clash Display';
src: url('https://cdn.avqn.ch/fonts/ClashDisplay-Medium.woff2') format('woff2');
font-weight: 500;
font-display: swap;
font-style: normal;
}
@font-face {
font-family: 'Clash Display';
src: url('https://cdn.avqn.ch/fonts/ClashDisplay-Semibold.woff2') format('woff2');
font-weight: 600;
font-display: swap;
font-style: normal;
}
@font-face {
font-family: 'Clash Display';
src: url('https://cdn.avqn.ch/fonts/ClashDisplay-Bold.woff2') format('woff2');
font-weight: 700;
font-display: swap;
font-style: normal;
}
@layer base { @layer base {
body { body {
font-family: 'Inter', system-ui, -apple-system, sans-serif; font-family: var(--font-sans);
@apply bg-primary-50 text-gray-900 antialiased selection:bg-primary-500 selection:text-white;
}
h1,
h2,
h3,
h4,
h5,
h6 {
font-family: var(--font-display);
} }
} }