/* ============================================================================
   cab-champ — la saisie de texte, et ce qui l'entoure.

   CE QUI GOUVERNE LE DESSIN

   1. L'ERREUR REMPLACE L'AIDE, ELLE NE S'AJOUTE PAS DESSOUS. Un formulaire où
      chaque erreur ajoute une ligne grandit à chaque validation, et les champs
      suivants sautent sous le curseur au moment précis où l'utilisateur y
      retourne pour corriger. Le message d'erreur prend donc la place du texte
      d'aide : un seul emplacement, jamais deux lignes en même temps.
   2. L'ERREUR SE VOIT AUTREMENT QUE PAR LA COULEUR. La charte Cabestian a
      mesuré que le rouge et l'ambre sont indistinguables en deutéranopie :
      la couleur seule ne peut donc pas porter l'information. Le cadre gagne
      une épaisseur de trait supplémentaire (via un anneau interne qui ne
      déplace pas la mise en page) et le message gagne une pastille « ! »,
      deux signaux de FORME, qui restent lisibles en niveaux de gris.
   3. LECTURE SEULE N'EST PAS DÉSACTIVÉ. Un champ désactivé est indisponible :
      il s'assombrit et se coupe de l'interaction. Un champ en lecture seule
      porte une valeur réelle et fiable, qu'on doit pouvoir lire et copier à
      pleine opacité ; seul son cadre passe en pointillé pour dire « ceci ne
      s'édite pas ici », sans jamais laisser croire que la donnée est absente
      ou périmée.
   4. LE CADRE VIT SUR L'ENVELOPPE, PAS SUR LE CHAMP NATIF. `input` et
      `textarea` sont posés sans bordure ni fond à l'intérieur d'une enveloppe
      commune (`cab-champ__control`), ce qui permet à un préfixe et un suffixe
      de partager exactement le même cadre que le texte plutôt que de coller
      un second bloc à côté.
   5. LE FOCUS S'AFFICHE SUR L'ENVELOPPE, PAS SUR LE CHAMP NATIF, ET AU SURVOL
      AUTANT QU'AU CLAVIER (`:focus-within`, pas `:focus-visible`). Poser
      l'anneau sur le seul `input` laisserait le préfixe et le suffixe hors du
      cadre visible ; et contrairement à un bouton, où l'anneau au clic gênerait
      plus qu'il n'informe, un champ de texte affiche son focus quel que soit
      le mode d'activation : on doit toujours voir où on écrit.
   ============================================================================ */

