/* ==========================================================================
   UCHIMO — composants partagés des pages app (inscription, abonnement, compte)
   Dépend de tokens.css (copie verbatim du design system, source de vérité).
   ========================================================================== */

@font-face {
  font-family: "Baloo 2";
  font-style: normal;
  font-weight: 400 800;
  font-display: swap;
  src: url("fonts/baloo2-latin.woff2") format("woff2");
}
@font-face {
  font-family: "Source Sans 3";
  font-style: normal;
  font-weight: 200 900;
  font-display: swap;
  src: url("fonts/sourcesans3-latin.woff2") format("woff2");
}
/* Fallbacks métriques anti-CLS — mêmes valeurs que index.html. tokens.css est
   une copie générée du design system (interdit d'y toucher) : on réinjecte les
   familles Fallback dans les stacks ici, après son chargement. */
@font-face {
  font-family: "Baloo 2 Fallback";
  src: local("Arial");
  ascent-override: 105%; descent-override: 52%; line-gap-override: 0%; size-adjust: 103%;
}
@font-face {
  font-family: "Source Sans 3 Fallback";
  src: local("Arial");
  ascent-override: 99%; descent-override: 27%; line-gap-override: 0%; size-adjust: 94%;
}
:root {
  --font-display: "Baloo 2", "Baloo 2 Fallback", ui-rounded, -apple-system, "Segoe UI", Roboto, sans-serif;
  --font-body: "Source Sans 3", "Source Sans 3 Fallback", "Source Sans Pro", -apple-system, "Segoe UI", Roboto, sans-serif;
}

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

/* `hidden` doit gagner sur tout `display` posé plus bas (une règle d'auteur,
   même de faible spécificité, écrase toujours la règle agent-utilisateur
   `[hidden] { display: none }`). Sans ce garde-fou, `.card` en display:block
   rendrait visibles les sections masquées de compte.html. */
[hidden] { display: none !important; }

body {
  font: var(--text-body);
  color: var(--text-primary);
  background: var(--bg-page); /* jamais de blanc pur en fond de page */
  min-height: 100dvh;
}

main.page {
  max-width: var(--container-form);
  margin-inline: auto;
  padding: var(--space-8) var(--space-6) var(--space-24);
}
main.page-wide { max-width: var(--container-app); }

/* ---- Header ------------------------------------------------------------- */
.site-header {
  position: sticky;
  top: 0;
  z-index: var(--z-header);
  background: var(--bg-page);
  border-bottom: var(--border-w-hairline) solid var(--border-subtle);
}
.site-header .inner {
  max-width: var(--container-app);
  margin-inline: auto;
  padding: var(--space-3) var(--space-6);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
}
.header-lockup { height: 36px; width: auto; display: block; }

/* Cibles tactiles du header (plancher 44 px du DS, WCAG 2.5.5).
   La cible RÉELLE du lien atteint 44 px de haut (min-height sur un
   inline-flex qui centre l'image dedans) — pas une zone étendue en
   pseudo-élément invisible aux outils de mesure/audit. L'image du logo
   (36 px) ne change pas de taille : seul le padding vertical du lien grandit.
   Couvre aussi bien le lockup que les liens texte du header (ex. « Connecte-toi »
   niché dans `.hint`), d'où un sélecteur descendant et non un enfant direct.
   `.btn` est exclu : il tient déjà --touch-target-comfort. */
.site-header a:not(.btn) {
  display: inline-flex;
  align-items: center;
  min-height: var(--touch-target-min);
}

