/* ============================================================
   COMPOSANTS PARTAGÉS — définis UNE seule fois pour tout le site
   (portail ET homepage). Règles (arbitrage 11/08) :
   1. zéro CSS dans les templates (gardé par la CI) ;
   2. un composant = un seul fichier propriétaire — avant d'écrire une
      classe, grep son nom dans assets/ ;
   3. aucune valeur brute hors tokens (exceptions commentées sur place).
   Ordre de chargement (l'ordre EST l'architecture) :
   tokens → composants → entete-publique → portail (app) / home (homepage)
   ============================================================ */

/* ---------- Gabarit ---------- */
.wrap { max-width: 1200px; margin: 0 auto; padding: 0 24px; }

/* ---------- Liens ---------- */
/* Filet global : un lien sans style dédié prend l'accent de la charte
   (clair ET sombre), jamais le bleu par défaut du navigateur. Les règles
   plus spécifiques (nav, boutons, pieds de page…) gardent la main. */
a { color: var(--accent-ink); }

/* ---------- Boutons ---------- */
.btn {
  display: inline-flex; align-items: center; gap: 8px; text-decoration: none; font-weight: 700;
  border-radius: var(--radius-btn); padding: 12px 22px; border: none;
  font-size: var(--btn-text); text-transform: uppercase; letter-spacing: var(--btn-tracking);
  cursor: pointer; min-height: var(--touch-target); font-family: inherit;
  transition: background var(--dur-fast) var(--ease), border-color var(--dur-fast) var(--ease), transform var(--dur-fast) var(--ease), filter var(--dur-fast) var(--ease);
}
.btn:active { transform: translateY(1px) scale(0.985); }
.btn-primary { background: var(--ink); color: var(--bg); }
.btn-primary:hover { opacity: 0.86; }
.btn-ghost { background: var(--surface); color: var(--ink); border: 1.5px solid var(--line); }
.btn-ghost:hover { border-color: color-mix(in srgb, var(--ink-faint) 60%, var(--line)); background: var(--bg-soft); }
.btn-danger { background: transparent; color: var(--alert); border: 1.5px solid var(--alert); }
.btn-danger:hover { background: var(--alert-soft); }
.btn-small { padding: 7px 13px; font-size: 0.72rem; min-height: 34px; }
:root[data-theme="dark"] .btn-primary:hover { opacity: 0.88; }


/* Variantes SUR PHOTO (homepage) : constantes assumées hors tokens —
   posées sur une image sombre, elles ne suivent pas le thème. */
