Alert

Feedback persistent — rămâne până se rezolvă cauza sau până îl închide utilizatorul. Două plasări, un singur component: inline și .alert.page. Pentru ceva tranzitoriu, Toast. Ghidul: docs/feedback.md.

Ierarhia notificărilor

Un singur principiu: cine ține informația după ce mesajul dispare.

TreaptăCine ține informațiaComponenta
0Tăcereconsecința din interfață — un sold mai mic, un document nou evident în listă, un card care lipsește. Utilizatorul vede rezultatul, deci mesajul n-ar adăuga nimicnimic
1Chitanțăinterfața ține informația, dar operațiunea a avut miză mai mare — ștergerea unui item se vede în UI și se confirmă și prin toast. Toast temporal, care poartă sens și prin culoare.toast
2Dovadămesajul, și numai mesajul — nimic din interfață nu o arată. Ex: sesiunea SPV a expirat, deci documentele nu se mai sincronizează; sau CUI-ul clientului e invalid, deci factura nu poate fi trimisă în e-Factura.alert (inline sau .page)
3Obligațiemesajul, și cere muncă.alert.page + .alert-actions, fără dismiss
4Deciziemesajul, și nimic nu merge înainte.modal

Treptele urcă, nu coboară — un eșec nu devine chitanță pentru că e mic.

Treapta 0 e o decizie de produs, nu de design system — DS-ul nu poate ști la ce se uită utilizatorul. Dar întrebarea merită pusă pe fiecare ecran: mesajul ăsta adaugă ceva ce interfața nu arată deja? O coloană de status care se schimbă, un sold care se actualizează, un badge care trece pe success — acolo feedbackul e starea vizibilă, nu un mesaj.

Work in progress — maparea aplicațiilor reale. Ierarhia e definită, dar nu e încă verificată pe inventarul complet de notificări din aplicațiile noastre. Urmează un task de inventariere: fiecare tip de notificare existent, mapat pe una din cele cinci trepte. Ce se schimbă după inventar se schimbă aici întâi.

Markup canonic · components/alert.json

sursa = JSON · generat de scripts/build-catalog.py
Adresa de facturare lipsește. Completează-o înainte de a emite factura.

Cinci stări

.alert .neutral / .success / .warning / .error / .brand
Perioada de raportare e deschisă. D112 se poate depune până pe 25 mai.
D112 a fost depusă la ANAF. Referință 2026-04-22-7841.
Adresa de facturare lipsește. Completează-o înainte de a emite factura.
Sfat de la Vox. Cheltuiala „cazare Hartmann" pare personală — vrei s-o marchez nedeductibilă?

Fundal = tintul familiei, text = tokenul -text al familiei. Niciodată fill-ul ca text: --c-error pe --c-error-bg dă 4.38:1, sub AA. .warn și .info rămân ca aliasuri deprecate pentru .warning și .neutral.

Dismiss × acțiuni — combinația e treapta

Prezența dismissului și prezența acțiunilor sunt două semnale independente. „Fără dismiss" nu e un singur lucru.

fără acțiunicu acțiuni
cu dismissdovadă pe care o poți confirma · T2dovadă cu o scurtătură opțională · T2
fără dismisscontextul ambiental al paginii · T2 (Callout)obligație · T3
dismiss prezent   utilizatorul poate pune mesajul deoparte
acțiuni prezente  există muncă de făcut

fără dismiss, fără acțiuni   contextul paginii — mod de probă, perioadă
                             read-only. Nu e nimic de confirmat, deci nu
                             există X. Callout-ul din Carbon, fără
                             componentă nouă. NU primește nici rol ARIA.

fără dismiss, CU acțiuni     OBLIGAȚIE. Butoanele sunt singurele ieșiri.
cu buton de închidere (.btn.ghost.xs.icon-only) — mesajul răspunde la o acțiune
Doua facturi nu au putut fi încadrate automat. Le găsești în „De verificat".
fără dismiss, fără acțiuni — contextul ambiental al paginii
Contul e în modul de probă. Depunerile nu ajung la ANAF până la activarea abonamentului.

Treapta 3 — obligația

Un mesaj care e dovadă și cere muncă. Forma e .alert.page + .alert-actions, fără dismiss — butoanele sunt singurele ieșiri, fiindcă munca nu dispare când mesajul dispare.