/* ---- Boutons (pilule, TOUJOURS) ------------------------------------------ */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  min-height: var(--touch-target-comfort);
  padding: 12px var(--space-6);
  border: none;
  border-radius: var(--radius-full);
  font: var(--text-button);
  letter-spacing: 0.005em;
  cursor: pointer;
  text-decoration: none;
  transition: background var(--duration-fast) var(--ease-uchi-out),
              transform var(--duration-instant) var(--ease-uchi-out);
}
/* Un bouton neutralisé ne se survole ni ne s'enfonce : le curseur le dit. */
.btn:disabled { cursor: default; }
.btn:not(:disabled):active { transform: scale(var(--motion-scale-press)); }
.btn-primary { background: var(--interactive-primary); color: var(--text-on-brand); }
.btn-primary:not(:disabled):hover { background: var(--interactive-primary-hover); }
.btn-primary:focus-visible { outline-color: var(--focus-ring-on-brand); }
.btn-primary:disabled { background: var(--interactive-primary-disabled); }
.btn-hero { box-shadow: var(--shadow-brand); } /* max 1 par écran */
.btn-ghost {
  background: transparent;
  border: var(--border-w-strong) solid var(--border-default);
  color: var(--text-primary);
}
.btn-ghost:not(:disabled):hover { border-color: var(--ink-300); background: var(--bg-surface); }
.btn-ghost:disabled { border-color: var(--border-subtle); color: var(--text-disabled); }
.btn-danger {
  background: transparent;
  border: var(--border-w-strong) solid var(--error-500);
  color: var(--error-fg);
}
.btn-danger:not(:disabled):hover { background: var(--error-bg); }
/* Crème de marque, jamais de blanc pur. Fond invariant (--error-600 n'est pas
   redéfini en thème sombre), donc texte invariant : ni --text-on-brand (encre,
   réservé au corail : 1,82:1 ici) ni --text-inverse (il bascule en encre sous
   [data-theme=dark]). cream-100 sur error-600 = 5,59:1 · sur error-700 = 7,68:1. */
.btn-danger-solid { background: var(--error-600); color: var(--cream-100); border: none; }
.btn-danger-solid:not(:disabled):hover { background: var(--error-700); }
.btn-block { width: 100%; }

/* ---- Cartes --------------------------------------------------------------- */
.card {
  display: block; /* posée aussi sur des <span> (choix 2FA) : sans display, le
                     fond ne peut pas envelopper le contenu et la boîte inline
                     se fragmente. Voir le garde-fou [hidden] plus haut. */
  background: var(--bg-surface);
  border: var(--border-w-hairline) solid var(--border-subtle);
  border-radius: var(--radius-md);
  padding: var(--space-6);
  box-shadow: var(--shadow-1);
}

/* ---- Formulaires ----------------------------------------------------------- */
.field { display: block; margin-top: var(--space-5); }
.field > span {
  display: block;
  font: var(--text-h4);
  margin-bottom: var(--space-2);
}
.field input {
  width: 100%;
  min-height: var(--touch-target-comfort);
  padding: 10px var(--space-4);
  border: var(--border-w-input) solid var(--border-input);
  border-radius: var(--radius-sm);
  font: var(--text-body);
  color: var(--text-primary);
  background: var(--bg-surface);
}
.field input:hover { border-color: var(--ink-500); }
.hint { font: var(--text-body-sm); color: var(--text-secondary); margin-top: var(--space-1); }

/* ---- Messages d'état -------------------------------------------------------- */
.msg {
  margin-top: var(--space-4);
  padding: var(--space-3) var(--space-4);
  border-radius: var(--radius-sm);
  font: var(--text-body-sm);
}
.msg-error   { background: var(--error-bg);   color: var(--error-fg); }
.msg-success { background: var(--success-bg); color: var(--success-fg); }
/* Ambre : « à valider », « envoi réel activé ». L'urgence n'est jamais rouge. */
.msg-urgency { background: var(--urgency-bg); color: var(--urgency-fg); }
/* Contexte, promesse de transparence, rappel neutre. */
.msg-info    { background: var(--info-bg);    color: var(--info-fg); }
/* Une région role="alert" qui passe de display:none à visible dans la même
   frame que l'injection de son texte est annoncée de façon peu fiable. On la
   laisse donc dans l'arbre d'accessibilité et on annule seulement sa boîte. */
.msg:empty {
  margin-top: 0;
  padding: 0;
  border: 0;
  block-size: 0;
  overflow: hidden;
}

/* ---- Bulle Uchimo (la mascotte parle) ---------------------------------------- */
.uchi-says {
  display: flex;
  gap: var(--space-3);
  align-items: flex-start;
  margin-bottom: var(--space-6);
}
.uchi-says img { width: var(--icon-xl); height: var(--icon-xl); flex-shrink: 0; }
.uchi-says p {
  background: var(--bg-brand-subtle);
  border-radius: var(--radius-md);
  border-start-start-radius: var(--radius-xs);
  padding: var(--space-3) var(--space-4);
  font: var(--text-body);
}

/* ---- Liens de contenu ------------------------------------------------------ */
/* Le corps, l'en-tête et le pied de page portent la couleur de marque, jamais
   le bleu par défaut du navigateur — y compris les liens texte nichés dans le
   header (ex. « Connecte-toi »). Les `.btn` gardent leur propre habillage ;
   `.site-footer-marketing` (fond encre) garde le sien aussi, avec une couleur
   claire dédiée et une spécificité plus forte qui l'emporte ici. */
