/* ============================================================
   Socle et composants communs — charte v1.0.
   Repris à l'identique du prototype contractuel
   specs/membre_phase1.html.
   ============================================================ */
*{box-sizing:border-box} html,body{height:100%}
body{margin:0;background:var(--bg);color:var(--ink);font-family:var(--font);font-size:16px;line-height:1.5;-webkit-font-smoothing:antialiased}
button{font-family:inherit}
:focus-visible{outline:2px solid var(--accent);outline-offset:2px;border-radius:8px}
::selection{background:var(--accent-soft)}
a{color:inherit}

.btn{display:inline-flex;align-items:center;justify-content:center;gap:8px;height:48px;padding:0 20px;border-radius:var(--r-ctl);border:1px solid transparent;font-size:16px;font-weight:600;cursor:pointer;white-space:nowrap;transition:transform var(--dur) var(--ease-out),background var(--dur),box-shadow var(--dur),opacity var(--dur)}
.btn:active{transform:scale(.98)}
.btn--primary{background:var(--accent);color:var(--on-accent)}
.btn--primary:hover{background:var(--accent-hover)}
.btn--secondary{background:var(--n2);color:var(--ink);border-color:var(--line)}
.btn--secondary:hover{background:var(--n3)}
/* Le prototype porte .btn--tertiary sans .btn : les propriétés de remise à
   plat du bouton natif sont donc reprises ici plutôt qu'héritées de .btn. */
.btn--tertiary{background:transparent;color:var(--accent-ink);height:auto;padding:8px 4px;border:none;cursor:pointer;font-family:inherit;font-size:14px;font-weight:600}
.btn--block{width:100%}
/* Une action de navigation reste un lien : porté par un <a>, .btn doit
   neutraliser le soulignement pour un rendu identique au prototype. */
a.btn{text-decoration:none}
.btn[disabled]{opacity:.4;cursor:not-allowed}
.btn .spin{width:18px;height:18px;border:2px solid rgba(255,255,255,.5);border-top-color:#fff;border-radius:50%;animation:spin .7s linear infinite;display:none}
.btn.is-loading .spin{display:inline-block}
@keyframes spin{to{transform:rotate(360deg)}}

.field{margin-bottom:16px}
.field label{display:block;font-size:14px;font-weight:500;margin-bottom:8px}
.control{position:relative}
.control input{width:100%;height:48px;padding:0 16px;border-radius:var(--r-ctl);border:1px solid var(--line);background:#fff;color:var(--ink);font-size:16px;transition:border-color var(--dur),box-shadow var(--dur)}
.control input:focus{outline:none;border-color:var(--accent);box-shadow:0 0 0 2px var(--surface), 0 0 0 4px var(--accent)}
.control .reveal{position:absolute;right:6px;top:50%;transform:translateY(-50%);background:none;border:none;color:var(--muted);font-size:14px;font-weight:500;cursor:pointer;padding:8px}
.field.has-error input{border-color:var(--err);box-shadow:0 0 0 2px var(--surface), 0 0 0 4px var(--err)}
.field .err{display:none;font-size:14px;color:var(--err);margin-top:8px}
.field.has-error .err{display:block}

.enter{opacity:0;transform:translateY(10px);animation:enter var(--dur-in) var(--ease-out) forwards}
@keyframes enter{to{opacity:1;transform:none}}

.toast-wrap{position:fixed;left:0;right:0;bottom:24px;display:flex;justify-content:center;z-index:80;pointer-events:none;flex-direction:column;gap:8px;align-items:center}
@media(max-width:900px){.toast-wrap{bottom:84px}}
.toast{background:var(--ink);color:#fff;padding:12px 16px;border-radius:var(--r-ctl);font-size:14px;font-weight:500;box-shadow:var(--shadow-2);display:flex;align-items:center;gap:12px;opacity:0;transform:translateY(12px);transition:opacity var(--dur) var(--ease-out),transform var(--dur) var(--ease-out);max-width:90vw}
.toast.show{opacity:1;transform:none}
/* Confirmation d'une operation reussie : fond vert plutot que l'encre neutre.
   La couleur porte le sens avant la lecture. Definie ici, avec le composant
   lui-meme, elle vaut pour les deux espaces — connexion et back-office. */
.toast.ok{background:var(--ok);color:#fff}
/* Refus d'une operation : fond rouge, meme logique que la variante verte. Le
   trace de l'icone suit le type (croix plutot que coche) — la couleur seule
   ne se lit pas de tous. */
.toast.err{background:var(--err);color:#fff}
.toast.warn{background:var(--warn);color:#fff}
.toast svg{width:16px;height:16px;color:#fff;flex:none}

.prod-foot{margin-top:48px;padding:16px 0 8px;text-align:center;font-size:12px;color:var(--muted)}
.prod-foot--fix{left:0;right:0;bottom:10px;margin:0;padding:0;z-index:5}
/* Élément présent dans le DOM mais sans rendu : support des messages flash
   rejoués en toast. */
.is-hidden{display:none}
/* Champ piège des formulaires publics (voir App\Security\Honeypot).
   Retiré du flux sans être `display:none` ni `type=hidden` : les robots
   savent ignorer ces deux-là, alors qu'un champ posé hors écran leur
   paraît ordinaire. Le déplacement plutôt que le masquage laisse aussi le
   navigateur le traiter comme un champ vivant, ce qui est le but. */
.hp{position:absolute;left:-9999px;top:auto;width:1px;height:1px;overflow:hidden}
.footlink{background:none;border:none;padding:0;font-family:inherit;font-size:12px;color:var(--muted);text-decoration:underline;cursor:pointer}
.footlink:hover{color:var(--ink)}

/* ============================================================
   PAGES D'ERREUR
   Servies par TwigBundle en production, hors de tout espace : elles
   reprennent `.center-canvas` et `.auth-card` des ecrans de connexion,
   dont elles partagent la situation — une page seule, sans navigation
   autour. Ces deux classes vivent dans auth.css, chargee sur toutes les
   pages comme les autres feuilles (voir assets/app.js).

   Ce qui suit ne concerne que les pages d'erreur et reste donc ici, dans
   le socle : une erreur survient n'importe ou, y compris avant qu'un
   espace ne soit resolu.
   ============================================================ */
.errpage{text-align:center}

/* Le code en grand, mais en gris : c'est un reperage, pas le message.
   L'ecrire en couleur d'accent le ferait lire comme une alerte, quand un
   404 n'en est pas une. La graisse et la taille suffisent a le poser. */
.errpage-code{
  font-size:56px;line-height:1;font-weight:600;letter-spacing:-.02em;
  color:var(--n4);margin:0 0 var(--space-16);
}

/* La consigne tient sur deux lignes au plus : au-dela, elle n'est plus lue,
   et une page d'erreur n'a rien a expliquer qui demande davantage. */
.errpage-sub{max-width:34ch;margin-left:auto;margin-right:auto}

.errpage-actions{display:flex;justify-content:center;margin-top:var(--space-24)}

/* La carte perd son fond sous 480px comme les ecrans de connexion, mais le
   code garde sa presence : c'est le seul repere de la page. */
@media(max-width:480px){
  .errpage-code{font-size:44px}
}

@media(prefers-reduced-motion:reduce){*{animation-duration:.001ms!important;transition-duration:.001ms!important}.enter{opacity:1;transform:none}}
