Suprafața canonică pentru orice overlay ancorat de un declanșator: dropdown menu, popover cu conținut liber, lista de typeahead, dropdown-ul din .stepper.mobile. Nu e modal — un modal blochează pagina și are scrim; un popover nu.
Markup canonic · components/popover.json
sursa = JSON · generat de scripts/build-catalog.py
Document
Suprafața
background --c-white
border 1px solid --c-rule-card
border-radius --r-lg /* 20px — o treaptă peste .stepper-menu vechi (md) */
padding 6px
min-width 200px
box-shadow --sh-popover
gap 2px /* între rânduri */
Radiusul suprafeței e --r-lg, la fel ca .input. Un meniu mai ascuțit decât câmpul care îl deschide se citește ca alt sistem — de aici treapta în plus față de originalul .stepper-menu.
Rânduri
padding 8px 10px
border-radius --r-md /* 14px — o treaptă peste xs */
font 14px / 20px, --c-ink
hover background --c-bej-0
.is-selected valoarea ALEASĂ — bifă .popover-check la capăt (--c-accent)
+ weight 600 pe text. Fără fundal și fără culoare de text:
rândul păstrează suprafața oricărui alt rând. Bifa e la CAPĂT,
greutatea marchează cuvântul citit — canale diferite, capete
diferite. În React greutatea vine prin [data-state="checked"].
Hover-ul NU se retrage — rândul n-are culoare de apărat.
.is-active cursorul de TASTATURĂ (aria-activedescendant, typeahead) —
suprafață --c-bej-1, aceeași ca hover-ul. Text și greutate
normale: culoarea într-un rând de listă e rezervată pentru
„asta e valoarea aleasă".
hover --c-bej-1
:disabled --c-mist, cursor not-allowed
Conținut liber · .popover.content
Filtrează după perioadă
Alege un interval sau scrie unul propriu.
Când conținutul nu e o listă de acțiuni, .popover.content dă padding 16px și scoate gap-ul dintre copii — nu mai sunt rânduri de meniu, deci nu trebuie distanțate ca atare.
Conținut liber · un câmp în popover
Containerul nu ține doar rânduri de acțiune. Un câmp de căutare în .popover.content e forma canonică pentru „filtrează înainte să alegi" — câmpul e .input, nemodificat, exact ca în Search. Suprafața rămâne aceeași; se schimbă doar ce ține.
Scrie cel puțin două litere.
Dacă acel câmp filtrează o listă de rânduri, suprafața nu mai e .popover.content: rândurile au nevoie de gap-ul de 2px și de padding-ul de 6px al lui .popover. Câmpul cu listă ancorată sub el are deja o componentă — typeahead / combobox, care e .input + .popover, fără chrome propriu.
O singură suprafață, două nume
.stepper-menu nu are suprafață proprie — o împarte pe aceasta, printr-un selector grupat în bono-ds.css. Dacă ar avea una proprie, ar deriva de popover exact cum a derivat badge-ul din aplicație de badge-ul din DS. Consecință de reținut: schimbi radiusul aici, se schimbă și dropdown-ul stepper-ului mobil, în același commit.