/* ui-auth.css — vocabularul ecranelor de autentificare, desprins din
   ui-forms.css (BACKOFFICE-19): poarta are propria ei limbă vizuală și era
   exact jumătatea pe care un reskin de formulare nu o atinge. Se leagă din
   layout.html imediat după ui-forms.css, deci cascada rămâne cea veche. */

/* ---- vocabularul ecranelor de autentificare --------------------------------
 * AUTORAT pe tokeni, ca restul consolei, după ecranele de autentificare ale
 * prototipului (scanexpert-backoffice: `.auth-shell`, `.auth-card`,
 * `.auth-heading`, `.auth-fields`, `.auth-field-error`, `.auth-alert`,
 * `.pw-requirements`). Numele de clasă vin din prototip; fiecare
 * culoare/rază/tipografie e tradusă pe tokenul canonic prin
 * design-kit/dialect.json — niciun hex copiat.
 *
 * Înlocuiește vechiul set `.gate*` din app.css, care picta din paleta legacy
 * (--paper/--ink/--accent). Setul acela nu mai există; o regulă `.gate*`
 * reintrodusă e un defect, fiindcă definițiile sunt șterse.
 *
 * Prototipul așează hero-ul în stânga și cardul în dreapta, cu O IMAGINE PE
 * FIECARE ECRAN. Hero-urile sunt vendorizate în internal/web/assets/hero/, nu
 * de pe o rețea: pagina de urgență de la /login/local folosește ACELAȘI
 * vocabular și trebuie să se deseneze cu internetul căzut. Nimic de aici nu
 * cere o cerere în afara originii.
 *
 * Escape-uri față de scala de tokeni, toate adunate aici: prototipul respiră
 * pe 32/56/80px, iar scala de spațiere se oprește la 28px; lățimea cardului
 * (568px) și înălțimea siglei (48px) sunt tot măsuri ale prototipului fără
 * token. Sunt variabile locale ca să existe o singură dată, nu împrăștiate. */

:root {
  --auth-gap-md: 32px;
  --auth-gap-lg: 56px;
  --auth-gap-xl: 80px;
  --auth-card-w: 568px;
  --auth-logo-h: 48px;
}

.auth-shell {
  min-height: 100vh;
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  background: var(--se-color-bg-surface);
}

/* Paginile fără hero — accesul de urgență și activarea invitației — cer o
   singură coloană EXPLICIT. Un `:has()` ar fi făcut-o singur, dar pagina de
   urgență e ultima care are voie să depindă de suportul unui selector: fără el
   cardul ar sta în jumătatea stângă a ecranului. */
.auth-shell[data-layout="solo"] {
  /* Un singur TRACK, cât cardul, centrat pe amândouă axele. Fără asta cardul se
     lipea de colțul din stânga-sus al ecranului: pe paginile cu hero centrarea
     o face `.auth-panel`, iar aceste două pagini nu au una. */
  grid-template-columns: minmax(0, var(--auth-card-w));
  justify-content: center;
  align-content: center;
  padding: var(--auth-gap-lg) var(--se-space-24);
}

/* Câte o imagine pe ecran, ca în prototip. Legătura se face prin `data-hero`
   și nu prin `<img src>` pentru că fișierul ăsta e digerat în AssetsVersion:
   o imagine schimbată mută ?v=-ul stylesheet-ului care o cere, iar un `src`
   scris din JS n-ar avea de unde să ia versiunea. */
.auth-hero {
  background-image: url("hero/login-hero.webp");
  background-size: cover;
  background-position: center;
}

.auth-hero[data-hero="register"] {
  background-image: url("hero/register-hero.webp");
}
.auth-hero[data-hero="requestSent"] {
  background-image: url("hero/request-sent-hero.webp");
}
.auth-hero[data-hero="forgot"] {
  background-image: url("hero/forgot-hero.webp");
}
.auth-hero[data-hero="codeSent"] {
  background-image: url("hero/link-sent-hero.webp");
}
.auth-hero[data-hero="reset"] {
  background-image: url("hero/reset-hero.webp");
}
.auth-hero[data-hero="resetDone"] {
  background-image: url("hero/reset-done-hero.webp");
}

