Amélioration de la réactivité et des styles : ajustements CSS, templates dynamiques, et ajout de la gestion de version applicative.

This commit is contained in:
mrtoine 2025-12-15 13:16:40 +01:00
parent ce0f1ac846
commit b7f792a182
5 changed files with 87 additions and 64 deletions

View file

@ -14,6 +14,8 @@ from pathlib import Path
import os
from dotenv import load_dotenv
import devart.context_processor
# Charger les variables d'environnement depuis le fichier .env
load_dotenv()
@ -75,6 +77,7 @@ TEMPLATES = [
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
'devart.context_processor.app_version',
'core.context_processor.site_settings',
'courses.context_processors.course_list',
],
@ -152,3 +155,18 @@ STATICFILES_DIRS = [os.path.join(BASE_DIR, 'static')]
# https://docs.djangoproject.com/en/5.0/ref/settings/#default-auto-field
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
# On défini une fonction qui va s'occuper de récupérer la version actuelle de l'application
def get_git_version():
try:
import subprocess
hash_version = subprocess.check_output(['git', 'rev-parse', '--short', 'HEAD']).strip().decode('utf-8')
app_version = subprocess.check_output(
["git", "describe", "--tags", "--abbrev=0"],
stderr=subprocess.STDOUT
).strip().decode('utf-8')
return app_version + " (" + hash_version + ")"
except Exception:
return 'Dev / Pas de git'
GIT_VERSION = get_git_version()

View file