main a:not(.btn),
header a:not(.btn),
footer a:not(.btn) {
  color: var(--text-brand);
  text-underline-offset: 2px;
}
main a:not(.btn):hover,
header a:not(.btn):hover,
footer a:not(.btn):hover {
  color: var(--link-hover);
}

/* ---- Pied de page — variante « minimal » ------------------------------------
   Pages funnel/compte/légal (inscription, compte, connexion, legal, cgu,
   confidentialite, mentions-legales). Payload HTML identique sur ces 7 pages
   (copie conforme, cf. commentaire en tête de chaque `<footer>`) ; les 4 pages
   légales n'utilisent pas app.css et en gardent une copie locale documentée. */
.site-footer {
  max-width: var(--container-form);
  margin: 0 auto;
  padding: var(--space-6);
  border-top: var(--border-w-hairline) solid var(--border-subtle);
  font: var(--text-body-sm);
  color: var(--text-secondary);
}
.site-footer ul { list-style: none; display: flex; flex-wrap: wrap; gap: var(--space-2) var(--space-4); }
/* `min-width` en plus du `min-height` : un lien court comme « Accueil » tenait
   déjà le plancher en hauteur mais pas en largeur (42 px mesurés) — les deux
   dimensions comptent pour une cible tactile (WCAG 2.5.5). */
.site-footer li a { display: inline-flex; align-items: center; justify-content: center; min-height: var(--touch-target-min); min-width: var(--touch-target-min); }

/* ---- Pied de page — variante « marketing complet » ---------------------------
   Pages marketing (accueil, /villes, /villes/*, /abonnement). Classe distincte
   de `.site-footer` ci-dessus pour ne jamais entrer en collision avec elle.
   Payload HTML identique sur ces 11 pages (copie conforme) ; l'accueil
   n'utilise pas app.css et en garde une copie locale documentée. */
.site-footer-marketing { background: var(--ink-900); color: var(--cream-100); padding: 44px 0 28px; }
.site-footer-marketing .wrap { max-width: var(--container-app); margin-inline: auto; padding-inline: var(--space-6); }
.site-footer-marketing .footer-top {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-6);
}
.site-footer-marketing .footer-lockup { height: 30px; width: auto; }
.site-footer-marketing .footer-links { display: flex; flex-wrap: wrap; gap: var(--space-2); list-style: none; }
.site-footer-marketing .footer-links a {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding: 0 var(--space-3);
  color: var(--cream-200);
  text-decoration: none;
  border-radius: var(--radius-full);
}
.site-footer-marketing .footer-links a:hover { color: var(--cream-50); text-decoration: underline; }
.site-footer-marketing .footer-links a:focus-visible { outline-color: var(--cream-100); }
.site-footer-marketing .footer-cities { margin-top: var(--space-4); }
.site-footer-marketing .footer-cities-title {
  font-size: 14px;
  font-weight: 600;
  color: var(--cream-300, #d8cfc0);
  margin: 0 0 2px var(--space-3);
}
.site-footer-marketing .footer-bottom {
  margin-top: var(--space-6);
  padding-top: var(--space-5);
  border-top: 1px solid var(--ink-700);
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: var(--space-3);
  font: var(--text-body-sm);
  color: var(--ink-300);
}

/* ---- Accessibilité --------------------------------------------------------- */
/* Cible tactile élargie pour un lien court noyé dans une phrase (mailto,
   renvoi interne) : le texte garde la taille et la graisse de la prose
   autour, mais la zone de tap grandit par un padding vertical, compensé par
   une marge négative égale pour ne pas pousser le texte voisin ni casser
   l'interligne du paragraphe. Calibré sur une ligne body-sm (14px/1.45 ≈
   20px) : + 2 × --space-3 = 44px, le plancher DS (WCAG 2.5.5). Partagé entre
   compte.html et abonnement.html. */
.tap-target-inline {
  display: inline-block;
  padding-block: var(--space-3);
  margin-block: calc(-1 * var(--space-3));
}

/* Visible uniquement pour les lecteurs d'écran (libellés de contexte, résumés). */
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

@media (prefers-reduced-motion: reduce) {
  .btn { transition: none; }
  .btn:not(:disabled):active { transform: none; }
}
