<body>
<!--
En-tête éditorial de la page.
Il pose le contexte pédagogique de l’exemple.
-->
<header class="site-header">
<p class="site-kicker">Puce & Média · Vanilla web</p>

<h1>Mini météo en JavaScript natif</h1>

<p class="site-intro">
Une petite interface pour comprendre le trajet :
formulaire, événement, requête HTTP, API, JSON, DOM et erreurs.
v1
</p>
</header>

<!--
Contenu principal de la page.
L’application météo tient volontairement dans une seule section.
-->
<main class="site-main">
<!--
La section représente la carte météo.
aria-labelledby relie la section à son titre visible.
-->
<section class="weather-card" aria-labelledby="weather-title">
<h2 id="weather-title">Rechercher la météo d’une ville</h2>

<!--
Le formulaire est le point d’entrée de l’application.
novalidate désactive la validation native du navigateur afin de montrer
une gestion d’erreur contrôlée en JavaScript.
-->
<form class="weather-form" id="weather-form" novalidate>
<div class="form-field">
<!--
Le label est associé au champ par for/id.
Cela améliore l’accessibilité et agrandit la zone cliquable.
-->
<label for="city-input">Nom de la ville</label>

<input
type="text"
id="city-input"
name="city"
placeholder="Exemple : Paris"
autocomplete="address-level2"
>
</div>

<!--
Le bouton submit déclenche naturellement l’événement submit du formulaire.
JavaScript interceptera ensuite cet événement.
-->
<button type="submit" id="search-button">Rechercher</button>
</form>

<!--
Zone de message dynamique.
role="status" et aria-live="polite" permettent d’annoncer les changements
aux technologies d’assistance sans interrompre brutalement l’utilisateur.
-->
<p class="message" id="message" role="status" aria-live="polite">
Saisissez une ville pour afficher la météo actuelle.
</p>

<!--
Zone de résultat.
L’attribut hidden masque le bloc tant qu’aucune météo n’a été chargée.
JavaScript le rendra visible au moment opportun.
-->
<article class="weather-result" id="weather-result" hidden>
<!--
Résumé principal : nom de la ville, description et température.
Cette zone donne l’information météo la plus importante en premier.
-->
<div class="weather-summary">
<div>
<h3 id="result-city"></h3>
<p class="weather-description" id="result-description"></p>
</div>

<p class="weather-temperature" id="result-temperature"></p>
</div>

<!--
Liste de définition.
Elle convient bien à une série de couples libellé / valeur :
Ressenti → 18 °C, Humidité → 72 %, etc.
-->
<dl class="weather-data">
<div>
<dt>Ressenti</dt>
<dd id="result-apparent-temperature"></dd>
</div>

<div>
<dt>Humidité</dt>
<dd id="result-humidity"></dd>
</div>

<div>
<dt>Vent</dt>
<dd id="result-wind"></dd>
</div>

<div>
<dt>Rafales</dt>
<dd id="result-gusts"></dd>
</div>

<div>
<dt>Pression</dt>
<dd id="result-pressure"></dd>
</div>

<div>
<dt>Nuages</dt>
<dd id="result-clouds"></dd>
</div>

<div>
<dt>Précipitations</dt>
<dd id="result-precipitation"></dd>
</div>

<div>
<dt>Jour / nuit</dt>
<dd id="result-day"></dd>
</div>

<div>
<dt>Mesure</dt>
<dd id="result-time"></dd>
</div>
</dl>
</article>
</section>
</main>

<!--
Pied de page minimal.
Il crédite la source des données sans alourdir l’interface.
-->
<footer class="site-footer">
<p>Données météo fournies par Open-Meteo.</p>
</footer>

<!--
Le script est chargé en fin de body.
À ce stade, le HTML est déjà présent dans le DOM.
-->
<script src="app-01.js"></script>
</body>