.auth-panel {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--auth-gap-lg);
  overflow-y: auto;
}

.auth-card {
  width: 100%;
  max-width: var(--auth-card-w);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--auth-gap-lg);
}

/* Fără hero, cardul plutește singur pe un ecran gol — deci acolo desenează o
   ramă, ca să aibă o margine. Pe ecranele cu hero, marginea o dă imaginea. */
.auth-shell[data-layout="solo"] .auth-card {
  gap: var(--auth-gap-md);
  padding: var(--auth-gap-md) var(--se-space-24) var(--se-space-24);
  background: var(--se-color-bg-surface);
  border: 1px solid var(--se-color-border-default);
  border-radius: var(--se-radius-lg);
}

/* Cardul de urgență e cel pe care n-ar trebui să fii: muchie roșie, nu navy. */
.auth-card[data-variant="breakglass"] {
  border-top: 2px solid var(--se-color-alert-red-600);
}

/* Prototipul ascunde hero-ul sub 1220px: sub atât, jumătatea de imagine
   îngustează formularul până sub lățimea lui utilă.
   STĂ AICI, DUPĂ `.auth-panel`, și nu sus lângă `.auth-shell`: un `@media` nu
   adaugă specificitate, deci `.auth-panel` din interiorul lui cântărește exact
   cât cel de afară și pierde pe ordine dacă e scris înainte. Măsurat: padding-ul
   rămânea 56px într-o fereastră de 896px. */
@media (max-width: 1219px) {
  .auth-shell {
    grid-template-columns: minmax(0, 1fr);
  }
  .auth-hero {
    display: none;
  }
  .auth-panel {
    padding: var(--se-space-24);
  }
}

/* Sigla e imaginea reală a mărcii, nu textul „Scan Expert" pus în locul ei. */
.auth-logo {
  height: var(--auth-logo-h);
  width: auto;
  display: block;
}

/* Eticheta de context a paginilor pe care prototipul nu le are (acces de
   urgență, activare invitație): designul n-are unde să o pună, iar fără ea
   cele două pagini arată identic cu autentificarea normală. */
.auth-microlabel {
  font-size: var(--se-type-micromed-size);
  line-height: var(--se-type-micromed-line);
  font-weight: var(--se-type-micromed-weight);
  color: var(--se-color-text-description);
  text-transform: uppercase;
  letter-spacing: 0.06em;
}

/* Una dintre vederi e vizibilă; restul poartă `hidden`. Ascunderea e
   atributul, nu o clasă — un formular ascuns rămâne un formular, iar `hidden`
   e ce citește și tastatura. */
.auth-view[hidden] {
  display: none;
}

.auth-view {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--se-space-24);
  width: 100%;
}

/* Ecranele de confirmare (cerere trimisă, cod trimis, parolă schimbată) respiră
   cu o treaptă mai mult decât cele cu formular — `--gap32` în prototip. */
.auth-view[data-shape="confirm"] {
  gap: var(--auth-gap-md);
}

.auth-heading {
  display: flex;
  flex-direction: column;
  gap: var(--se-space-8);
  text-align: center;
  width: 100%;
}

.auth-heading h1 {
  margin: 0;
  color: var(--se-color-text-title);
  font-size: var(--se-type-h2med-size);
  line-height: var(--se-type-h2med-line);
  font-weight: var(--se-type-h2med-weight);
}

.auth-heading p {
  margin: 0;
  color: var(--se-color-text-title);
  font-size: var(--se-type-bodyreg-size);
  line-height: var(--se-type-bodyreg-line);
}