:where(:root),
:where([data-cab-theme]) {
  --cabc-encre:      var(--cab-ink, #06121A);
  --cabc-douce:      var(--cab-ink-2, #4D5B68);
  --cabc-faible:     var(--cab-ink-3, #8A95A0);
  --cabc-filet:      var(--cab-line, #E7E9EC);
  --cabc-filet-fort: var(--cab-line-strong, #D9DCE1);
  --cabc-fond:       var(--cab-surface, #FFFFFF);
  --cabc-creux:      var(--cab-band, #F7F8F9);
  --cabc-accent:     var(--cab-accent, #9A1B38);
  /* Texte et pastille sur un aplat de danger : jamais --cab-danger-ink, qui EST
     la teinte de danger et sert à écrire EN danger sur une surface neutre. */
  --cabc-danger:     var(--cab-danger-ink, #C2334A);
  --cabc-danger-vif: var(--cab-danger, #E5484D);
  --cabc-sur-danger: #FFFFFF;
  --cabc-sans:       var(--cab-font-sans, system-ui, sans-serif);
  --cabc-mono:       var(--cab-font-mono, ui-monospace, monospace);
}

.cab-champ {
  display: flex; flex-direction: column;
  font-family: var(--cabc-sans);
}

.cab-champ__label {
  display: block; margin: 0 0 6px;
  font-size: 12.5px; font-weight: 500; color: var(--cabc-douce);
}

/* --- l'enveloppe : le cadre commun au texte, au préfixe et au suffixe ----- */

.cab-champ__control {
  display: flex; align-items: center; gap: 6px;
  min-height: 32px; padding: 0 10px;
  border: 1px solid var(--cabc-filet); border-radius: 8px;
  background: var(--cabc-fond);
  /* `box-shadow` et non `border-width` pour l'anneau d'erreur : changer une
     épaisseur de bordure déplace le contenu d'un pixel au moment précis où
     l'utilisateur corrige. Le halo interne épaissit le trait sans rien
     bouger. */
  transition: border-color 140ms ease, box-shadow 140ms ease, background-color 140ms ease;
}
.cab-champ__control:hover { border-color: var(--cabc-filet-fort); }

.cab-champ__control:focus-within {
  border-color: var(--cabc-accent);
  outline: 2px solid var(--cabc-accent); outline-offset: 2px;
}

/* Zone de texte multiligne : le contenu s'aligne en haut, pas au centre. */
.cab-champ__control--zone { align-items: flex-start; padding: 8px 10px; }

.cab-champ__saisie {
  flex: 1 1 auto; min-width: 0;
  border: 0; background: none; outline: none; margin: 0; padding: 0;
  font: inherit; font-size: 13px; color: var(--cabc-encre); line-height: 1.35;
}
.cab-champ__saisie::placeholder { color: var(--cabc-faible); }
/* `resize: vertical` seulement : une zone qui s'élargit casse la grille du
   formulaire, une zone qui s'allonge ne casse que sa propre colonne. */
textarea.cab-champ__saisie { resize: vertical; min-height: 60px; }

/* --- préfixe et suffixe : unité, devise, symbole -------------------------- */

.cab-champ__affixe {
  flex: none;
  font-family: var(--cabc-mono); font-size: 11px; letter-spacing: .03em;
  color: var(--cabc-faible); white-space: nowrap;
}

/* --- lecture seule : la donnée reste pleine, seul le cadre change --------- */

.cab-champ__saisie:read-only { cursor: default; }
.cab-champ__control:has(.cab-champ__saisie:read-only) {
  background: var(--cabc-creux); border-style: dashed;
}

/* --- désactivé : indisponible, et ça se voit --------------------------- */

.cab-champ__saisie:disabled { cursor: not-allowed; }
.cab-champ__control:has(.cab-champ__saisie:disabled) {
  background: var(--cabc-creux); border-color: var(--cabc-filet); opacity: .55;
}
.cab-champ__control:has(.cab-champ__saisie:disabled) .cab-champ__saisie,
.cab-champ__control:has(.cab-champ__saisie:disabled) .cab-champ__affixe { color: var(--cabc-faible); }

/* --- aide et erreur : un seul des deux occupe la place -------------------- */

.cab-champ__aide, .cab-champ__erreur {
  margin: 6px 0 0; font-size: 12px; line-height: 1.5;
}
.cab-champ__aide { color: var(--cabc-faible); }
.cab-champ__erreur {
  display: none; align-items: center; gap: 6px;
  color: var(--cabc-danger); font-weight: 500;
}
/* La pastille « ! » : le second signal de forme, indépendant de la teinte. */
.cab-champ__erreur::before {
  content: "!"; flex: none;
  display: inline-flex; align-items: center; justify-content: center;
  width: 14px; height: 14px; border-radius: 50%;
  background: var(--cabc-danger-vif); color: var(--cabc-sur-danger);
  font-size: 10px; font-weight: 700; line-height: 1;
}

.cab-champ[data-etat="erreur"] .cab-champ__aide { display: none; }
.cab-champ[data-etat="erreur"] .cab-champ__erreur { display: flex; }
.cab-champ[data-etat="erreur"] .cab-champ__control {
  border-color: var(--cabc-danger-vif);
  box-shadow: 0 0 0 1px var(--cabc-danger-vif) inset;
}
.cab-champ[data-etat="erreur"] .cab-champ__control:focus-within {
  outline-color: var(--cabc-danger-vif);
}

/* --- compact, pour les barres denses --------------------------------------- */

.cab-champ[data-taille="compact"] .cab-champ__control {
  min-height: 26px; padding: 0 8px; border-radius: 6px;
}
.cab-champ[data-taille="compact"] .cab-champ__saisie,
.cab-champ[data-taille="compact"] .cab-champ__affixe { font-size: 12px; }
.cab-champ[data-taille="compact"] .cab-champ__label { font-size: 11px; margin-bottom: 4px; }

@media (prefers-reduced-motion: reduce) {
  .cab-champ__control { transition: border-color 140ms ease, background-color 140ms ease; }
}
