/* Feuille de style unique du site.
 *
 * Contraintes de `spec-ui-site.md` §1, traitées ici :
 *  - aucune ressource externe : pas de @import, pas de police téléchargée. La
 *    pile système suffit et ne coûte pas un octet sur la 4G du chalet ;
 *  - thème clair/sombre automatique ET basculable, le choix explicite gagnant
 *    sur la préférence système dans les deux sens ;
 *  - couleurs sémantiques distinctes de l'accent, « veille » comprise ;
 *  - contraste AA (4,5:1) sur tout texte, dans les deux thèmes ;
 *  - cibles tactiles ≥ 44 px, focus clavier visible partout ;
 *  - mobile d'abord : tout doit tenir en portrait sur 360 px.
 */

/* ---------------------------------------------------------------- couleurs */

:root {
  --fond: #ffffff;
  --surface: #f4f6f8;
  --surface-appuyee: #e8ecf1;
  --bordure: #ccd3dc;
  --texte: #15181d;
  --texte-doux: #545c68;

  --accent: #0b5fa5;
  --accent-fond: #e4eef8;

  /* Sémantiques, volontairement éloignées de l'accent (spec-ui §1.4). */
  --ok: #1a6b3c;
  --ok-fond: #e2f2e8;
  --veille: #55349b;
  --veille-fond: #eee7fa;
  --avertissement: #8a4b00;
  --avertissement-fond: #fbeeda;
  --erreur: #b02418;
  --erreur-fond: #fbe7e5;

  --rayon: 10px;
  --espace: 16px;
  --largeur-max: 1080px;
}

@media (prefers-color-scheme: dark) {
  :root {
    --fond: #12151a;
    --surface: #1a1f26;
    --surface-appuyee: #232a33;
    --bordure: #333c47;
    --texte: #e7eaf0;
    --texte-doux: #a3abb8;

    --accent: #74b9ff;
    --accent-fond: #182634;

    --ok: #62cf8c;
    --ok-fond: #16271d;
    --veille: #b8a8ff;
    --veille-fond: #21203a;
    --avertissement: #f0b256;
    --avertissement-fond: #2b2113;
    --erreur: #ff9086;
    --erreur-fond: #2e1a18;
  }
}

/* La bascule explicite doit gagner sur la préférence système dans les DEUX
 * sens : d'où ces deux blocs, et non un seul « data-theme=sombre ». */
:root[data-theme="clair"] {
  --fond: #ffffff;
  --surface: #f4f6f8;
  --surface-appuyee: #e8ecf1;
  --bordure: #ccd3dc;
  --texte: #15181d;
  --texte-doux: #545c68;
  --accent: #0b5fa5;
  --accent-fond: #e4eef8;
  --ok: #1a6b3c;
  --ok-fond: #e2f2e8;
  --veille: #55349b;
  --veille-fond: #eee7fa;
  --avertissement: #8a4b00;
  --avertissement-fond: #fbeeda;
  --erreur: #b02418;
  --erreur-fond: #fbe7e5;
}

:root[data-theme="sombre"] {
  --fond: #12151a;
  --surface: #1a1f26;
  --surface-appuyee: #232a33;
  --bordure: #333c47;
  --texte: #e7eaf0;
  --texte-doux: #a3abb8;
  --accent: #74b9ff;
  --accent-fond: #182634;
  --ok: #62cf8c;
  --ok-fond: #16271d;
  --veille: #b8a8ff;
  --veille-fond: #21203a;
  --avertissement: #f0b256;
  --avertissement-fond: #2b2113;
  --erreur: #ff9086;
  --erreur-fond: #2e1a18;
}

/* ------------------------------------------------------------------- socle */

*, *::before, *::after { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  background: var(--fond);
  color: var(--texte);
  font: 400 16px/1.5 system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
}