.btn-light { background: #ffffff; color: #1c1c1a; }
.btn-light:hover { background: #eceae6; }
.btn-onphoto { background: transparent; color: #ffffff; border: 1.5px solid rgb(255 255 255 / 0.75); }
.btn-onphoto:hover { border-color: #ffffff; background: rgb(255 255 255 / 0.1); }

/* ---------- Messages flash ---------- */
.flashes { margin-bottom: var(--space-5); display: grid; gap: 10px; }
.flash { border-radius: var(--radius-field); padding: 13px 16px; font-size: 0.95rem; font-weight: 500; border: 1px solid; }
.flash.success { background: var(--accent-soft); color: var(--accent-ink); border-color: color-mix(in srgb, var(--accent) 30%, transparent); }
.flash.warning { background: var(--alert-soft); color: var(--alert); border-color: color-mix(in srgb, var(--alert) 30%, transparent); }

/* ---------- Formulaires (conformes au book) ---------- */
.form-card {
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius-card);
  box-shadow: var(--shadow-card); padding: var(--space-6); max-width: 460px;
}
.form-card h1 { font-size: 1.45rem; margin-bottom: var(--space-5); }
.field { display: grid; gap: 8px; margin-bottom: var(--space-5); }
.field label { font-weight: 700; font-size: 0.95rem; }
.field .help { font-size: 0.85rem; color: var(--ink-faint); }
.field input {
  font-family: inherit; font-size: 1rem; color: var(--ink);
  background: var(--surface); border: 1.5px solid var(--line); border-radius: var(--radius-field);
  padding: 12px 14px; min-height: var(--touch-target); width: 100%;
  transition: border-color var(--dur-fast) var(--ease);
}
.field input:hover { border-color: color-mix(in srgb, var(--ink-faint) 60%, var(--line)); }
.field input:focus { outline: none; border-color: var(--accent); box-shadow: var(--focus-ring); }
.field.error input { border-color: var(--alert); }
.field .error-text { font-size: 0.85rem; color: var(--alert); font-weight: 700; }

/* Œil « afficher / masquer le mot de passe » : bouton icône DANS le champ,
   à droite (partials/oeil-mdp.html.twig + assets/mdp.js).
   Le bouton est « hidden » tant que mdp.js ne l'a pas révélé ; la réserve de
   place à droite du texte suit cette révélation (:has), pour que le champ
   reste un champ ordinaire sans JavaScript.
   L'icône affichée découle du seul aria-pressed : un état, pas deux. */
.champ-mdp { position: relative; display: grid; }
.champ-mdp:has(.mdp-oeil:not([hidden])) input { padding-right: 52px; }
.mdp-oeil {
  position: absolute; top: 0; right: 0; height: 100%;
  width: var(--touch-target); min-height: var(--touch-target);
  display: flex; align-items: center; justify-content: center;
  background: transparent; border: none; border-radius: var(--radius-field);
  color: var(--ink-faint); cursor: pointer;
  transition: color var(--dur-fast) var(--ease);
}
.mdp-oeil[hidden] { display: none; }
.mdp-oeil:hover { color: var(--ink); }
.mdp-oeil:focus-visible { outline: none; color: var(--ink); box-shadow: var(--focus-ring); }
.mdp-oeil svg { width: 20px; height: 20px; display: block; }
.mdp-oeil .oeil-barre { display: none; }
.mdp-oeil[aria-pressed="true"] .oeil-ouvert { display: none; }
.mdp-oeil[aria-pressed="true"] .oeil-barre { display: block; }

.form-actions { display: flex; align-items: center; gap: 16px; flex-wrap: wrap; }
/* Pages auth : le bouton conclut le formulaire À DROITE, les liens dessous
   (décision Aurélien 11/08) */
.auth .form-actions { justify-content: flex-end; }
.form-alt { margin-top: var(--space-4); font-size: 0.9rem; color: var(--ink-soft); }
.form-alt + .form-alt { margin-top: var(--space-2); }
.form-alt a, .form-link { font-weight: 700; } /* couleur : filet global des liens */

/* Pages d'authentification : carte centrée */
.auth main { display: grid; place-items: start center; padding-top: var(--space-8); }
.auth .form-card { width: min(460px, calc(100vw - 48px)); }

/* ---------- Bannière de consentement (mesure d'audience) ---------- */
.consent { position: fixed; inset-inline: 0; bottom: 0; z-index: 50; background: var(--surface); border-top: 1px solid var(--line); box-shadow: 0 -8px 30px color-mix(in srgb, var(--ink) 10%, transparent); padding: 14px 0; }
.consent .wrap { display: flex; gap: 16px; align-items: center; flex-wrap: wrap; justify-content: space-between; }
.consent p { margin: 0; font-size: 0.95rem; max-width: 62ch; }
.consent p a { color: var(--accent-ink); font-weight: 700; }
.consent .actions { display: flex; gap: 10px; }
.consent .actions .btn { min-height: 44px; }



/* Prénom + nom côte à côte sur les formulaires (empilés sur mobile) */
.champs-nom { display: grid; grid-template-columns: 1fr 1fr; gap: 0 16px; }
@media (max-width: 480px) { .champs-nom { grid-template-columns: 1fr; } }

/* Zone de texte des formulaires (même peau que les champs) */
.field textarea {
  font-family: inherit; font-size: 1rem; color: var(--ink); resize: vertical;
  background: var(--surface); border: 1.5px solid var(--line); border-radius: var(--radius-field);
  padding: 12px 14px; width: 100%; min-height: 120px;
  transition: border-color var(--dur-fast) var(--ease);
}
.field textarea:hover { border-color: color-mix(in srgb, var(--ink-faint) 60%, var(--line)); }
.field textarea:focus { outline: none; border-color: var(--accent); box-shadow: var(--focus-ring); }
.field.error textarea { border-color: var(--alert); }

/* Champ piège anti-robots : hors écran pour les humains, présent pour les robots */
.piege { position: absolute; left: -5000px; width: 1px; height: 1px; overflow: hidden; }

/* ---------- Interrupteur (réglages oui/non) ----------
   Deux emplois, une seule peau :
   1. <label class="interrupteur"><input type="checkbox">…  → un réglage
      qui part avec le formulaire ;
   2. <button class="interrupteur" role="switch" aria-checked="…">  → une
      action immédiate (le serveur bascule, la page revient). Sans
      JavaScript dans les deux cas.
   L'état se lit sur input:checked OU sur aria-checked : jamais sur une
   classe posée à la main. */
.interrupteur {
  display: flex; align-items: flex-start; gap: 14px; width: 100%;
  min-height: var(--touch-target); cursor: pointer; text-align: left;
  font: inherit; color: var(--ink); background: none; border: none; padding: 0;
}
.interrupteur input { position: absolute; opacity: 0; width: 1px; height: 1px; }
.interrupteur .piste {
  position: relative; flex: none; width: 46px; height: 28px; margin-top: 2px;
  border-radius: var(--radius-pill);
  background: color-mix(in srgb, var(--ink-faint) 45%, var(--line));
  transition: background var(--dur-med) var(--ease);
}
.interrupteur .piste::after {
  /* La pastille reste blanche dans les deux thèmes (constante assumée) :
     c'est elle qui donne la lecture « poussée à droite ». */
  content: ""; position: absolute; top: 3px; left: 3px; width: 22px; height: 22px;
  border-radius: 50%; background: #ffffff; box-shadow: 0 1px 3px rgb(0 0 0 / 0.25);
  transition: transform var(--dur-med) var(--ease);
}
.interrupteur input:checked + .piste,
.interrupteur[aria-checked="true"] .piste { background: var(--accent); }
.interrupteur input:checked + .piste::after,
.interrupteur[aria-checked="true"] .piste::after { transform: translateX(18px); }
.interrupteur:focus-visible { outline: none; }
.interrupteur input:focus-visible + .piste,
.interrupteur:focus-visible .piste { box-shadow: var(--focus-ring); }
/* « L'indicateur respire » : 14 px de gap + 10 px = les 24 px de la règle */
.interrupteur .txt { min-width: 0; margin-right: 10px; }
.interrupteur .txt strong { display: block; font-size: 1rem; font-weight: 700; }
.interrupteur .txt .help { display: block; font-size: 0.88rem; color: var(--ink-soft); margin-top: 3px; max-width: 62ch; }
.interrupteur .pill { margin-left: auto; margin-bottom: 0; flex: none; align-self: flex-start; margin-top: 4px; }
@media (max-width: 620px) { .interrupteur .pill { display: none; } }
@media (prefers-reduced-motion: reduce) {
  .interrupteur .piste, .interrupteur .piste::after { transition: none; }
}

/* ---------- Modale de confirmation (changements d'offre) ---------- */
dialog.modale {
  /* margin:auto : le reset global (margin:0) écrase le centrage natif du dialog */
  position: fixed; inset: 0; margin: auto; height: fit-content;
  border: none; border-radius: var(--radius-card); background: var(--surface); color: var(--ink);
  box-shadow: 0 18px 50px rgb(0 0 0 / 0.25); padding: 24px;
  width: min(440px, calc(100vw - 32px));
}
dialog.modale::backdrop { background: rgb(0 0 0 / 0.45); }
.modale h2 { font-size: 1.15rem; margin-bottom: 12px; }
.modale p { font-size: 0.95rem; color: var(--ink-soft); line-height: 1.55; margin-bottom: 10px; }
.modale p strong { color: var(--ink); }
.modale .modale-actions { display: flex; gap: 10px; justify-content: flex-end; margin-top: 18px; flex-wrap: wrap; }
@media (prefers-reduced-motion: no-preference) {
  dialog.modale[open] { animation: modale-arrivee 0.16s var(--ease); }
  @keyframes modale-arrivee { from { opacity: 0; transform: translateY(8px); } }
}