.auth-form {
  display: flex;
  flex-direction: column;
  gap: var(--auth-gap-md);
  width: 100%;
}

/* `hidden` is an attribute the UA styles with `display: none` at the LOWEST
   priority, so ANY `display` written in a class beats it. The register view's
   code step is a `.auth-form` that starts hidden, and it drew under the form it
   replaces until this rule existed. Every component here that sets `display`
   owes the same line — see `.auth-view[hidden]` above. */
.auth-form[hidden] {
  display: none;
}

.auth-fields {
  display: flex;
  flex-direction: column;
  gap: var(--se-space-16);
  width: 100%;
}

/* Câmpul își poartă propria etichetă și propria eroare. Pastila de 44px, hover
   roz și cele două stări de focus vin din baza de elemente (ui-forms.css) —
   nu se rescriu aici, ar fi al doilea adevăr despre același câmp. */
.auth-field label {
  display: block;
  color: var(--se-color-text-title);
  margin-bottom: var(--se-space-8);
  font-size: var(--se-type-bodyreg-size);
  line-height: var(--se-type-bodyreg-line);
}

/* Baza pune 12px sub fiecare câmp; aici distanța dintre câmpuri o dă `gap`, iar
   marginea în plus ar dubla-o. */
.auth-field input {
  margin-bottom: 0;
}

.auth-field[data-invalid="true"] input {
  border-color: var(--se-color-alert-red-600);
}

/* Eroarea de câmp e pastila roșie a prototipului, cu iconița de avertizare
   lângă text. `hidden` o scoate cu totul, ca la vederi. */
.auth-field-error {
  display: flex;
  align-items: center;
  gap: var(--se-space-8);
  margin-top: var(--se-space-8);
  padding: var(--se-space-4) var(--se-space-12);
  background: var(--se-color-badge-red-100);
  border: 1px solid var(--se-color-alert-red-600);
  border-radius: var(--se-radius-pill);
  color: var(--se-color-alert-red-600);
  font-size: var(--se-type-bodyreg-size);
  line-height: var(--se-type-bodyreg-line);
}

.auth-field-error[hidden] {
  display: none;
}

.auth-field-error .ph {
  font-size: var(--se-size-icon-functional);
  flex: 0 0 auto;
}

/* Un text lung nu mai e o pastilă: se aliniază sus și pierde rotunjirea. */
.auth-field-error[data-multiline="true"] {
  align-items: flex-start;
  border-radius: var(--se-radius-md);
}

.auth-field-error[data-multiline="true"] .ph {
  margin-top: var(--se-space-4);
}

/* Anunțul neutru al prototipului — „În așteptarea aprobării". Albastrul de
   informare, nu verdele de succes: cererea a plecat, dar nu s-a rezolvat. */
.auth-alert {
  display: flex;
  align-items: center;
  gap: var(--se-space-8);
  padding: var(--se-space-8) var(--se-space-16);
  background: var(--se-color-badge-blue-100);
  border: 1px solid var(--se-color-badge-blue-600);
  border-radius: var(--se-radius-pill);
  color: var(--se-color-badge-blue-600);
  font-size: var(--se-type-bodyreg-size);
  line-height: var(--se-type-bodyreg-line);
}

.auth-alert .ph {
  font-size: var(--se-size-icon-functional);
  flex: 0 0 auto;
}

/* Aceeași pastilă, celălalt ton: refuzul de drepturi nu e o informare. Albastrul
   spune „am primit cererea", iar peste «drept lipsă» ar fi mesaj amestecat. */
.auth-alert[data-kind="warn"] {
  background: var(--se-color-badge-red-100);
  border-color: var(--se-color-alert-red-600);
  color: var(--se-color-alert-red-600);
}

/* „Ai uitat parola?" stă lipit de dreapta formularului, sub câmpuri. */
.auth-forgot-link {
  align-self: flex-end;
}

