Files
jerome 486d395e6b Initial commit — site configs
- vault.hidrago.click: Vaultwarden (password manager)
- git.hidrago.click: Gitea (git service)
- All static sites (suma, weather, combien-jour, tokyo-trip, etc.)
- Nginx configs for all subdomains
- Systemd user service for Vaultwarden
2026-07-31 11:38:43 +01:00

246 lines
13 KiB
HTML

<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Météo — Chambourcy · Kuwana · Tokyo</title>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
min-height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
padding: 2rem 1rem;
}
.lang-switch {
display: flex;
gap: 0.5rem;
margin-bottom: 1.5rem;
}
.lang-btn {
padding: 0.4rem 1rem;
border: 2px solid rgba(255,255,255,0.4);
background: rgba(255,255,255,0.15);
color: #fff;
border-radius: 8px;
cursor: pointer;
font-size: 0.9rem;
font-weight: 600;
transition: all 0.2s;
}
.lang-btn:hover { background: rgba(255,255,255,0.3); }
.lang-btn.active {
background: #fff;
color: #764ba2;
border-color: #fff;
}
h1 {
color: #fff;
font-size: 2rem;
margin-bottom: 0.3rem;
text-shadow: 0 2px 4px rgba(0,0,0,0.2);
}
.subtitle {
color: rgba(255,255,255,0.8);
font-size: 0.9rem;
margin-bottom: 2rem;
}
.container {
display: flex;
flex-wrap: wrap;
gap: 1.5rem;
justify-content: center;
max-width: 1100px;
width: 100%;
}
.card {
background: rgba(255,255,255,0.95);
border-radius: 20px;
padding: 2rem;
width: 320px;
box-shadow: 0 8px 32px rgba(0,0,0,0.15);
backdrop-filter: blur(10px);
transition: transform 0.2s;
}
.card:hover { transform: translateY(-4px); }
.card.error { border: 2px solid #e74c3c; }
.card-header {
display: flex;
justify-content: space-between;
align-items: baseline;
margin-bottom: 1rem;
}
.card-header h2 { font-size: 1.4rem; color: #333; }
.country { font-size: 0.8rem; color: #999; }
.temp-main {
font-size: 3.5rem;
font-weight: 700;
color: #333;
text-align: center;
margin: 0.5rem 0;
}
.desc {
text-align: center;
color: #666;
font-size: 1.1rem;
margin-bottom: 1.5rem;
}
.details {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 0.75rem;
}
.detail-item {
display: flex;
flex-direction: column;
background: rgba(0,0,0,0.03);
border-radius: 10px;
padding: 0.6rem 0.8rem;
}
.label { font-size: 0.75rem; color: #999; }
.value { font-size: 1rem; color: #333; font-weight: 600; }
footer {
margin-top: 2rem;
color: rgba(255,255,255,0.6);
font-size: 0.8rem;
text-align: center;
}
footer a { color: rgba(255,255,255,0.8); }
</style>
</head>
<body>
<div class="lang-switch">
<button class="lang-btn active" data-lang="fr">FR</button>
<button class="lang-btn" data-lang="en">EN</button>
<button class="lang-btn" data-lang="ja">日本語</button>
</div>
<h1 id="heading">🌤️ Météo du jour</h1>
<p class="subtitle" id="subtitle">Chambourcy · Kuwana · Tokyo</p>
<div class="container">
<div class="card">
<div class="card-header">
<h2><span class="wmo-emoji" data-code="3"></span> Chambourcy</h2>
<span class="country" data-city="Chambourcy"></span>
</div>
<div class="temp-main">17.2°C</div>
<div class="desc" data-wmo="3"></div>
<div class="details">
<div class="detail-item"><span class="label" data-i18n="feels">Ressenti</span><span class="value">18.0°C</span></div>
<div class="detail-item"><span class="label" data-i18n="humidity">Humidité</span><span class="value">86%</span></div>
<div class="detail-item"><span class="label" data-i18n="wind">Vent</span><span class="value">5.4 km/h</span></div>
<div class="detail-item"><span class="label" data-i18n="maxmin">Max / Min</span><span class="value">28.3° / 17.2°</span></div>
<div class="detail-item"><span class="label" data-i18n="precip">Précip.</span><span class="value">0.0 mm</span></div>
<div class="detail-item"><span class="label" data-i18n="sunrise">Lever</span><span class="value">2026-07-31T06:23</span></div>
<div class="detail-item"><span class="label" data-i18n="sunset">Coucher</span><span class="value">2026-07-31T21:32</span></div>
</div>
</div>
<div class="card">
<div class="card-header">
<h2><span class="wmo-emoji" data-code="3"></span> Kuwana</h2>
<span class="country" data-city="Kuwana"></span>
</div>
<div class="temp-main">35.3°C</div>
<div class="desc" data-wmo="3"></div>
<div class="details">
<div class="detail-item"><span class="label" data-i18n="feels">Ressenti</span><span class="value">41.8°C</span></div>
<div class="detail-item"><span class="label" data-i18n="humidity">Humidité</span><span class="value">56%</span></div>
<div class="detail-item"><span class="label" data-i18n="wind">Vent</span><span class="value">9.5 km/h</span></div>
<div class="detail-item"><span class="label" data-i18n="maxmin">Max / Min</span><span class="value">35.3° / 26.5°</span></div>
<div class="detail-item"><span class="label" data-i18n="precip">Précip.</span><span class="value">0.0 mm</span></div>
<div class="detail-item"><span class="label" data-i18n="sunrise">Lever</span><span class="value">2026-07-31T05:01</span></div>
<div class="detail-item"><span class="label" data-i18n="sunset">Coucher</span><span class="value">2026-07-31T18:57</span></div>
</div>
</div>
<div class="card">
<div class="card-header">
<h2><span class="wmo-emoji" data-code="1"></span> Tokyo</h2>
<span class="country" data-city="Tokyo"></span>
</div>
<div class="temp-main">32.4°C</div>
<div class="desc" data-wmo="1"></div>
<div class="details">
<div class="detail-item"><span class="label" data-i18n="feels">Ressenti</span><span class="value">37.8°C</span></div>
<div class="detail-item"><span class="label" data-i18n="humidity">Humidité</span><span class="value">58%</span></div>
<div class="detail-item"><span class="label" data-i18n="wind">Vent</span><span class="value">1.4 km/h</span></div>
<div class="detail-item"><span class="label" data-i18n="maxmin">Max / Min</span><span class="value">32.7° / 24.5°</span></div>
<div class="detail-item"><span class="label" data-i18n="precip">Précip.</span><span class="value">0.0 mm</span></div>
<div class="detail-item"><span class="label" data-i18n="sunrise">Lever</span><span class="value">2026-07-31T04:48</span></div>
<div class="detail-item"><span class="label" data-i18n="sunset">Coucher</span><span class="value">2026-07-31T18:47</span></div>
</div>
</div>
</div>
<footer>
<span data-i18n="data_source">Données</span>: <a href="https://open-meteo.com/">Open-Meteo</a> · <span data-i18n="updated">Mis à jour le</span> 31/07/2026 à 05:00 UTC
</footer>
<script>
const I18N = {"fr": {"title": "Météo — Chambourcy · Kuwana · Tokyo", "heading": "🌤️ Météo du jour", "subtitle": "Chambourcy · Kuwana · Tokyo", "feels": "Ressenti", "humidity": "Humidité", "wind": "Vent", "maxmin": "Max / Min", "precip": "Précip.", "sunrise": "Lever", "sunset": "Coucher", "data_source": "Données", "updated": "Mis à jour le", "error": "Erreur", "unknown": "Inconnu"}, "en": {"title": "Weather — Chambourcy · Kuwana · Tokyo", "heading": "🌤️ Today's Weather", "subtitle": "Chambourcy · Kuwana · Tokyo", "feels": "Feels like", "humidity": "Humidity", "wind": "Wind", "maxmin": "High / Low", "precip": "Rain", "sunrise": "Sunrise", "sunset": "Sunset", "data_source": "Data", "updated": "Updated on", "error": "Error", "unknown": "Unknown"}, "ja": {"title": "天気 — Chambourcy · Kuwana · Tokyo", "heading": "🌤️ 今日の天気", "subtitle": "Chambourcy · Kuwana · Tokyo", "feels": "体感温度", "humidity": "湿度", "wind": "風速", "maxmin": "最高 / 最低", "precip": "降水量", "sunrise": "日の出", "sunset": "日の入り", "data_source": "データ元", "updated": "更新日時", "error": "エラー", "unknown": "不明"}};
const COUNTRIES = {"Chambourcy": {"fr": "France", "en": "France", "ja": "フランス"}, "Kuwana": {"fr": "Japon", "en": "Japan", "ja": "日本"}, "Tokyo": {"fr": "Japon", "en": "Japan", "ja": "日本"}};
const WMO = {"0": {"fr": "Ciel dégagé", "en": "Clear sky", "ja": "快晴", "emoji": "☀️"}, "1": {"fr": "Peu nuageux", "en": "Mainly clear", "ja": "概ね晴れ", "emoji": "🌤️"}, "2": {"fr": "Partiellement nuageux", "en": "Partly cloudy", "ja": "所により曇り", "emoji": "⛅"}, "3": {"fr": "Couvert", "en": "Overcast", "ja": "曇り", "emoji": "☁️"}, "45": {"fr": "Brouillard", "en": "Fog", "ja": "霧", "emoji": "🌫️"}, "48": {"fr": "Brouillard givrant", "en": "Rime fog", "ja": "着氷霧", "emoji": "🌫️"}, "51": {"fr": "Bruine légère", "en": "Light drizzle", "ja": "軽い霧雨", "emoji": "🌦️"}, "53": {"fr": "Bruine modérée", "en": "Moderate drizzle", "ja": "霧雨", "emoji": "🌦️"}, "55": {"fr": "Bruine dense", "en": "Dense drizzle", "ja": "濃い霧雨", "emoji": "🌧️"}, "56": {"fr": "Bruine verglaçante", "en": "Freezing drizzle", "ja": "着氷霧雨", "emoji": "🌧️"}, "57": {"fr": "Bruine verglaçante dense", "en": "Dense freezing drizzle", "ja": "濃い着氷霧雨", "emoji": "🌧️"}, "61": {"fr": "Pluie légère", "en": "Slight rain", "ja": "小雨", "emoji": "🌧️"}, "63": {"fr": "Pluie modérée", "en": "Moderate rain", "ja": "雨", "emoji": "🌧️"}, "65": {"fr": "Pluie forte", "en": "Heavy rain", "ja": "大雨", "emoji": "🌧️"}, "66": {"fr": "Pluie verglaçante", "en": "Freezing rain", "ja": "着氷雨", "emoji": "🌧️"}, "67": {"fr": "Pluie verglaçante forte", "en": "Heavy freezing rain", "ja": "着氷大雨", "emoji": "🌧️"}, "71": {"fr": "Neige légère", "en": "Slight snow", "ja": "小雪", "emoji": "🌨️"}, "73": {"fr": "Neige modérée", "en": "Moderate snow", "ja": "雪", "emoji": "🌨️"}, "75": {"fr": "Neige forte", "en": "Heavy snow", "ja": "大雪", "emoji": "❄️"}, "77": {"fr": "Grains de neige", "en": "Snow grains", "ja": "細かい雪", "emoji": "🌨️"}, "80": {"fr": "Averses légères", "en": "Light showers", "ja": "軽いにわか雨", "emoji": "🌦️"}, "81": {"fr": "Averses modérées", "en": "Moderate showers", "ja": "にわか雨", "emoji": "🌧️"}, "82": {"fr": "Averses violentes", "en": "Violent showers", "ja": "激しいにわか雨", "emoji": "⛈️"}, "85": {"fr": "Averses de neige légères", "en": "Light snow showers", "ja": "軽いにわか雪", "emoji": "🌨️"}, "86": {"fr": "Averses de neige fortes", "en": "Heavy snow showers", "ja": "激しいにわか雪", "emoji": "❄️"}, "95": {"fr": "Orage", "en": "Thunderstorm", "ja": "雷雨", "emoji": "⛈️"}, "96": {"fr": "Orage grêle léger", "en": "Thunderstorm slight hail", "ja": "雷雨・小さな雹", "emoji": "⛈️"}, "99": {"fr": "Orage grêle fort", "en": "Thunderstorm heavy hail", "ja": "雷雨・大きな雹", "emoji": "⛈️"}};
let currentLang = 'fr';
function applyLang(lang) {
currentLang = lang;
const t = I18N[lang];
document.title = t.title;
document.getElementById('heading').textContent = t.heading;
document.getElementById('subtitle').textContent = t.subtitle;
// Labels
document.querySelectorAll('[data-i18n]').forEach(el => {
const key = el.getAttribute('data-i18n');
if (t[key]) el.textContent = t[key];
});
// Country names
document.querySelectorAll('[data-city]').forEach(el => {
const city = el.getAttribute('data-city');
if (COUNTRIES[city]) el.textContent = COUNTRIES[city][lang];
});
// Weather descriptions + emojis
document.querySelectorAll('[data-wmo]').forEach(el => {
const code = parseInt(el.getAttribute('data-wmo'));
const w = WMO[code];
if (w) el.textContent = w[lang];
});
document.querySelectorAll('.wmo-emoji').forEach(el => {
const code = parseInt(el.getAttribute('data-code'));
const w = WMO[code];
if (w) el.textContent = w.emoji;
});
// Update active button
document.querySelectorAll('.lang-btn').forEach(btn => {
btn.classList.toggle('active', btn.getAttribute('data-lang') === lang);
});
// Update <html lang>
document.documentElement.lang = lang;
}
document.querySelectorAll('.lang-btn').forEach(btn => {
btn.addEventListener('click', () => applyLang(btn.getAttribute('data-lang')));
});
// Auto-detect from browser or saved preference
const saved = localStorage.getItem('weather-lang');
if (saved && I18N[saved]) {
applyLang(saved);
} else {
const browserLang = navigator.language.slice(0, 2);
if (I18N[browserLang]) applyLang(browserLang);
}
// Save preference on change
document.querySelectorAll('.lang-btn').forEach(btn => {
btn.addEventListener('click', () => localStorage.setItem('weather-lang', btn.getAttribute('data-lang')));
});
</script>
</body>
</html>