h1, h2, h3 { line-height: 1.25; margin: 0 0 .5em; font-weight: 600; }
h1 { font-size: 1.4rem; }
h2 { font-size: 1.15rem; }
h3 { font-size: 1rem; }
p { margin: 0 0 .75em; }

a { color: var(--accent); }
a:hover { text-decoration-thickness: 2px; }

:focus-visible {
  outline: 3px solid var(--accent);
  outline-offset: 2px;
  border-radius: 4px;
}

.saut-au-contenu {
  position: absolute;
  left: -9999px;
  background: var(--fond);
  color: var(--texte);
  padding: 12px 16px;
  z-index: 10;
}
.saut-au-contenu:focus { left: 8px; top: 8px; }

.icone { flex: none; vertical-align: -.15em; }

.discret { color: var(--texte-doux); font-size: .875rem; }
.en-ligne { display: inline; }

/* ------------------------------------------------------------------ entête */

.entete {
  border-bottom: 1px solid var(--bordure);
  background: var(--surface);
  position: sticky;
  top: 0;
  z-index: 5;
}
.entete-interieur {
  max-width: var(--largeur-max);
  margin: 0 auto;
  padding: 8px var(--espace);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}
.marque {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-weight: 600;
  color: var(--texte);
  text-decoration: none;
  min-height: 44px;
}
.entete-actions { display: flex; align-items: center; gap: 4px; }

.contenu {
  max-width: var(--largeur-max);
  margin: 0 auto;
  padding: var(--espace);
}

.fil { margin-bottom: 12px; }
.fil a { display: inline-flex; align-items: center; gap: 4px; min-height: 44px; }

/* ---------------------------------------------------------------- contrôles */

.bouton, .bouton-icone {
  font: inherit;
  border-radius: var(--rayon);
  border: 1px solid var(--bordure);
  background: var(--fond);
  color: var(--texte);
  cursor: pointer;
  min-height: 44px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
}
.bouton { padding: 0 16px; }
.bouton-icone { min-width: 44px; padding: 0 10px; }
.bouton:hover, .bouton-icone:hover { background: var(--surface-appuyee); }
.bouton[disabled] { opacity: .55; cursor: not-allowed; }

.bouton.principal {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--fond);
  font-weight: 600;
}
.bouton.danger { border-color: var(--erreur); color: var(--erreur); }

label { display: block; font-weight: 600; margin-bottom: 4px; }

input, select, textarea {
  font: inherit;
  color: var(--texte);
  background: var(--fond);
  border: 1px solid var(--bordure);
  border-radius: var(--rayon);
  padding: 10px 12px;
  min-height: 44px;
  width: 100%;
}

.champ { margin-bottom: 14px; }
.champ .aide { color: var(--texte-doux); font-size: .875rem; margin: 4px 0 0; font-weight: 400; }

fieldset { border: 1px solid var(--bordure); border-radius: var(--rayon); padding: 12px; margin: 0 0 14px; }
legend { font-weight: 600; padding: 0 6px; }

.ligne-champs { display: grid; gap: 12px; }
@media (min-width: 640px) { .ligne-champs { grid-template-columns: 1fr 1fr; } }

/* ------------------------------------------------------------------ cartes */

.carte {
  background: var(--surface);
  border: 1px solid var(--bordure);
  border-radius: var(--rayon);
  padding: var(--espace);
  margin-bottom: var(--espace);
}
.carte h2 { display: flex; align-items: center; gap: 8px; }

.grille { display: grid; gap: 12px; }
@media (min-width: 560px) { .grille.deux { grid-template-columns: 1fr 1fr; } }
@media (min-width: 860px) { .grille.trois { grid-template-columns: repeat(3, 1fr); } }

/* ------------------------------------------------------------------- états */

.etat {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 4px 10px;
  border-radius: 999px;
  font-size: .875rem;
  font-weight: 600;
  border: 1px solid transparent;
}
/* Chaque état porte une icône ET un texte : jamais la couleur seule. */
.etat-ok { color: var(--ok); background: var(--ok-fond); border-color: var(--ok); }
.etat-veille { color: var(--veille); background: var(--veille-fond); border-color: var(--veille); }
.etat-avertissement { color: var(--avertissement); background: var(--avertissement-fond); border-color: var(--avertissement); }

