/* ===========================================================================
   /login — habillage de l'écran d'entrée (#800)
   ---------------------------------------------------------------------------
   POURQUOI CE FICHIER EXISTE.
   `login.blade.php` portait sa PROPRE copie de la palette : 14 littéraux
   hexadécimaux, ses propres variables (`--petrole`, `--ink`, `--ink-2`…), sa
   propre pile de polices (`'Inter', -apple-system…`), ses propres rayons et son
   ombre. L'écran était donc HORS DE LA CASCADE : une correction de jeton ne
   l'atteignait pas, et sa copie avait déjà dérivé une fois (le `--ink-3`
   d'avant #438 y survivait). CLAUDE.md §Front : « le front possède une source
   canonique unique de tokens ».

   La règle qui tient ici : ce fichier ne DÉCLARE aucune couleur, aucune police,
   aucun rayon — il ne fait que CITER `optifisc-tokens.css`. Un `#hex` dans ce
   fichier est un bug, pas un choix. `npm run tokens:audit` le voit.

   CE QU'IL NE TOUCHE PAS. Rien de ce fichier n'entre dans le chemin
   d'authentification : ni la validation, ni le verrou anti-bruteforce, ni le
   CSRF, ni le message de refus (qui ne distingue jamais « compte inconnu » de
   « mot de passe faux »). `login.js` n'a pas bougé d'une ligne.

   COMPOSITION. Deux colonnes, `1fr / 760px` (maquette « Connexion 29 pouces ») :
   à gauche la marque sur fond océan, à droite l'accès sur surface claire.
   Replis : ≤1279 la colonne de marque passe en bandeau au-dessus ; ≤560 elle se
   réduit au bloc de marque seul (le titre de marque et sa phrase sortent — sur
   un écran de 412 px, ils repoussent le formulaire sous la ligne de flottaison).
   =========================================================================== */

/* Le socle pose une grille à deux pistes pour le shell (`body>*{grid-column:2}`).
   `/login` n'a PAS de shell — c'est délibéré (#766 : la page d'entrée ne charge
   ni `optifisc-shared.js` ni `of-ui.js`). On repasse donc en flux normal plutôt
   que d'occuper la deuxième piste d'une grille sans première colonne. */
body{
  display:block;
  background:var(--of-ocean-950);
  background-attachment:scroll;
}

.cnx-page{
  min-height:100dvh;
  display:grid;
  grid-template-columns:minmax(0,1fr) minmax(0,760px);
}

/* ---------- Colonne de marque (océan) ---------- */

.cnx-marque{
  position:relative;
  overflow:hidden;
  background:var(--of-ocean-950);
  color:var(--of-white);
  padding:56px 64px;
  display:flex;
  flex-direction:column;
  justify-content:space-between;
  gap:40px;
}

.cnx-logo{display:flex;align-items:center;gap:12px}
/* L'étoile réutilise `.of-marque-etoile` du socle : c'est LÀ que le solaire est
   posé, et il n'entre nulle part ailleurs (cf. le commentaire de la règle dans
   `optifisc.css`). Ici on ne fait que l'agrandir. */
.cnx-logo .of-marque-etoile svg{width:30px;height:30px}
.cnx-logo-mot{
  font-family:var(--of-font-display);
  font-size:29px;line-height:32px;font-weight:500;
  letter-spacing:.2px;color:var(--of-white);
}

.cnx-promesse{max-width:62ch}
.cnx-promesse h1{
  margin:0;
  font-family:var(--of-font-display);
  font-size:56px;line-height:62px;font-weight:500;
  letter-spacing:-.4px;color:var(--of-white);
}
.cnx-promesse p{
  margin:20px 0 0;
  font-size:17px;line-height:28px;color:var(--of-sur-marine);
}

.cnx-provision{
  margin:0;
  font-size:12px;line-height:18px;color:var(--of-sur-marine-faible);
}

/* ---------- Colonne d'accès (surface claire) ---------- */

.cnx-acces{
  background:var(--of-surface-200);
  color:var(--of-ink-950);
  padding:56px 72px;
  display:flex;
  flex-direction:column;
  justify-content:center;
}
.cnx-acces-corps{width:100%;max-width:480px}

.cnx-acces h2{
  margin:0;
  font-family:var(--of-font-display);
  font-size:34px;line-height:40px;font-weight:400;
  color:var(--of-ink-950);
}
.cnx-intro{margin:8px 0 0;font-size:14px;line-height:22px;color:var(--of-ink-650)}

/* ---------- L'alerte ----------
   UN seul emplacement, alimenté par `login.js` : refus d'identifiants, bride de
   tentatives (429) et indisponibilité y écrivent tour à tour. On n'en fait pas
   trois blocs distincts dans le balisage — ce serait exiger de `login.js` qu'il
   choisisse une cible, donc modifier le chemin d'authentification pour une
   raison de dessin. La doctrine du refus muet, elle, est PERMANENTE : elle vit
   plus bas, dans les notes, pas dans un état d'erreur transitoire.

   ⚠️ PAS D'ICÔNE DANS CE BLOC, et c'est un choix de robustesse, pas d'esthétique.
   `login.js` écrit le message par `textContent` : un `<svg>` placé DANS `#error`
   serait effacé à la première erreur. Le sortir dans un frère et piloter le tout
   par `:has()` marcherait, mais un `:has()` non supporté laisserait l'écran MUET
   sur un échec de connexion — sur une surface de sécurité, on ne troque pas une
   garantie d'affichage contre une icône. Le filet de gauche joue son rôle. */