.alert.page + .alert-actions · FĂRĂ buton de închidere
Verificarea identității e necesară. Depunerile către ANAF sunt suspendate până la finalizare.
Amânarea e o acțiune explicită, nu un X. Diferența nu e cosmetică: un X e ambiguu — aplicația nu poate distinge „am văzut" de „nu-mi mai arăta niciodată". Amână 24h e o promisiune pe care interfața o poate ține, și pe care o poate loga.
PLAFONUL, ȘI UNDE SE RUPE MVP-UL

.alert.page e max 1 vizibil. Cu două sau trei obligații simultane,
COMASEAZĂ: un singur alert care spune „3 acțiuni așteaptă" plus un buton
„Vezi", care duce la lista lor.

Limita, declarată: dacă obligațiile devin rutină — mai multe pe
săptămână, în paralel — un alert de pagină nu mai e răspunsul, oricât de
bine e comasat. Atunci ai nevoie de o SUPRAFAȚĂ DE SARCINI (panou de
notificări, carduri „acțiune necesară" pe home, o vedere de listă).
Nu e în DS și nu e în MVP. Când ajungi acolo, se decide separat.

O obligație care se încarcă odată cu pagina nu primește rol ARIA — .alert.page e primul copil al shell-ului, deci e deja primul lucru citit.

Cu acțiuni

.alert-actions — butoane sm sub text
Termenul de depunere se apropie. D390 trebuie depusă până pe 25 mai.

Alertul persistă, deci acțiunile pot fi oricâte și pot fi obligatorii. Ăsta e contrastul cu toastul, care admite o singură acțiune și numai opțională.

.alert.page — plasarea la nivel de pagină

full-bleed · colțuri drepte · lipit sus, fără gap · în flux
Adresa de facturare lipsește. Completează-o înainte de a emite factura.
Sfat de la Vox. Cheltuiala „cazare Hartmann" pare personală — vrei s-o marchez nedeductibilă?
.alert.page   width 100% · border-radius 0 · padding 12px 20px
              ÎN FLUX — se inserează ca prim copil al shell-ului și
              ÎMPINGE conținutul în jos

NU position: fixed. Fixed ar acoperi topnavul, ar cere o intrare de
z-index plus padding pe body, și s-ar putea suprapune cu un modal.
Carbon și Salesforce fac amândouă la fel pentru bara de nivel pagină.

.alert.page.brand   păstrează MARKERUL: alb, bară pink 3px stânga,
                    aldin pink, restul textului --c-ink. Identic cu
                    .alert.brand — o stare, un tratament

Anatomie

.alert > .ic  +  .alert-body  +  .btn.ghost.xs.icon-only?

.ic              16px, dat de CSS pe ambele componente de feedback — nu
                 din atributele width/height ale SVG-ului, ca să nu devieze
.alert-body      obligatoriu: poartă min-width: 0, fără care textul lung
                 nu se comprimă și împinge dismissul afară din suprafață
.alert-actions   în .alert-body, sub text
butonul de      opțional (vezi mai sus). NU o clasă proprie — e butonul din
închidere       DS: .btn.ghost.xs.icon-only (26×26, cerc, glif 12px).
                Singura extensie scopată e culoarea: pe un tint de warning
                sau error, ghostul --c-fog s-ar certa cu textul de lângă,
                deci moștenește culoarea stării

Anunțare

.alert.error   role="alert"    asertiv, întrerupe
celelalte      role="status"   politicos, la următoarea pauză

Rolul se pune DOAR pe alertele care apar după încărcare. Un alert randat
cu pagina e deja în ordinea de citire, iar un rol pe el îl face citit de
două ori — deci alertul de context ambiental NU primește rol.

butonul de închidere   aria-label — e icon-only
.ic              aria-hidden="true" — decorativ, mesajul e în text

Migrare de la .banner / .page-banner

Deprecat (v8)Folosește
.banner.alert
.page-banner.alert.page
.banner-body / .banner-text.alert-body
.page-banner-body.alert-body
.banner-actions.alert-actions
.banner-dismiss / .page-banner-dismiss.btn.ghost.xs.icon-only
.info / .warn.neutral / .warning
.page-banner.dark.alert.page.brand
.alert.floating.toast într-un .toast-stack

Cele deprecate rămân funcționale până la îndepărtare — nu mai devreme de v10 (VERSIONING.md). Borderul de 1px de pe .banner.error nu se migrează: .alert are o singură regulă de bordură pentru toate stările.