.message { border-radius: var(--rayon); padding: 12px 14px; margin-bottom: var(--espace); border: 1px solid; }
.message-erreur { color: var(--erreur); background: var(--erreur-fond); border-color: var(--erreur); }
.message-ok { color: var(--ok); background: var(--ok-fond); border-color: var(--ok); }
.message-info { color: var(--texte); background: var(--surface-appuyee); border-color: var(--bordure); }

.bandeau-reseau {
  background: var(--avertissement-fond);
  color: var(--avertissement);
  border-bottom: 1px solid var(--avertissement);
  padding: 8px var(--espace);
  text-align: center;
  font-size: .875rem;
  font-weight: 600;
}

/* ------------------------------------------------------------------ tuiles */

.tuile {
  background: var(--fond);
  border: 1px solid var(--bordure);
  border-radius: var(--rayon);
  padding: 12px;
}
.tuile .intitule {
  display: flex;
  align-items: center;
  gap: 6px;
  color: var(--texte-doux);
  font-size: .8125rem;
  margin-bottom: 4px;
}
.tuile .valeur { font-size: 1.5rem; font-weight: 600; font-variant-numeric: tabular-nums; }
.tuile .unite { font-size: .9rem; font-weight: 400; color: var(--texte-doux); margin-left: 2px; }
.tuile .age { color: var(--texte-doux); font-size: .8125rem; }

/* Une valeur plus vieille qu'un intervalle est atténuée ET annoncée. */
.perimee { opacity: .55; }
.perimee .valeur { text-decoration: underline dotted; text-underline-offset: 4px; }

/* ----------------------------------------------------------------- listes */

.liste { list-style: none; margin: 0; padding: 0; }
.liste > li {
  border-top: 1px solid var(--bordure);
  padding: 12px 0;
  display: flex;
  flex-wrap: wrap;
  gap: 8px 12px;
  align-items: center;
  justify-content: space-between;
}
.liste > li:first-child { border-top: 0; }

.vide { color: var(--texte-doux); padding: 12px 0; }

.tableau-defilant { overflow-x: auto; }
table { border-collapse: collapse; width: 100%; }
th, td { text-align: left; padding: 10px 12px; border-bottom: 1px solid var(--bordure); }
th { font-size: .8125rem; color: var(--texte-doux); font-weight: 600; }
td.nombre { font-variant-numeric: tabular-nums; text-align: right; }

/* ------------------------------------------------------------------ divers */

.onglets { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: var(--espace); }
.onglets a {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-height: 44px;
  padding: 0 12px;
  border: 1px solid var(--bordure);
  border-radius: var(--rayon);
  color: var(--texte);
  text-decoration: none;
  background: var(--surface);
}
.onglets a[aria-current="page"] {
  background: var(--accent-fond);
  border-color: var(--accent);
  color: var(--accent);
  font-weight: 600;
}

.galerie { display: grid; gap: 12px; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); }
.galerie figure { margin: 0; }
.galerie img {
  width: 100%;
  height: auto;
  display: block;
  border-radius: var(--rayon);
  border: 1px solid var(--bordure);
  background: var(--surface-appuyee);
}
.galerie figcaption { font-size: .8125rem; color: var(--texte-doux); margin-top: 4px; }

.graphe { width: 100%; height: auto; display: block; }
.graphe .bande { fill: var(--accent); opacity: .22; }
.graphe .moyenne { fill: none; stroke: var(--accent); stroke-width: 2; }
.graphe .axe { stroke: var(--bordure); stroke-width: 1; }
.graphe .etiquette { fill: var(--texte-doux); font-size: 11px; }
.graphe .veille { fill: var(--veille); opacity: .14; }