.cnx-alerte{
  display:none;
  margin-top:20px;padding:13px 16px;
  border-radius:var(--of-radius-md);
  border-left:3px solid var(--of-negative-700);
  background:var(--of-negative-100);
  box-shadow:inset 0 0 0 1px var(--of-negative-700);
  font-size:13px;line-height:20px;color:var(--of-negative-700);
}
.cnx-alerte.show{display:block}

/* ---------- Formulaire ---------- */

.cnx-form{display:flex;flex-direction:column;gap:16px;margin-top:26px}
/* `login.js` masque ce groupe (`style.display='none'`) quand il bascule sur le
   second facteur, et le rétablit à `''` — donc à la valeur de CETTE règle. */
.cnx-groupe{display:flex;flex-direction:column;gap:16px}
.cnx-champ{display:flex;flex-direction:column;gap:7px}
.cnx-champ label{
  font:var(--of-label);color:var(--of-ink-950);
}
.cnx-champ input{
  height:46px;padding:0 14px;
  border:0;border-radius:var(--of-radius-md);
  background:var(--of-white);
  box-shadow:var(--of-anneau);
  font-family:var(--of-font-ui);font-size:14px;
  color:var(--of-ink-950);
  outline:none;
  transition:box-shadow .15s;
}
.cnx-champ input:focus-visible{box-shadow:var(--of-anneau-selection)}
.cnx-aide{margin:0;font:var(--of-caption);color:var(--of-ink-550)}

.cnx-envoyer{
  height:48px;margin-top:6px;
  border:0;border-radius:var(--of-radius-md);
  background:var(--of-teal-650);color:var(--of-white);
  font-family:var(--of-font-ui);font-size:15px;font-weight:700;
  cursor:pointer;
  transition:background .15s;
}
.cnx-envoyer:hover{background:var(--of-petrol-800)}
.cnx-envoyer:focus-visible{outline:2px solid var(--of-teal-650);outline-offset:2px}
.cnx-envoyer[disabled]{opacity:.6;cursor:progress}

/* ---------- Notes de doctrine ----------
   Deux faits PERMANENTS, pas des états : ils sont vrais avant, pendant et après
   une tentative. Le second porte le copywriting du refus muet, qui est une
   décision de sécurité (#800) — le dire ici, en clair, évite qu'un utilisateur
   déduise de « identifiants incorrects » que l'adresse, elle, était bonne. */
.cnx-notes{
  display:flex;flex-direction:column;gap:10px;
  margin-top:28px;padding-top:22px;
  border-top:1px solid var(--of-line-200);
}
.cnx-note{
  margin:0;display:flex;align-items:flex-start;gap:9px;
  font-size:12px;line-height:18px;color:var(--of-ink-650);
}
.cnx-note svg{flex:0 0 15px;margin-top:2px}
.cnx-note strong{font-weight:650;color:var(--of-ink-950)}
.cnx-note-ic-accent{color:var(--of-teal-650)}
.cnx-note-ic-muet{color:var(--of-ink-550)}

.cnx-retour{margin:22px 0 0;font-size:12px}
.cnx-retour a{color:var(--of-teal-650)}

/* ---------- Replis ---------- */

@media (max-width:1279px){
  /* `auto 1fr` : sans la seconde piste explicite, les deux rangées d'une grille
     `min-height:100dvh` s'étirent à parts égales et le bandeau de marque gagne
     une hauteur qu'aucun contenu ne justifie. */
  .cnx-page{grid-template-columns:minmax(0,1fr);grid-template-rows:auto 1fr}
  .cnx-marque{padding:40px 40px 44px;gap:28px;justify-content:flex-start}
  .cnx-promesse h1{font-size:38px;line-height:44px}
  .cnx-promesse p{font-size:15px;line-height:24px;margin-top:14px}
  .cnx-acces{padding:44px 40px 64px;justify-content:flex-start}
  .cnx-acces-corps{max-width:560px;margin:0 auto}
}

@media (max-width:560px){
  /* Le bandeau de marque se réduit au bloc de marque : sur 412 px, un titre de
     38 px et sa phrase repousseraient le formulaire hors de l'écran. La promesse
     n'est pas supprimée du produit, elle cède la place à l'action. */
  .cnx-marque{padding:22px 20px;gap:0}
  .cnx-promesse,.cnx-provision{display:none}
  .cnx-logo .of-marque-etoile svg{width:24px;height:24px}
  .cnx-logo-mot{font-size:23px;line-height:26px}
  .cnx-acces{padding:28px 20px 56px}
  .cnx-acces h2{font-size:27px;line-height:33px}
}

@media (prefers-reduced-motion:reduce){
  .cnx-champ input,.cnx-envoyer{transition:none}
}
