Modal / Dialog
Markup canonic · components/modal.json
Confirmă trimiterea
Documentul ajunge la contabil în maxim 24h.
Scrim live · deschide/închide
Demo interactivă a tratamentului canonic: background: var(--c-backdrop) (ink @ 25%) + backdrop-filter: blur(var(--scrim-blur)) (6px), cu animația reală (modal-fade 180ms pe backdrop, modal-in 220ms pe card). Închide cu X, click pe backdrop, sau Escape — cele trei căi obligatorii din „Comportament obligatoriu" (docs/components/modal.md).
Către cine emitem factura?
Eyebrow parametric
Eticheta .t-eyebrow de deasupra titlului e opțională — o folosești când modalul are nevoie de context sau categorie (ex. „Factură nouă"). Layoutul cardului funcționează identic cu sau fără ea; când lipsește, titlul .t28 urcă primul și primește +4px spațiu sus.
Confirmă trimiterea
Confirmă trimiterea
Variantă · acțiuni suprapuse
Dialog de dismiss cu două acțiuni suprapuse vertical, într-un .modal-actions.stacked (= .btn-group.stacked): dismiss ca .btn.outline deasupra, confirm ca .btn.primary dedesubt. Ambele size default (md), întinse de grup; spațiere moderată: gap 8px (--sp-8). Rămâne o singură acțiune primary per modal, și aceeași ordine la orice lățime.
Renunți la modificări?
Dialog de ștergere · distructiv
Confirmarea unei acțiuni distructive, în același .modal-actions.stacked. Acțiunea distructivă e negru cu iconiță (.btn.danger), dismiss-ul deasupra ca .btn.outline — dedesubt niciodată, la nicio lățime. Pentru ștergeri cu impact mare adaugă confirmare prin nume: inputul rămâne în stare de eroare până când textul se potrivește, cu .field-help.error aliniat sub input.
Ștergi factura #2043?
Ștergi ACME Studio SRL?
Structură HTML
<div class="modal-backdrop" onclick="if(event.target===this)closeModal()">
<div class="modal">
<button class="btn outline sm icon-only" aria-label="Închide">...</button>
<div class="t-eyebrow">...</div> <!-- opțional — fără el, titlul primește margin-top:4px -->
<h2 class="t28">Titlu <em>modal</em></h2>
<!-- inputs lg -->
<button class="btn primary lg full">Acțiune</button>
<!-- SAU varianta stacked-actions (dismiss dialog) -->
<div class="modal-actions stacked">
<button class="btn outline">Renunță</button>
<button class="btn primary">Confirmă</button>
</div>
</div>
</div>
JS: backdrop.classList.toggle('open')
Sloturile
Părțile pe care orice modal le are oricum, formalizate ca să nu fie reinventate per ecran.
.modal-title 20px / 600 · ink · padding-right 40px (lasă loc pentru X)
.modal-body 15px / 22px · fog
.modal-actions flex end · gap 10px · ordinea [secundar][primar]
sub 1024px: column, aceeași ordine, fiecare buton full-width
.modal-actions.stacked
coloană la orice lățime · gap --sp-8 · suprapuse
.modal-actions e .btn-group — același selector în CSS, nu o a doua implementare. Un modal nu are alt rând de acțiuni decât restul aplicației, deci nici alt CSS. Ordinea e [secundar][primar] pe mobil și pe desktop; .stacked schimbă doar axa, niciodată ordinea.
Alert dialog · .modal.confirm
Aceeași suprafață, conținut simplificat: un titlu și o propoziție. Fără X — o întrebare blocantă cere un răspuns explicit, nu o ieșire laterală. Exemplul de aici e distructiv, deci poartă regula de ștergere: .modal-actions.stacked, cu .btn.outline deasupra și .btn.danger cu iconiță dedesubt — aceeași ca la Dialog de ștergere. Un .modal.confirm nedistructiv (confirmare de trimitere, de exemplu) folosește același .modal-actions, fără .stacked.
Ștergi factura 2026-0184?
Factura a fost deja trimisă clientului. Ștergerea nu poate fi anulată.
.modal.confirm max-width 400px · padding 28px 28px 24px
aceeași suprafață: bej-1 · --r-xl · outline alb offset 16px
butonul de închidere ascuns
acțiuni dacă e DISTRUCTIV: .modal-actions.stacked — .btn.outline
deasupra + .btn.danger (negru + iconiță) dedesubt —
aceeași regulă ca „Dialog de ștergere" mai sus
dacă NU e distructiv: același .modal-actions fără .stacked —
rând aliniat dreapta pe desktop, coloană full-width sub 1024px
ordinea [secundar][primar] în ambele cazuri, la orice lățime
role alertdialog (nu dialog) + aria-modal + aria-labelledby
.modal.alert. Ăsta era numele evident, dar .alert e deja o componentă — iar .modal.alert prinde și regula ei, care e display: flex: titlul, textul și butoanele se așează pe un rând. Un modificator nu poate purta numele unei componente existente. Prins la randare, nu la citire..btn.danger — fill --c-danger (ink), nu roșu. Și fără accent de brand în modalul distructiv: fără pink, fără <em> în titlu.