.auth-actions {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--se-space-16);
  width: 100%;
}

/* Fiecare acțiune ocupă lățimea cardului: designul n-are butoane pe jumătate de
   rând pe ecranele astea. Primarul rămâne butonul gol al bazei, alternativa e
   `.secondary` din aceeași bază — două vocabulare pentru același buton ar fi
   exact duplicarea pe care o evităm. */
.auth-actions > button,
.auth-actions > [role="button"] {
  width: 100%;
}

/* Ce ține cardul sub siglă: vederile și linia de stare, la distanța dintre
   blocuri a designului, nu la cea dintre siglă și conținut. */
.auth-content {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--se-space-24);
  width: 100%;
}

/* Rândul „Nu ai cont? Creează cont", sub card. */
.auth-signup-row {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--se-space-8);
  width: 100%;
  color: var(--se-color-text-title);
  font-size: var(--se-type-bodyreg-size);
  line-height: var(--se-type-bodyreg-line);
}

/* ---- butoanele-text ---------------------------------------------------------
 * ui-forms.css pictează ORICE <button> gol ca primarul navy, iar hover-ul lui
 * cântărește (0,2,1) — mai mult decât o clasă simplă. Un buton-text care declară
 * doar `background: none` la repaus primește fundal navy la hover și textul lui
 * navy dispare. De aceea fiecare stare de mai jos e scrisă la ≥(0,3,0) și pune
 * ȘI fundal ȘI culoare, ca în doctrina din CLAUDE.md. */

.auth-link-btn,
.auth-signup-btn,
.auth-forgot-link,
.auth-back-btn {
  border: 1px solid transparent;
  background: none;
  color: var(--se-color-primary-60);
  font-family: var(--se-font-family);
  font-size: var(--se-type-bodyreg-size);
  line-height: var(--se-type-bodyreg-line);
  cursor: pointer;
}

.auth-link-btn:hover:not(:disabled),
.auth-signup-btn:hover:not(:disabled),
.auth-forgot-link:hover:not(:disabled),
.auth-back-btn:hover:not(:disabled) {
  background: var(--se-color-bg-console);
  border-color: transparent;
  color: var(--se-color-primary-70);
}

.auth-link-btn:disabled,
.auth-signup-btn:disabled,
.auth-forgot-link:disabled,
.auth-back-btn:disabled {
  background: none;
  border-color: transparent;
  color: var(--se-color-primary-20);
}

/* Cele două de sub formular sunt „legături": greutate medie, fără pastilă. */
.auth-signup-btn,
.auth-forgot-link {
  padding: 10px 0;
  font-weight: var(--se-type-bodymed-weight);
  color: var(--se-color-primary-70);
}

.auth-forgot-link {
  padding: 10px var(--se-space-24);
  border-radius: var(--se-radius-pill);
}

/* Întoarcerea la autentificare: acțiune de rang doi în `.auth-actions`, deci
   pe toată lățimea, fără contur, cu greutatea unui buton. */
.auth-back-btn {
  padding: 10px var(--se-space-24);
  border-radius: var(--se-radius-md);
  font-weight: var(--se-type-bodymed-weight);
}

/* Legătura subliniată din josul cardului (prototipul o folosește pentru pasul
   secundar de pe ecranul „cod trimis"). */
.auth-link-btn {
  padding: 0;
  text-decoration: underline;
  text-underline-offset: 2px;
}

/* ---- linia de stare ---------------------------------------------------------
 * Ce spune scriptul despre pasul în curs: neutru cât timp lucrează, pastila
 * roșie când refuză, cea verde când a reușit. Trei stări, trei culori: o eroare
 * care arată ca o notificare de succes e o eroare pe care nimeni nu o citește. */

.auth-status {
  display: flex;
  align-items: center;
  gap: var(--se-space-8);
  margin: 0;
  width: 100%;
  color: var(--se-color-text-description);
  font-size: var(--se-type-captionreg-size);
  line-height: var(--se-type-captionreg-line);
  min-height: var(--se-type-captionreg-line);
}