/* Bilan d'énergie : deux courbes distinguées par la couleur ET par le trait,
 * jamais par la couleur seule. */
.graphe .courbe { fill: none; stroke-width: 2; }
.graphe .entree { stroke: var(--ok); }
.graphe .sortie { stroke: var(--avertissement); stroke-dasharray: 5 4; }
.graphe text.entree { fill: var(--ok); }
.graphe text.sortie { fill: var(--avertissement); }

/* ------------------------------------------------------------------ cartes */

.carte-osm .cadre-carte {
  position: relative;
  width: 100%;
  height: 320px;
  overflow: hidden;
  border: 1px solid var(--bordure);
  border-radius: var(--rayon);
  background: var(--surface-appuyee);
}
.carte-osm .tuiles img { position: absolute; width: 256px; height: 256px; }
.carte-osm .reperes { position: absolute; inset: 0; width: 100%; height: 100%; }
.carte-osm .trace { fill: none; stroke: var(--accent); stroke-width: 3; stroke-dasharray: 8 5; }
.carte-osm .repere circle {
  fill: var(--surface);
  stroke: var(--texte);
  stroke-width: 2;
}
.carte-osm .repere.actuel circle { fill: var(--erreur); stroke: var(--fond); stroke-width: 3; }
.carte-osm .attribution { font-size: .75rem; color: var(--texte-doux); margin: 4px 0 0; }
.carte-osm .commandes-carte { display: flex; gap: 6px; margin-top: 8px; }

/* Déplacement à la souris : le curseur doit annoncer que la carte se prend. */
.carte-osm .cadre-carte { cursor: grab; }
.carte-osm .cadre-carte.en-deplacement { cursor: grabbing; }
/* Pendant le geste, les tuiles ne doivent pas être attrapées comme des images. */
.carte-osm .cadre-carte img { user-select: none; -webkit-user-drag: none; }

/* --------------------------------------------------------- choix d'un lieu */

/* Ici seulement le doigt commande la carte : ailleurs, un glissement vertical
 * appartient au défilement de la page. */
.carte-choix .cadre-carte { touch-action: none; }
.carte-choix .repere.choisi path { fill: var(--accent); stroke: var(--fond); stroke-width: 2; }
.carte-choix .repere.choisi .oeil { fill: var(--fond); stroke: none; }
.carte-choix .repere.choisi { cursor: move; }

.recherche-lieu { display: flex; gap: 8px; margin-bottom: 8px; }
.recherche-lieu input { flex: 1 1 auto; }
.recherche-lieu .bouton { flex: 0 0 auto; }

.resultats-lieu {
  list-style: none;
  margin: 0 0 8px;
  padding: 6px;
  border: 1px solid var(--bordure);
  border-radius: var(--rayon);
  background: var(--fond);
  max-height: 200px;
  overflow: auto;
}
.resultats-lieu[hidden] { display: none; }
.resultats-lieu li { padding: 2px 0; }
.resultats-lieu .lien-bouton { text-align: left; display: block; width: 100%; }

/* Étiquette réservée aux lecteurs d'écran : le champ de recherche a déjà son
 * texte indicatif, mais un texte indicatif n'est pas une étiquette. */
