Converti chill-theme en dossier classique

This commit is contained in:
Boris Waaub
2026-01-28 09:40:37 +01:00
parent 577786f22d
commit cc60b64505
118 changed files with 11868 additions and 1 deletions
@@ -0,0 +1,28 @@
{{ if .Site.Params.cta.enable }}
<section class="cta-section">
<div class="container">
{{ $angle := .Site.Params.cta.gradient_angle | default 45 }}
{{ $from := .Site.Params.cta.gradient_from }}
{{ $to := .Site.Params.cta.gradient_to }}
<div class="relative rounded-lg overflow-hidden bg-primary-600 cta-gradient"
style="--gradient-angle: {{ $angle }}; --gradient-from: {{ $from }}; --gradient-to: {{ $to }}">
<div class="relative text-center max-w-3xl mx-auto px-6 py-10">
<h2 class="text-3xl md:text-4xl font-bold text-white mb-6">{{ .Site.Params.cta.title }}</h2>
<p class="text-xl text-primary-100 mb-8">{{ .Site.Params.cta.description }}</p>
<div class="flex flex-col sm:flex-row justify-center gap-4">
{{ with .Site.Params.cta.primary_button }}
<a href="{{ .url }}" class="btn bg-white text-primary-600 hover:bg-gray-100">
{{ .text }}
</a>
{{ end }}
{{ with .Site.Params.cta.secondary_button }}
<a href="{{ .url }}" class="btn border-2 border-white text-white hover:bg-primary-700">
{{ .text }}
</a>
{{ end }}
</div>
</div>
</div>
</div>
</section>
{{ end }}
@@ -0,0 +1,46 @@
{{ $lang := .Language.Lang }}
<div class="bg-primary-50 p-6 rounded-lg">
<h3 class="text-lg font-bold text-gray-900 mb-2">
{{ if .title }}
{{ .title }}
{{ else }}
{{ if eq $lang "zh-cn" }}订阅新闻通讯{{ else }}Subscribe to Newsletter{{ end }}
{{ end }}
</h3>
<p class="text-sm text-gray-600 mb-4">
{{ if .description }}
{{ .description }}
{{ else }}
{{ if eq $lang "zh-cn" }}将最新文章直接发送到您的收件箱{{ else }}Get the latest posts delivered right to your inbox{{ end }}
{{ end }}
</p>
<form action="{{ .action | default "#" }}" method="POST" class="space-y-3">
{{ with .hidden }}
{{ range $name, $value := . }}
<input type="hidden" name="{{ $name }}" value="{{ $value }}">
{{ end }}
{{ end }}
<div>
<input
type="email"
name="{{ .emailName | default "email" }}"
placeholder="{{ if .placeholder }}{{ .placeholder }}{{ else }}{{ if eq $lang "zh-cn" }}输入您的邮箱{{ else }}Enter your email{{ end }}{{ end }}"
required
class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-primary-500 focus:border-primary-500"
>
</div>
<button
type="submit"
class="w-full px-4 py-2 bg-primary-600 text-white rounded-lg hover:bg-primary-700 transition-colors duration-200"
>
{{ if .buttonText }}{{ .buttonText }}{{ else }}{{ if eq $lang "zh-cn" }}订阅{{ else }}Subscribe{{ end }}{{ end }}
</button>
{{ with .disclaimer }}
<p class="text-xs text-gray-500 mt-2">{{ . }}</p>
{{ end }}
</form>
</div>
@@ -0,0 +1,18 @@
<!-- Custom Head Content -->
<!--
This partial is intentionally left empty in the theme.
Users can override this partial in their own site by creating:
layouts/partials/custom-head.html
Example usage - Add any custom code to the <head> section:
- Custom tracking scripts (Hotjar, Mixpanel, etc.)
- Meta tags for verification (Google Search Console, Pinterest, etc.)
- Custom CSS or JavaScript libraries
- Any other HTML that should be in the <head>
Example:
<script>
// Your custom tracking code
</script>
-->
@@ -0,0 +1,22 @@
<div class="docs-sidebar bg-white shadow-sm rounded-lg p-4 sticky top-20 mt-2">
<h3 class="text-lg font-semibold text-gray-900 mb-3 mt-1">{{ i18n "documentation" }}</h3>
<nav class="docs-nav">
<ul class="space-y-1">
{{ range (where .Site.Pages "Section" "docs").ByWeight }}
{{ if and .Title (not .IsHome) (ne .Kind "section") }}
<li>
<a href="{{ .RelPermalink }}"
class="block px-4 py-2 rounded-md transition-colors duration-200
{{ if eq .RelPermalink $.RelPermalink }}
bg-indigo-50 text-indigo-600 font-medium
{{ else }}
text-gray-700 hover:bg-gray-50 hover:text-gray-900
{{ end }}">
{{ .Title }}
</a>
</li>
{{ end }}
{{ end }}
</ul>
</nav>
</div>
@@ -0,0 +1,151 @@
<footer class="footer py-12 ">
<div class="container mx-auto px-4 sm:px-6 lg:px-8 max-w-7xl">
<div class="flex flex-col md:flex-row justify-between space-y-4 md:space-y-0">
<!-- Logo and Social Media -->
<div class="flex-1">
<div class="flex items-center space-x-3 mb-4">
<a href="{{ .Site.BaseURL }}" class="inline-block">
{{ with .Site.Params.logo }}
<img src="{{ . | relURL }}" alt="{{ $.Site.Title }}" class="h-6">
{{ end }}
</a>
<span class="text-xl font-bold text-gray-900">{{ .Site.Title }}</span>
</div>
<div class="flex space-x-3 p-2">
{{ with .Site.Params.social.linkedin }}
<a href="{{ . }}" class="text-gray-600 hover:text-gray-900" target="_blank" rel="noopener noreferrer">
<span class="sr-only">LinkedIn</span>
<img src="/images/social/linkedin.svg" alt="LinkedIn" class="h-5 w-5">
</a>
{{ end }}
{{ with .Site.Params.social.bluesky }}
<a href="{{ . }}" class="text-gray-600 hover:text-gray-900" target="_blank" rel="noopener noreferrer">
<span class="sr-only">Bluesky</span>
<img src="/images/social/bluesky.svg" alt="Bluesky" class="h-5 w-5">
</a>
{{ end }}
{{ with .Site.Params.social.twitter }}
<a href="{{ . }}" class="text-gray-600 hover:text-gray-900" target="_blank" rel="noopener noreferrer">
<span class="sr-only">Twitter (X)</span>
<img src="/images/social/twitter.svg" alt="Twitter" class="h-5 w-5">
</a>
{{ end }}
{{ with .Site.Params.social.youtube }}
<a href="{{ . }}" class="text-gray-600 hover:text-gray-900" target="_blank" rel="noopener noreferrer">
<span class="sr-only">YouTube</span>
<img src="/images/social/youtube.svg" alt="YouTube" class="h-5 w-5">
</a>
{{ end }}
{{ with .Site.Params.social.facebook }}
<a href="{{ . }}" class="text-gray-600 hover:text-gray-900" target="_blank" rel="noopener noreferrer">
<span class="sr-only">Facebook</span>
<img src="/images/social/facebook.svg" alt="Facebook" class="h-5 w-5">
</a>
{{ end }}
{{ with .Site.Params.social.instagram }}
<a href="{{ . }}" class="text-gray-600 hover:text-gray-900" target="_blank" rel="noopener noreferrer">
<span class="sr-only">Instagram</span>
<img src="/images/social/instagram.svg" alt="Instagram" class="h-5 w-5">
</a>
{{ end }}
{{ with .Site.Params.social.github }}
<a href="{{ . }}" class="text-gray-600 hover:text-gray-900" target="_blank" rel="noopener noreferrer">
<span class="sr-only">GitHub</span>
<img src="/images/social/github.svg" alt="GitHub" class="h-5 w-5">
</a>
{{ end }}
{{ with .Site.Params.social.telegram }}
<a href="{{ . }}" class="text-gray-600 hover:text-gray-900" target="_blank" rel="noopener noreferrer">
<span class="sr-only">Telegram</span>
<img src="/images/social/telegram.svg" alt="Telegram" class="h-5 w-5">
</a>
{{ end }}
{{ with .Site.Params.social.discord }}
<a href="{{ . }}" class="text-gray-600 hover:text-gray-900" target="_blank" rel="noopener noreferrer">
<span class="sr-only">Discord</span>
<img src="/images/social/discord.svg" alt="Discord" class="h-5 w-5">
</a>
{{ end }}
{{ with .Site.Params.social.slack }}
<a href="{{ . }}" class="text-gray-600 hover:text-gray-900" target="_blank" rel="noopener noreferrer">
<span class="sr-only">Slack</span>
<img src="/images/social/slack.svg" alt="Slack" class="h-5 w-5">
</a>
{{ end }}
{{ with .Site.Params.social.medium }}
<a href="{{ . }}" class="text-gray-600 hover:text-gray-900" target="_blank" rel="noopener noreferrer">
<span class="sr-only">Medium</span>
<img src="/images/social/medium.svg" alt="Medium" class="h-5 w-5">
</a>
{{ end }}
{{ with .Site.Params.social.dribbble }}
<a href="{{ . }}" class="text-gray-600 hover:text-gray-900" target="_blank" rel="noopener noreferrer">
<span class="sr-only">Dribbble</span>
<img src="/images/social/dribbble.svg" alt="Dribbble" class="h-5 w-5">
</a>
{{ end }}
{{ with .Site.Params.social.behance }}
<a href="{{ . }}" class="text-gray-600 hover:text-gray-900" target="_blank" rel="noopener noreferrer">
<span class="sr-only">Behance</span>
<img src="/images/social/behance.svg" alt="Behance" class="h-5 w-5">
</a>
{{ end }}
{{ with .Site.Params.social.mastodon }}
<a href="{{ . }}" class="text-gray-600 hover:text-gray-900" target="_blank" rel="noopener noreferrer">
<span class="sr-only">mastodon</span>
<img src="/images/social/mastodon.svg" alt="mastodon" class="h-5 w-5">
</a>
{{ end }}
{{ with .Site.Params.social.gitlab }}
<a href="{{ . }}" class="text-gray-600 hover:text-gray-900" target="_blank" rel="noopener noreferrer">
<span class="sr-only">gitlab</span>
<img src="/images/social/gitlab.svg" alt="gitlab" class="h-5 w-5">
</a>
{{ end }}
</div>
</div>
<!-- Column 1 -->
<div class="flex-1">
<h3 class="text-sm font-semibold uppercase tracking-wider text-gray-900 mb-4">{{ .Site.Params.footer.column_1_title }}</h3>
<ul class="space-y-2">
{{ range .Site.Menus.footer_column_1 }}
<li><a href="{{ .URL }}" class="text-gray-600 hover:text-primary-600">{{ .Name }}</a></li>
{{ end }}
</ul>
</div>
<!-- Column 2 -->
<div class="flex-1">
<h3 class="text-sm font-semibold uppercase tracking-wider text-gray-900 mb-4">{{ .Site.Params.footer.column_2_title }}</h3>
<ul class="space-y-2">
{{ range .Site.Menus.footer_column_2 }}
<li><a href="{{ .URL }}" class="text-gray-600 hover:text-primary-600">{{ .Name }}</a></li>
{{ end }}
</ul>
</div>
<!-- Column 3 -->
<div class="flex-1">
<h3 class="text-sm font-semibold uppercase tracking-wider text-gray-900 mb-4">{{ .Site.Params.footer.column_3_title }}</h3>
<ul class="space-y-2">
{{ range .Site.Menus.footer_column_3 }}
<li><a href="{{ .URL }}" class="text-gray-600 hover:text-primary-600">{{ .Name }}</a></li>
{{ end }}
</ul>
</div>
</div>
<!-- Bottom -->
<div class="mt-12 pt-8 border-t border-gray-600">
<div class="flex flex-col md:flex-row justify-between items-center space-y-4 md:space-y-0">
<p class="text-gray-600 text-sm">
© {{ now.Format "2006" }} {{ .Site.Title }}. All rights reserved.
</p>
<a href="https://www.champs-libres.coop/" class="text-sm text-gray-600 hover:text-primary-600" target="_blank" rel="noopener noreferrer">
Designed by Champs-Libres
</a>
</div>
</div>
</div>
</footer>
@@ -0,0 +1,10 @@
{{ if and hugo.IsProduction .Site.Params.googleAnalytics }}
<!-- Google tag (gtag.js) -->
<script async src="https://www.googletagmanager.com/gtag/js?id={{ .Site.Params.googleAnalytics }}"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', '{{ .Site.Params.googleAnalytics }}');
</script>
{{ end }}
@@ -0,0 +1,9 @@
{{ if and hugo.IsProduction .Site.Params.googleTagManager }}
<!-- Google Tag Manager -->
<script>(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
})(window,document,'script','dataLayer','{{ .Site.Params.googleTagManager }}');</script>
<!-- End Google Tag Manager -->
{{ end }}
@@ -0,0 +1,160 @@
{{ $headerConfig := .Site.Params.header }}
{{ $dropdownConfig := $headerConfig.menu.dropdown }}
<div class="mobile-menu-wrapper">
<input type="checkbox" id="nav-toggle" class="nav-toggle">
<header class="fixed w-full top-0 z-50 {{ with $headerConfig.background }}{{ . }}{{ else }}bg-white/80 backdrop-blur-sm{{ end }} {{ with $headerConfig.border }}{{ . }}{{ else }}border-b border-gray-100{{ end }}">
<div class="container mx-auto px-4 sm:px-6 lg:px-8 max-w-7xl">
<nav class="flex items-center justify-between h-20">
<!-- Logo and Title -->
<a href="{{ "/" | relLangURL }}" class="flex items-center space-x-4">
{{ with $headerConfig.logo }}
<img src="{{ .src | relURL }}" alt="{{ $.Site.Title }}" class="{{ with .class }}{{ . }}{{ else }}h-12{{ end }}">
{{ else }}
<span class="text-3xl font-bold text-gray-900">{{ .Site.Title }}</span>
{{ end }}
{{ if .Site.Title }}
<span class="text-3xl font-semibold text-gray-800">{{ .Site.Title }}</span>
{{ end }}
</a>
<!-- Navigation -->
<div class="hidden md:flex items-center {{ with $headerConfig.menu.spacing }}{{ . }}{{ else }}space-x-8{{ end }}">
{{ range .Site.Menus.main }}
{{ if .Params.has_submenu }}
<div class="relative group">
<button class="flex items-center {{ with $headerConfig.menu.linkClass }}{{ . }}{{ else }}text-base text-gray-900 hover:text-primary-600 font-bold transition duration-200{{ end }}">
{{ .Name }}
<svg class="ml-2 w-4 h-4" 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="absolute left-0 mt-2 {{ $dropdownConfig.width | default "w-72" }} opacity-0 invisible group-hover:opacity-100 group-hover:visible transition-all duration-200 ease-in-out">
<div class="{{ $dropdownConfig.container_padding | default "py-6" }} {{ $dropdownConfig.background | default "bg-white" }} {{ $dropdownConfig.border | default "border border-gray-100" }} {{ $dropdownConfig.shadow | default "shadow-xl" }} {{ $dropdownConfig.radius | default "rounded-lg" }}">
{{ range .Params.submenu }}
<a href="{{ .url }}" class="block {{ $dropdownConfig.item_padding | default "px-8 py-3" }} {{ $dropdownConfig.text_size | default "text-sm" }} {{ $dropdownConfig.text_color | default "text-gray-700" }} {{ $dropdownConfig.hover_background | default "hover:bg-gray-50" }}">{{ .name }}</a>
{{ end }}
</div>
</div>
</div>
{{ else }}
<a href="{{ .URL }}" class="{{ with $headerConfig.menu.linkClass }}{{ . }}{{ else }}text-base text-gray-900 hover:text-primary-600 font-bold transition duration-200{{ end }}">{{ .Name }}</a>
{{ end }}
{{ end }}
<!-- Language Switcher -->
{{ partial "language-switcher" . }}
</div>
<!-- CTA Buttons -->
{{ if not $headerConfig.hideButtons }}
<div class="hidden md:flex items-center space-x-4">
{{ with $headerConfig.buttons.signIn }}
<a href="{{ .url | default "#" }}" class="{{ with .class }}{{ . }}{{ else }}inline-flex items-center justify-center px-6 py-3 rounded-lg font-bold transition duration-200 ease-in-out border-2 border-gray-200 hover:border-primary-600 hover:text-primary-600{{ end }}">
{{ .text | default "Sign in" }}
</a>
{{ end }}
{{ with $headerConfig.buttons.getStarted }}
<a href="{{ .url | default "#" }}" class="{{ with .class }}{{ . }}{{ else }}inline-flex items-center justify-center px-6 py-3 rounded-lg font-bold transition duration-200 ease-in-out bg-primary-600 text-white hover:bg-primary-700 hover:scale-105{{ end }}">
{{ .text | default "Get Started" }}
</a>
{{ end }}
</div>
{{ end }}
<!-- Mobile Menu Toggle -->
<div class="md:hidden">
<label for="nav-toggle" class="p-2 rounded-lg hover:bg-gray-100 focus:outline-none focus:ring-2 focus:ring-primary-600 focus:ring-offset-2 transition-colors cursor-pointer">
<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="M4 6h16M4 12h16M4 18h16"></path>
</svg>
</label>
</div>
</nav>
</div>
<!-- Mobile Menu -->
<div class="nav-content md:hidden w-full fixed left-0 right-0 top-20 bg-white border-t border-gray-100 shadow-lg max-h-[calc(100vh-5rem)] overflow-y-auto">
<div class="w-full px-6 py-4">
{{ range .Site.Menus.main }}
{{ if .Params.has_submenu }}
<div class="py-2">
<div class="text-xl text-gray-900 font-bold mb-2">{{ .Name }}</div>
<div class="pl-4">
{{ range .Params.submenu }}
<a href="{{ .url }}" class="block text-gray-700 hover:text-primary-600 py-2">{{ .name }}</a>
{{ end }}
</div>
</div>
{{ else }}
<a href="{{ .URL }}" class="{{ with $headerConfig.menu.mobileLinkClass }}{{ . }}{{ else }}block text-xl text-gray-900 hover:text-primary-600 font-bold transition duration-200 py-2{{ end }}">{{ .Name }}</a>
{{ end }}
{{ end }}
<!-- Mobile Language Switcher -->
{{ if .Site.IsMultiLingual }}
<div class="py-4 border-t border-gray-200 mt-4">
<div class="text-lg text-gray-600 font-semibold mb-2">{{ i18n "language" }}</div>
{{ range .Site.Languages }}
{{ if eq $.Site.Language.Lang .Lang }}
<span class="block py-2 text-primary-600 font-bold">{{ .LanguageName }}</span>
{{ else }}
{{ $langURL := printf "/%s/" .Lang }}
<a href="{{ $langURL }}" class="language-switch-link block py-2 text-gray-700 hover:text-primary-600" data-lang="{{ .Lang }}">
{{ .LanguageName }}
</a>
{{ end }}
{{ end }}
</div>
{{ end }}
{{ if not $headerConfig.hideButtons }}
<div class="pt-4 space-y-4">
{{ with $headerConfig.buttons.signIn }}
<a href="{{ .url | default "#" }}" class="{{ with .mobileClass }}{{ . }}{{ else }}block text-center px-6 py-3 rounded-lg font-bold transition duration-200 ease-in-out border-2 border-gray-200 hover:border-primary-600 hover:text-primary-600{{ end }}">
{{ .text | default "Sign in" }}
</a>
{{ end }}
{{ with $headerConfig.buttons.getStarted }}
<a href="{{ .url | default "#" }}" class="{{ with .mobileClass }}{{ . }}{{ else }}block text-center px-6 py-3 rounded-lg font-bold transition duration-200 ease-in-out bg-primary-600 text-white hover:bg-primary-700 hover:scale-105{{ end }}">
{{ .text | default "Get Started" }}
</a>
{{ end }}
</div>
{{ end }}
</div>
</div>
</header>
<style>
.mobile-menu-wrapper {
position: relative;
}
.nav-toggle {
display: none;
}
.nav-content {
display: none;
-webkit-overflow-scrolling: touch;
}
.nav-toggle:checked ~ header .nav-content {
display: block;
}
</style>
<script>
(function() {
var navToggle = document.getElementById('nav-toggle');
if (navToggle) {
navToggle.addEventListener('change', function() {
if (this.checked) {
document.body.style.overflow = 'hidden';
} else {
document.body.style.overflow = '';
}
});
}
})();
</script>
</div>
@@ -0,0 +1,22 @@
{{- $iconClass := printf "w-%s h-%s" (.size | default "6") (.size | default "6") -}}
{{- $color := .color | default "#000000" -}}
<svg class="{{ $iconClass }}" style="color: {{ $color }};" fill="none" stroke="currentColor" viewBox="0 0 24 24">
{{- if eq .name "chart" -}}
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 19v-6a2 2 0 00-2-2H5a2 2 0 00-2 2v6a2 2 0 002 2h2a2 2 0 002-2zm0 0V9a2 2 0 012-2h2a2 2 0 012 2v10m-6 0a2 2 0 002 2h2a2 2 0 002-2m0 0V5a2 2 0 012-2h2a2 2 0 012 2v14a2 2 0 01-2 2h-2a2 2 0 01-2-2z"></path>
{{- else if eq .name "attribution" -}}
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 7h8m0 0v8m0-8l-8 8-4-4-6 6"></path>
{{- else if eq .name "roi" -}}
<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>
{{- else if eq .name "check" -}}
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"></path>
{{- else if eq .name "analytics" -}}
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M16 8v8m-4-5v5m-4-2v2m-2 4h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z"></path>
{{- else if eq .name "funnel" -}}
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 4h18M5 8h14M7 12h10M9 16h6M11 20h2"></path>
{{- else if eq .name "target" -}}
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"></path>
{{- else if eq .name "custom" -}}
{{ .path | safeHTML }}
{{- end -}}
</svg>
@@ -0,0 +1,24 @@
{{ if .Site.IsMultiLingual }}
{{ $headerConfig := .Site.Params.header }}
{{ $dropdownConfig := $headerConfig.menu.dropdown }}
<div class="relative group">
<button class="flex items-center {{ with $headerConfig.menu.linkClass }}{{ . }}{{ else }}text-base text-gray-900 hover:text-primary-600 font-bold transition duration-200{{ end }}">
{{ .Site.Language.LanguageName }}
<svg class="ml-2 w-4 h-4" 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="absolute right-0 mt-2 {{ $dropdownConfig.width | default "w-72" }} opacity-0 invisible group-hover:opacity-100 group-hover:visible transition-all duration-200 ease-in-out">
<div class="{{ $dropdownConfig.container_padding | default "py-6" }} {{ $dropdownConfig.background | default "bg-white" }} {{ $dropdownConfig.border | default "border border-gray-100" }} {{ $dropdownConfig.shadow | default "shadow-xl" }} {{ $dropdownConfig.radius | default "rounded-lg" }}">
{{ range .Site.Languages }}
{{ if ne $.Site.Language.Lang .Lang }}
{{ $langURL := printf "/%s/" .Lang }}
<a href="{{ $langURL }}" class="language-switch-link block {{ $dropdownConfig.item_padding | default "px-8 py-3" }} {{ $dropdownConfig.text_size | default "text-sm" }} {{ $dropdownConfig.text_color | default "text-gray-700" }} {{ $dropdownConfig.hover_background | default "hover:bg-gray-50" }}" data-lang="{{ .Lang }}">
{{ .LanguageName }}
</a>
{{ end }}
{{ end }}
</div>
</div>
</div>
{{ end }}
@@ -0,0 +1,80 @@
<article class="bg-white rounded-lg shadow-md overflow-hidden hover:shadow-lg transition-shadow duration-300">
{{ with .Params.featured_image }}
<a href="{{ $.RelPermalink }}" class="block aspect-w-16 aspect-h-9 overflow-hidden">
<img
src="{{ . }}"
alt="{{ $.Title }}"
class="object-cover w-full h-full transform hover:scale-105 transition-transform duration-300"
loading="lazy"
>
</a>
{{ end }}
<div class="p-6">
<!-- Category -->
{{ with .Params.categories }}
<div class="mb-4">
{{ range first 1 . }}
<a href="{{ "/categories/" | relLangURL }}{{ . | urlize }}"
class="inline-block px-3 py-1 text-sm font-medium text-primary-600 bg-primary-50 rounded-full hover:bg-primary-100">
{{ . }}
</a>
{{ end }}
</div>
{{ end }}
<!-- Title -->
<h2 class="text-2xl font-bold mb-3 hover:text-primary-600 transition-colors duration-200">
<a href="{{ .RelPermalink }}">{{ .Title }}</a>
</h2>
<!-- Description -->
<p class="text-gray-600 mb-4 line-clamp-2">
{{ with .Description }}
{{ . }}
{{ else }}
{{ .Summary | truncate 160 }}
{{ end }}
</p>
<!-- Author and Date in a cleaner layout -->
<div class="flex items-center justify-between text-sm text-gray-500 mb-4">
{{ with .Params.author }}
<div class="flex items-center">
<svg class="w-4 h-4 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M16 7a4 4 0 11-8 0 4 4 0 018 0zM12 14a7 7 0 00-7 7h14a7 7 0 00-7-7z"></path>
</svg>
<span>{{ . }}</span>
</div>
{{ end }}
<div class="flex items-center">
<svg class="w-4 h-4 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 7V3m8 4V3m-9 8h10M5 21h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z"></path>
</svg>
<time datetime="{{ .Date.Format "2006-01-02" }}">
{{ .Date.Format "Jan 2, 2006" }}
</time>
</div>
</div>
<!-- Read More link and Reading Time -->
<div class="flex justify-between items-center">
<a href="{{ .RelPermalink }}"
class="inline-flex items-center text-primary-600 hover:text-primary-700 font-medium">
{{ i18n "readMore" }}
<svg class="w-4 h-4 ml-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M14 5l7 7m0 0l-7 7m7-7H3"></path>
</svg>
</a>
<!-- Reading Time -->
<span class="text-sm text-gray-500 flex items-center">
<svg class="w-4 h-4 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 6.253v13m0-13C10.832 5.477 9.246 5 7.5 5S4.168 5.477 3 6.253v13C4.168 18.477 5.754 18 7.5 18s3.332.477 4.5 1.253m0-13C13.168 5.477 14.754 5 16.5 5c1.747 0 3.332.477 4.5 1.253v13C19.832 18.477 18.247 18 16.5 18c-1.746 0-3.332.477-4.5 1.253"></path>
</svg>
<span>{{ .ReadingTime }} {{ i18n "readTime" }}</span>
</span>
</div>
</div>
</article>
@@ -0,0 +1,45 @@
<div class="flex flex-col space-y-4">
<!-- Author and Date -->
<div class="flex items-center justify-between text-sm text-gray-500">
{{ with .Params.author }}
<div class="flex items-center">
<svg class="w-4 h-4 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M16 7a4 4 0 11-8 0 4 4 0 018 0zM12 14a7 7 0 00-7 7h14a7 7 0 00-7-7z"></path>
</svg>
<span>{{ . }}</span>
</div>
{{ end }}
<div class="flex items-center space-x-6">
<div class="flex items-center">
<svg class="w-4 h-4 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 6.253v13m0-13C10.832 5.477 9.246 5 7.5 5S4.168 5.477 3 6.253v13C4.168 18.477 5.754 18 7.5 18s3.332.477 4.5 1.253m0-13C13.168 5.477 14.754 5 16.5 5c1.747 0 3.332.477 4.5 1.253v13C19.832 18.477 18.247 18 16.5 18c-1.746 0-3.332.477-4.5 1.253"></path>
</svg>
<span>{{ .ReadingTime }} {{ i18n "minRead" . }}</span>
</div>
<div class="flex items-center">
<svg class="w-4 h-4 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 7V3m8 4V3m-9 8h10M5 21h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z"></path>
</svg>
<time datetime="{{ .Date.Format "2006-01-02" }}">
{{ .Date.Format (i18n "dateFormat" .) }}
</time>
</div>
</div>
</div>
<!-- Tags -->
{{ with .Params.tags }}
<div class="flex items-center flex-wrap gap-2">
{{ range . }}
<a href="{{ "/tags/" | relLangURL }}{{ . | urlize }}"
class="px-3 py-1 bg-gray-100 hover:bg-gray-200 rounded-full text-sm text-gray-700 transition-colors duration-200">
#{{ . }}
</a>
{{ end }}
</div>
{{ end }}
</div>
@@ -0,0 +1,52 @@
{{/* Feature Partial (utilisé par le carousel) */}}
{{ $title := .title }}
{{ $titleBtn := .titleBtn}}
{{ $description := .description }}
{{ $badge := .badge }}
{{ $badgeColor := .badgeColor | default "chill-blue" }}
{{ $image := .image }}
{{ $buttonText := .buttonText | default "Learn More" }}
{{ $buttonLink := .buttonLink | default "#" }}
{{ $imagePosition := .imagePosition | default "right" }}
{{ $features := split (.features) "," }}
<div class="grid lg:grid-cols-2 gap-12 items-center badge-{{ $badgeColor }}">
{{ if eq $imagePosition "left" }}
<div class="order-2 lg:order-1">
<img src="{{ $image | relURL }}" alt="{{ $title }}" class="rounded-xl shadow-elevation">
</div>
{{ end }}
<div class="space-y-6 {{ if eq $imagePosition "left" }}order-1 lg:order-2{{ end }}">
<style>
.badge {
background-color: color-mix(in srgb, var(--badge-color) 30%, transparent);
color: #222;
}
.badge-icon {
color: var(--badge-color);
}
</style>
<div class="badge inline-block px-4 py-2 rounded-full font-medium">{{ $badge }}</div>
<h3 class="text-2xl md:text-3xl font-bold">{{ $title }}</h3>
<p class="text-lg text-gray-600">{{ $description }}</p>
<ul class="space-y-4">
{{ range $features }}
<li class="flex items-center space-x-3">
<svg class="badge-icon w-5 h-5" fill="currentColor" viewBox="0 0 20 20">
<path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z" clip-rule="evenodd"/>
</svg>
<span>{{ . | default "" }}</span>
</li>
{{ end }}
</ul>
<a href="{{ $buttonLink }}" class="btn-primary inline-block">{{ $buttonText }}</a>
</div>
{{ if ne $imagePosition "left" }}
<div>
<img src="{{ $image | relURL }}" alt="{{ $title }}" class="rounded-xl shadow-elevation">
</div>
{{ end }}
</div>
@@ -0,0 +1,88 @@
<div class="space-y-8">
<!-- Subscribe Form -->
{{ if .Site.Params.blog.sidebar.subscribe.enable }}
{{ $params := dict
"Site" .Site
"Language" .Site.Language
"title" .Site.Params.blog.sidebar.subscribe.title
"description" .Site.Params.blog.sidebar.subscribe.description
"action" .Site.Params.blog.sidebar.subscribe.action
"emailName" .Site.Params.blog.sidebar.subscribe.emailName
"buttonText" .Site.Params.blog.sidebar.subscribe.buttonText
"placeholder" .Site.Params.blog.sidebar.subscribe.placeholder
"disclaimer" .Site.Params.blog.sidebar.subscribe.disclaimer
"hidden" .Site.Params.blog.sidebar.subscribe.hidden
}}
{{ partial "components/subscribe-form" $params }}
{{ end }}
<!-- Recent Articles -->
{{ if .Site.Params.blog.sidebar.recent.enable }}
<div class="bg-white rounded-lg shadow-md p-6">
<h3 class="text-lg font-bold mb-4">{{ .Site.Params.blog.sidebar.recent.title | default (i18n "recentArticles" .) }}</h3>
<div class="space-y-4">
{{ $recentCount := .Site.Params.blog.sidebar.recent.count | default 5 }}
{{ range first $recentCount (where .Site.RegularPages "Type" "blog") }}
<div class="group">
<a href="{{ .RelPermalink }}" class="block">
{{ with .Params.featured_image }}
<div class="aspect-w-16 aspect-h-9 mb-3 overflow-hidden rounded-lg">
<img
src="{{ . }}"
alt="{{ $.Title }}"
class="object-cover w-full h-full transform group-hover:scale-105 transition-transform duration-300"
loading="lazy"
>
</div>
{{ end }}
<h4 class="font-medium text-gray-900 group-hover:text-primary-600 transition-colors duration-200 line-clamp-2">
{{ .Title }}
</h4>
<div class="flex items-center text-sm text-gray-500 mt-2">
<svg class="w-4 h-4 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 7V3m8 4V3m-9 8h10M5 21h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z"></path>
</svg>
<time datetime="{{ .Date.Format "2006-01-02" }}">
{{ .Date.Format "Jan 2, 2006" }}
</time>
</div>
</a>
</div>
{{ end }}
</div>
</div>
{{ end }}
<!-- Categories -->
{{ if .Site.Params.blog.sidebar.categories.enable }}
<div class="bg-white rounded-lg shadow-md p-6">
<h3 class="text-lg font-bold mb-4">{{ .Site.Params.blog.sidebar.categories.title | default (i18n "categories" .) }}</h3>
<div class="flex flex-wrap gap-2">
{{ range $name, $taxonomy := .Site.Taxonomies.categories }}
<a href="{{ "/categories/" | relLangURL }}{{ $name | urlize }}"
class="inline-block px-3 py-1 text-sm font-medium text-primary-600 bg-primary-50 rounded-full hover:bg-primary-100">
{{ $name }}
<span class="text-gray-500 ml-1">({{ $taxonomy.Count }})</span>
</a>
{{ end }}
</div>
</div>
{{ end }}
<!-- Tags Cloud -->
{{ if .Site.Params.blog.sidebar.tags.enable }}
<div class="bg-white rounded-lg shadow-md p-6">
<h3 class="text-lg font-bold mb-4">{{ .Site.Params.blog.sidebar.tags.title | default (i18n "popularTags" .) }}</h3>
<div class="flex flex-wrap gap-2">
{{ $tagCount := .Site.Params.blog.sidebar.tags.count | default 20 }}
{{ range first $tagCount .Site.Taxonomies.tags.ByCount }}
<a href="{{ "/tags/" | relLangURL }}{{ .Name | urlize }}"
class="text-sm text-gray-600 hover:text-primary-600">
#{{ .Name }}
<span class="text-gray-500">({{ .Count }})</span>
</a>
{{ end }}
</div>
</div>
{{ end }}
</div>