.auth-status[data-kind="err"] {
  padding: var(--se-space-8) var(--se-space-16);
  background: var(--se-color-badge-red-100);
  border: 1px solid var(--se-color-alert-red-600);
  border-radius: var(--se-radius-md);
  color: var(--se-color-alert-red-600);
}

.auth-status[data-kind="ok"] {
  padding: var(--se-space-8) var(--se-space-16);
  background: var(--se-color-badge-green-100);
  border: 1px solid var(--se-color-badge-green-600);
  border-radius: var(--se-radius-md);
  color: var(--se-color-badge-green-600);
}

.auth-foot {
  width: 100%;
  padding-top: var(--se-space-16);
  border-top: 1px solid var(--se-color-border-default);
  color: var(--se-color-text-description);
  font-size: var(--se-type-captionreg-size);
  line-height: var(--se-type-captionreg-line);
  text-align: center;
}

.auth-code {
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.4em;
  text-align: center;
}

/* Învelișul pe care reveal.js îl construiește în jurul unui câmp de parolă.
   Butonul stă PESTE câmp, deci câmpul își păstrează lățimea întreagă. */
.auth-secret {
  position: relative;
  display: block;
}
.auth-secret > input {
  width: 100%;
  padding-right: 2.75rem;
}

/* Ochiul e tot un <button>, deci cade pe primarul navy al bazei dacă nu-și
   scrie singur fundalul în FIECARE stare. Fără `background: none` la hover,
   iconița primea o pastilă navy peste câmp. */
.auth-secret > .reveal {
  position: absolute;
  top: 50%;
  right: var(--se-space-8);
  transform: translateY(-50%);
  display: flex;
  align-items: center;
  justify-content: center;
  width: var(--se-size-icon-functional);
  height: var(--se-size-icon-functional);
  padding: 0;
  border: none;
  background: none;
  color: var(--se-color-text-description);
  cursor: pointer;
}

.auth-secret > .reveal:hover:not(:disabled) {
  background: none;
  color: var(--se-color-text-title);
}

/* The icon is the button's only content, so it must not sit on a text baseline. */
.auth-secret > .reveal svg {
  display: block;
}

/* Tabbing from the field to the eye must not change the vocabulary, so the eye
   takes a focus ring of its own rather than inheriting the browser's. */
.auth-secret > .reveal:focus-visible {
  background: none;
  color: var(--se-color-text-title);
  outline: 2px solid var(--se-color-secondary-60);
  outline-offset: 1px;
  box-shadow: none;
}

/* ---- lista de cerințe pentru parolă -----------------------------------------
 * Forma e a prototipului (frază introductivă + listă cu bifă), dar REGULA e a
 * noastră și e una singură — lungimea — argumentată în auth.go:175-179
 * (HashPassword). Clerk are propria politică, pe care acest repo nu o poate
 * citi, așa că mesajul lui trece nemodificat prin login.js când nu e de acord.
 * Iconița vine din subsetul Phosphor vendorizat pe originea noastră, deci se
 * desenează și cu internetul căzut. */
.auth-reqs {
  display: flex;
  flex-direction: column;
  gap: var(--se-space-4);
  width: 100%;
  list-style: none;
  margin: var(--se-space-8) 0 0;
  padding: 0;
  color: var(--se-color-text-title);
  font-size: var(--se-type-bodyreg-size);
  line-height: var(--se-type-bodyreg-line);
}

.auth-req {
  display: flex;
  align-items: center;
  gap: var(--se-space-8);
}

.auth-req .ph {
  font-size: var(--se-size-icon-functional);
  flex: 0 0 auto;
  color: var(--se-color-primary-30);
}

.auth-req[data-met="true"] .ph {
  color: var(--se-color-badge-green-600);
}
