site.toml [administration] adresse : l'accueil affiche un bouton « Connexion » vers l'interface. Celle-ci peut tourner derrière le serveur web du site (rtg interface --proxy --prefixe /admin) : adresses préfixées, mot de passe obligatoire, visiteur identifié par X-Forwarded-For, cookie Secure limité au préfixe quand le site est en HTTPS. Exemples nginx et Apache dans le README. Le bouton Arrêter ne remplace plus le bloc de la tâche en même temps que la relève. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Mf2kATMtqVABHSYdxJMnim
97 lines
4.6 KiB
HTML
97 lines
4.6 KiB
HTML
{#- Gabarit commun à la page d'accueil (accueil.html) et aux listes complètes
|
|
(liste.html). Les pages filles remplissent les blocs titre et contenu. -#}
|
|
<!DOCTYPE html>
|
|
<html lang="fr">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
<title>{% block titre %}{{ titre_site }}{% endblock %}</title>
|
|
<style>
|
|
:root { color-scheme: light dark; }
|
|
* { box-sizing: border-box; }
|
|
body {
|
|
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
|
|
background: #f4f4f9; margin: 0; padding: 20px; color: #222;
|
|
}
|
|
header { text-align: center; margin-bottom: 30px; }
|
|
h1 { margin: 0 0 6px; font-size: clamp(1.6rem, 4vw, 2.4rem); }
|
|
.sous-titre { color: #777; font-size: 0.9rem; }
|
|
main { max-width: 1200px; margin: 0 auto; }
|
|
a.retour { display: inline-block; margin-bottom: 10px; color: #3498db; text-decoration: none; font-weight: bold; }
|
|
|
|
/* Rubriques de l'accueil, côte à côte ; empilées quand la place manque. */
|
|
.rubriques {
|
|
display: grid; gap: 40px;
|
|
grid-template-columns: repeat(auto-fit, minmax(min(480px, 100%), 1fr));
|
|
}
|
|
.rubrique-titre {
|
|
display: flex; justify-content: space-between; align-items: baseline; gap: 10px;
|
|
margin: 0 0 16px; padding-bottom: 6px; border-bottom: 2px solid #ddd;
|
|
}
|
|
.rubrique-titre h2 { margin: 0; font-size: 1.3rem; }
|
|
.rubrique-titre a, a.tout-voir { color: #3498db; text-decoration: none; font-weight: bold; font-size: 0.9rem; white-space: nowrap; }
|
|
a.tout-voir { display: block; margin-top: 14px; text-align: right; }
|
|
|
|
/* min() : sur un écran étroit, une colonne fixe déborderait. */
|
|
.grid { display: grid; gap: 24px; grid-template-columns: repeat(auto-fill, minmax(min(var(--carte, 400px), 100%), 1fr)); }
|
|
.compact { --carte: 220px; }
|
|
.card {
|
|
background: #fff; border-radius: 15px; overflow: hidden;
|
|
box-shadow: 0 10px 20px rgba(0,0,0,0.1);
|
|
transition: transform .2s, box-shadow .2s;
|
|
}
|
|
.card:hover { transform: translateY(-4px); box-shadow: 0 14px 28px rgba(0,0,0,0.15); }
|
|
/* Toute la carte est cliquable ; l'iframe ne capte pas les clics. */
|
|
.card > a { display: block; color: inherit; text-decoration: none; }
|
|
.map-container { width: 100%; height: 300px; border: none; pointer-events: none; display: block; }
|
|
.compact .map-container { height: 190px; }
|
|
.card-content { padding: 16px 20px 20px; text-align: center; }
|
|
.card h3 { text-transform: capitalize; margin: 0 0 4px; font-size: 1.2rem; }
|
|
.compact .card h3 { font-size: 1.05rem; }
|
|
.periode { color: #888; font-size: 0.85rem; }
|
|
.carte-externe { margin-top: 50px; scroll-margin-top: 20px; }
|
|
.carte-externe iframe {
|
|
display: block; width: 100%; height: min(600px, 75vh); border: none;
|
|
border-radius: 15px; box-shadow: 0 10px 20px rgba(0,0,0,0.1);
|
|
}
|
|
/* Bouton discret vers l'interface d'administration (site.toml, [administration]). */
|
|
a.connexion { position: absolute; top: 16px; right: 20px; font-size: 0.85rem; color: #777;
|
|
text-decoration: none; padding: 5px 12px; border: 1px solid #ccc; border-radius: 99px; }
|
|
a.connexion:hover { color: #3498db; border-color: #3498db; }
|
|
.vide { text-align: center; color: #777; margin-top: 60px; line-height: 1.7; }
|
|
code { background: #e8e8ef; padding: 2px 6px; border-radius: 4px; }
|
|
@media (prefers-color-scheme: dark) {
|
|
body { background: #16161a; color: #e8e8ea; }
|
|
.card { background: #232329; box-shadow: 0 10px 20px rgba(0,0,0,0.4); }
|
|
.sous-titre, .vide, .periode { color: #9a9aa2; }
|
|
.rubrique-titre { border-color: #333; }
|
|
code { background: #2e2e36; }
|
|
a.connexion { color: #9a9aa2; border-color: #444; }
|
|
}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
{% if administration %}<a class="connexion" href="{{ administration }}" rel="nofollow">Connexion</a>{% endif %}
|
|
<header>
|
|
<h1>{% block entete %}🌍 {{ titre_site }}{% endblock %}</h1>
|
|
<div class="sous-titre">{% block sous_titre %}{% endblock %}</div>
|
|
</header>
|
|
<main>
|
|
{% block contenu %}{% endblock %}
|
|
</main>
|
|
</body>
|
|
</html>
|
|
|
|
{% macro carte(v) -%}
|
|
<article class="card">
|
|
<a href="{{ v.chemin }}/index.html">
|
|
{# loading="lazy" : sinon chaque miniature charge une carte Leaflet complète dès l'ouverture #}
|
|
<iframe class="map-container" src="{{ v.chemin }}/mini.html" loading="lazy" title="Carte de {{ v.titre }}" tabindex="-1"></iframe>
|
|
<div class="card-content">
|
|
<h3>{{ v.titre }}</h3>
|
|
{% if v.periode %}<div class="periode">{{ v.periode }}</div>{% endif %}
|
|
</div>
|
|
</a>
|
|
</article>
|
|
{%- endmacro %}
|