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. Titlul și descrierea nu au tipografie proprie: .modal-title e .t28 și .modal-body e .t14 — același selector în regula treptei din scală. Slotul adaugă doar spațierea.
.modal-title = .t28 · 22→28px / 700 · ink · 8px dedesubt
padding-right 40px (lasă loc pentru X)
.modal-body = .t14 · 14px / 20px / 500 · fog · 24px dedesubt
.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.Modal în pași · .modal.stepped
Un flux scurt — editare → … → confirmare — într-o singură fereastră. Confirmarea nu mai e un al doilea modal deschis peste primul, ci ultimul pas al aceluiași modal. Pașii stau sub titlu (--sp-16 deasupra, --sp-28 dedesubt), iar fereastra are aceeași înălțime la toți pașii (--modal-stepped-h = cel mai înalt pas): se schimbă doar conținutul din .modal-step, butoanele stau pe loc. Exemplele sunt din Vertigo: Status ONRC în 2 pași și Sediu social în 4 pași pe .modal.lg, la 700px.
Modifică Status ONRC
Valoare actuală: Neînregistrat
Confirmă modificarea
Status ONRC e un atribut important. Verifică modificarea înainte să o salvezi.
- Status ONRC
- Neînregistrat → Înregistrat
- Intră în vigoare
- 13 octombrie 2026
Modifică sediu social
Cât timp e valabil sediul și cum e folosit.
Confirmă modificarea
Sediul social se schimbă în toate documentele firmei de la data intrării în vigoare. Verifică datele înainte să le salvezi.
- Adresă
- Str. Lizeanu 23, ap. 4
- Localitate
- București, Sector 2
- Valabil
- 1 nov. 2026 – 31 oct. 2029
- Mod de folosință
- Contract de comodat
- Spațiul folosit
- Tot imobilul
- Documente
- 2 încărcate
.modal.stepped display flex · column · height var(--modal-stepped-h)
max-height calc(100dvh − 64px)
ordine X · .modal-title · .stepper · .modal-step · .modal-actions
.stepper SUB titlu — --sp-16 deasupra, --sp-28 dedesubt
mărimea de conținut: chip 28 · label 14 · gap 28
.modal-step descrierea + câmpurile pasului · se derulează dacă depășește
.modal-actions lipit jos · --sp-24 deasupra · rând pe desktop
ambele butoane md (40px) — .btn.outline + .btn.primary
.lg doar pe mobil
înălțime aceeași la toți pașii = cel mai înalt pas (pus de flux)
pași 2–5 · ultimul = Confirmare (.quantum-stack + „Da, salvează")
4–5 pași sau câmpuri pe 2 coloane → .modal.lg
5 pași → stepperul trece singur pe treapta compactă (26 · 13 · gap 22)
> 5 pași sau > 6 câmpuri pe pas → ecran de flux, nu modal
acțiuni primul [Anulează][Continuă] · mijloc [Înapoi][Continuă]
ultimul [Înapoi][Da, salvează] · Continuă disabled până e valid
focus la schimbarea pasului → titlul (h2 tabindex=-1)
mobil TBD — varianta nu e desenată sub 1024px
.stepper.mobile sau contor „2 din 4"), înălțimea fixă și dacă fereastra devine ecran de flux. Până atunci, nu o folosi pe mobil fără un design aprobat.