@ -79,8 +79,9 @@
--font-mono: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
/* Layout */
--container-w: 1100px;
--gutter: 20px;
/* Fluid container and gutters for responsive spacing */
--container-w: clamp(320px, 92vw, 1100px);
--gutter: clamp(14px, 3vw, 24px);
--focus-ring: 0 0 0 3px rgba(78,158,214,0.45);
/* Utility base colors */
@ -108,6 +109,23 @@
--border-glass-light: rgba(255,255,255,0.05);
}
/*
Mobile width guardrail
- Cap container width on touch devices to improve readability and avoid edge overflows
*/
@media (hover: none) and (pointer: coarse) {
:root {
/* Keep fluid gutters but prevent overly wide lines on large/mobile landscape */
--container-w: min(92vw, 480px);
}
html, body { overflow-x: hidden; }
}
/* Global box-sizing reset to prevent width overflow on mobile
Ensures padding/border are included in the element's total width/height */
html { box-sizing: border-box; }
*, *::before, *::after { box-sizing: inherit; }
/* Light theme values — applied via colors_light.css inclusion */
/* ==========================
@ -469,8 +487,7 @@ body {
height: 100vh;
/* Ensure total box never exceeds the viewport width (padding + border included) */
box-sizing: border-box;
width: min(85vw, 380px);
max-width: 100vw;
width: min(92vw, 380px);
margin: 0;
/* Safe-area aware padding on the right (iOS notch) */
padding: var(--space-5) max(var(--gutter), env(safe-area-inset-right)) var(--space-5) var(--gutter);
@ -510,8 +527,8 @@ body {
z-index: 1100;
}
.navbar ul { flex-direction: column; width: 100%; }
.navbar li { margin: 0; }
.navbar ul { flex-direction: column; width: 100%; align-items: flex-start; }
.navbar li { margin: 0; width: 100%; }
.navbar a { display: block; padding: 12px 14px; border-radius: var(--r-1); }
/* Dropdowns behave as inline lists on mobile */
@ -524,18 +541,22 @@ body {
padding-left: 10px;
}
.navbar ul ul li { border: 0; margin: 0; padding: 6px 8px; }
.navbar ul ul { align-items: flex-start; }
.navbar ul ul li { border: 0; margin: 0; padding: 6px 8px; width: 100%; }
.navbar ul ul a { text-align: left; }
.navend {
width: 100%;
margin-top: auto; /* push to bottom */
display: flex;
flex-direction: column;
align-items: stretch;
align-items: flex-start; /* start-align items on mobile */
justify-content: flex-start;
gap: 6px;
}
.navend ul { width: 100%; }
.navend ul { width: 100%; align-items: flex-start; }
.navend a { text-align: left; }
}
/* Respect reduced motion preferences */
@ -650,17 +671,18 @@ section {
display: flex;
flex-direction: column;
padding: var(--space-6) var(--gutter);
width: min(100%, 60%);
margin: 20px auto;
width: 100%;
max-width: var(--container-w);
margin: clamp(12px, 3vw, 24px) auto;
}
.courseNav {
display: block;
float: left;
position: fixed;
position: sticky;
left: 0;
top: 150px;
max-width: 15%;
top: clamp(64px, 12vh, 150px);
max-width: clamp(220px, 22vw, 300px);
border: 1px solid;
}
@ -691,9 +713,7 @@ section {
h1 {
color: var(--primary);
font-size: clamp(1.8rem, 4vw, 2.5rem);
border-left: 5px solid var(--accent);
border-bottom: 1px solid var(--accent);
padding-left: 10px;
padding-left: var(--space-3);
}
h2 {
@ -703,8 +723,15 @@ h2 {
img {
max-width: 100%;
height: auto;
}
/* Make embedded media responsive */
iframe, video { max-width: 100%; height: auto; }
/* Responsive tables: wrap in a container if needed */
.table-responsive { width: 100%; overflow-x: auto; -webkit-overflow-scrolling: touch; }
.card-header img.thumbnails {
transition: transform 1s ease
}
@ -714,21 +741,20 @@ img {
}
.container-inline {
display: flex;
flex-direction: row;
flex-wrap: wrap;
gap: 20px;
display: grid;
grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
gap: var(--space-5);
}
.card {
display: flex;
flex-direction: column;
max-width: 250px;
width: 100%;
border-left: 1px solid var(--border);
border-top: 1px solid var(--border);
border-radius: var(--r-2);
overflow: hidden;
margin: 20px;
margin: 0;
background: var(--card);
box-shadow: var(--shadow-1);
transition: transform var(--transition-1), box-shadow var(--transition-1);
@ -767,7 +793,7 @@ img {
.def-author {
display: flex;
padding: 10px;
padding: var(--space-3);
flex-direction: row;
align-items: center;
font-size: 0.8rem;
@ -780,18 +806,18 @@ img {
}
pre {
border-radius: 5px;
border-radius: var(--r-2);
/* Ne dépasse pas du parent en largeur et défile si nécessaire */
max-width: 800px;
max-width: clamp(320px, 100%, 800px);
overflow: auto; /* scroll horizontal et vertical si besoin */
max-height: 800px;
max-height: clamp(360px, 70vh, 800px);
}
/* ====== Homepage enhancements ====== */
.hero {
display: block;
width: 100%;
padding: 80px 20px 56px;
padding: clamp(48px, 10vw, 96px) var(--gutter) clamp(32px, 6vw, 64px);
text-align: center;
background:
radial-gradient(1200px 600px at 50% -10%, rgba(78,158,214,0.20), transparent 60%),
@ -800,10 +826,7 @@ pre {
position: relative;
}
.hero-inner {
max-width: 960px;
margin: 0 auto;
}
.hero-inner { max-width: var(--container-w); margin: 0 auto; padding: 0 var(--gutter); }
.hero-decor {
position: absolute;
@ -816,31 +839,12 @@ pre {
opacity: .6;
}
.hero .hero-sub {
font-size: 1.125rem;
font-weight: 500;
margin: 10px auto 0;
max-width: 800px;
}
.hero .hero-sub { font-size: clamp(1rem, 2.4vw, 1.125rem); font-weight: 500; margin: var(--space-3) auto 0; max-width: 65ch; }
.badge-row { display: flex; gap: 10px; justify-content: center; margin: 18px 0 6px; flex-wrap: wrap; }
.badge {
display: inline-flex;
align-items: center;
gap: 8px;
padding: 6px 10px;
border: 1px solid var(--border-subtle);
border-radius: 999px;
background: color-mix(in oklab, var(--card) 80%, transparent);
font-size: .9rem;
color: var(--text-muted);
}
.badge-row { display: flex; gap: var(--space-3); justify-content: center; margin: var(--space-4) 0 var(--space-2); flex-wrap: wrap; }
.badge { display: inline-flex; align-items: center; gap: var(--space-2); padding: 6px 10px; border: 1px solid var(--border-subtle); border-radius: 999px; background: color-mix(in oklab, var(--card) 80%, transparent); font-size: .9rem; color: var(--text-muted); }
.hero-cta .button {
padding: 12px 18px;
font-size: 1rem;
border-radius: 6px;
}
.hero-cta .button { padding: 12px 18px; font-size: 1rem; border-radius: var(--r-2); }
.cta-primary {
/* Make primary CTA more visible */
@ -927,11 +931,12 @@ pre {
}
.pricing-teaser {
width: 60%;
margin: 10px auto 40px;
width: 100%;
max-width: 820px;
margin: var(--space-3) auto var(--space-6);
border: 1px solid var(--border);
border-radius: var(--r-3);
padding: 20px;
padding: var(--space-5);
background: var(--card);
}
@ -943,7 +948,7 @@ pre {
.carousel-track {
display: grid;
grid-auto-flow: column;
grid-auto-columns: 80%;
grid-auto-columns: minmax(260px, 80%);
gap: var(--space-4);
overflow-x: auto;
scroll-snap-type: x mandatory;
@ -967,7 +972,7 @@ pre {
display: grid;
gap: var(--space-4);
}
.testimonials-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--space-4); }
.testimonials-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: var(--space-4); }
.testimonial {
background: var(--card);
border: 1px solid var(--border);

View file

@ -6,7 +6,7 @@
<div class="hero-inner hero-split">
<div class="hero-text">
<h1>Apprenez à coder de A à Z</h1>
<h1>Apprendre le développement de zéro : Cours complets pour débutant (ou pas !)</h1>
<p class="hero-sub">Des cours gratuits<!-- et payants-->, structurés et concrets, pour progresser rapidement en programmation.</p>
<div class="badge-row" aria-hidden="true">
<span class="badge"><i class="fa-solid fa-code"></i> Logiciel, Web, Jeux Vidéos</span>

View file

@ -6,7 +6,7 @@
{% load static %}
<title>PartirDeZero - {% block title %}{% endblock %}</title>
<title>PartirDeZero {% block title %}{% endblock %}</title>
<meta name="description" content="{% block description %}Apprendre le développement web et la programmation en partant de zéro.{% endblock %}">

View file

@ -33,7 +33,7 @@
</div>
<div class="footer-legal">
<span>Partir de Zero ©2024 - {% now "Y" %}</span>
<span>v0.1.1</span>
<span>v{{ SITE_VERSION }}</span>
<span>Site fièrement créer par <a href="https://av-interactive.be" target="_blank" rel="noopener">AV Interactive</a></span>
</div>
</footer>