.sr-seul {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* Le code QR garde son cartouche blanc dans les deux thèmes : des modules
 * clairs sur fond sombre ne sont pas lisibles par un lecteur. */
.cadre-qr {
  display: inline-block;
  background: #ffffff;
  padding: 10px;
  border-radius: var(--rayon);
  border: 1px solid var(--bordure);
  margin: 12px 0;
}
.cadre-qr .qr { display: block; }

.formulaire-etroit { max-width: 420px; margin: 0 auto; }

.pied-action { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 12px; }

/* ------------------------------------------------------------ page d'accueil
 *
 * La porte d'entrée : une seule chose à faire, se connecter. Tout le reste
 * s'efface — la marque au-dessus, la création de compte en une ligne dessous.
 */
.accueil { max-width: 400px; margin: 4vh auto 0; }
.accueil-marque { text-align: center; margin-bottom: 20px; }
.accueil-marque svg { color: var(--accent); }
.accueil-marque h1 { margin: 4px 0 2px; font-size: 1.75rem; letter-spacing: -.02em; }
.accueil-marque .discret { margin: 0; }
.carte-accueil { padding: 20px; }
.carte-accueil h2 { margin-top: 0; font-size: 1.1rem; }
.bouton.large { width: 100%; }
.accueil-bascule { text-align: center; color: var(--texte-doux); font-size: .9375rem; }

/* Un bouton qui a l'air d'un lien : l'action est une vraie action (elle ouvre
 * une fenêtre), mais elle ne doit pas rivaliser avec « Se connecter ». */
.lien-bouton {
  font: inherit;
  background: none;
  border: 0;
  padding: 4px;
  min-height: 44px;
  color: var(--accent);
  text-decoration: underline;
  cursor: pointer;
}

/* ----------------------------------------------------------------- modales
 *
 * `<dialog>` natif : la pile, le focus piégé et la touche Échap sont donnés
 * par le navigateur. Le seul soin à prendre est que la fenêtre reste lisible
 * sans script — elle est alors rendue dans le flux, d'où `position: static`.
 */
.modale {
  border: 1px solid var(--bordure);
  border-radius: var(--rayon);
  background: var(--surface);
  color: var(--texte);
  padding: 0;
  width: min(100%, 420px);
  max-height: 92vh;
  overflow: auto;
}
.modale::backdrop { background: rgba(0, 0, 0, .6); }
.modale-corps { padding: 20px; }
.modale-entete { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.modale-entete h2 { margin: 0 0 8px; font-size: 1.1rem; }
/* Sans script, la fenêtre reste ouverte dans le flux, sous le formulaire de
 * connexion : elle ne doit alors ni flotter ni recouvrir quoi que ce soit. */
html:not(.script) .modale { position: static; margin: 0 auto 24px; }

/* Barre des 24 heures — plages d'allumage.
 *
 * En HTML plutôt qu'en SVG : un « viewBox » de 1440 minutes déformerait les
 * poignées à l'échelle, et des <button> positionnés en pourcentage donnent le
 * focus clavier, le rôle « slider » et une zone tactile pleine hauteur sans
 * rien réécrire.
 *
 * La piste au repos, c'est la VEILLE ; les segments peints, l'allumage. On
 * lit donc directement « ce qui est rempli, la maison est là ».
 */
.ruban { margin: 4px 0 18px; }
.ruban-piste {
  position: relative;
  height: 48px;
  border: 1px solid var(--bordure);
  border-radius: var(--rayon);
  background: repeating-linear-gradient(
    45deg, var(--surface-appuyee), var(--surface-appuyee) 6px,
    var(--surface) 6px, var(--surface) 12px);
  touch-action: none;  /* le doigt fait glisser une poignée, il ne défile pas */
}
.ruban-segment {
  position: absolute;
  top: 0;
  bottom: 0;
  background: var(--accent-fond);
  border-top: 3px solid var(--accent);
  border-bottom: 3px solid var(--accent);
}
.ruban-poignee {
  position: absolute;
  top: -6px;
  bottom: -6px;
  /* Dessinée fine, mais large de 44 px au toucher : la cible ne se voit pas,
   * elle se manque. */
  width: 44px;
  margin-left: -22px;
  padding: 0;
  border: 0;
  background: none;
  cursor: ew-resize;
  touch-action: none;
}
.ruban-poignee::before {
  content: "";
  position: absolute;
  inset: 0 20px;
  border-radius: 3px;
  background: var(--accent);
  box-shadow: 0 0 0 2px var(--fond);
}
.ruban-poignee:focus-visible { outline: none; }
.ruban-poignee:focus-visible::before {
  inset: 0 16px;
  box-shadow: 0 0 0 3px var(--fond), 0 0 0 6px var(--accent);
}
.ruban-graduations {
  position: relative;
  height: 1.2em;
  margin-top: 4px;
  font-size: .75rem;
  color: var(--texte-doux);
}
.ruban-graduations span { position: absolute; transform: translateX(-50%); }
.ruban-graduations span:first-child { transform: none; }

/* Galerie : vignettes de hauteur égale, pour une grille qui ne fait pas de
 * marches d'escalier quand les photos n'ont pas toutes le même format. */
.galerie figure { margin: 0; }
.galerie a {
  display: block;
  position: relative;
  border-radius: var(--rayon);
  overflow: hidden;
  border: 1px solid var(--bordure);
  background: var(--surface-appuyee);
}
.galerie a::after {
  /* Repère d'agrandissement : la vignette ne se télécharge pas, elle s'ouvre. */
  content: "⤢";
  position: absolute;
  right: 6px;
  bottom: 6px;
  padding: 2px 6px;
  border-radius: 6px;
  font-size: .9rem;
  color: #ffffff;
  background: rgba(0, 0, 0, .55);
  opacity: 0;
  transition: opacity .15s;
}
.galerie a:hover::after, .galerie a:focus-visible::after { opacity: 1; }
.galerie img {
  width: 100%;
  aspect-ratio: 4 / 3;
  object-fit: cover;
  height: auto;
  display: block;
  border: 0;
  border-radius: 0;
  transition: transform .2s;
}
.galerie a:hover img { transform: scale(1.03); }

/* Une photo qui vient d'arriver se signale, sinon elle se glisse en tête sans
 * qu'on remarque que quelque chose a bougé. */
@keyframes galerie-arrivee {
  from { opacity: 0; transform: translateY(-8px); }
  to { opacity: 1; transform: none; }
}
.galerie figure.nouvelle { animation: galerie-arrivee .4s ease-out; }
@media (prefers-reduced-motion: reduce) {
  .galerie figure.nouvelle { animation: none; }
  .galerie a:hover img { transform: none; }
}

/* Visionneuse plein écran. */
.visionneuse {
  position: fixed;
  inset: 0;
  z-index: 50;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 16px;
  background: rgba(0, 0, 0, .88);
}
.visionneuse[hidden] { display: none; }
body.visionneuse-ouverte { overflow: hidden; }
.visionneuse figure { margin: 0; max-width: 100%; max-height: 100%; }
.visionneuse img {
  max-width: 100%;
  /* Place gardée pour la légende et les boutons du bas. */
  max-height: calc(100vh - 120px);
  object-fit: contain;
  display: block;
  margin: 0 auto;
  border-radius: var(--rayon);
}
.visionneuse figcaption {
  color: #ffffff;
  text-align: center;
  margin-top: 8px;
  font-size: .875rem;
}
.visionneuse .bouton {
  position: absolute;
  min-width: 44px;
  min-height: 44px;
  color: #ffffff;
  background: rgba(255, 255, 255, .15);
  border-color: rgba(255, 255, 255, .35);
}
.visionneuse [data-visionneuse="fermer"] { top: 12px; right: 12px; }
.visionneuse [data-visionneuse="-1"] { left: 12px; top: 50%; transform: translateY(-50%); }
.visionneuse [data-visionneuse="1"] { right: 12px; top: 50%; transform: translateY(-50%); }

/* Réglage des films permanents : replié par défaut, il n'encombre pas la page
 * de quelqu'un qui vient juste regarder ses photos. */
.reglage-films { margin: 12px 0; }
.reglage-films summary {
  /* `list-item` par défaut : le triangle casserait l'alignement du bouton. */
  display: inline-flex;
  width: auto;
}
.reglage-films summary::-webkit-details-marker { display: none; }
.reglage-films[open] summary { margin-bottom: 12px; }
