Icons
Un singur set — Lucide, grila 24×24 — printr-o singură clasă, .ic. Markup-ul poartă glifa copiată verbatim din assets/icons/; CSS-ul decide mărimea și grosimea liniei (optică, pe trepte). Așa nu poate deriva: înainte de 2026-09-10 sistemul avea 111 desene diferite, 6 grile și 9 grosimi, iar „warning" exista în patru variante.
Markup canonic · components/foundation-icons.json
Specificația — ce e în markup, ce e în CSS
| Ce | Valoare | De unde |
|---|---|---|
glifă | Lucide, copiată verbatim | assets/icons/<nume>.svg — niciodată redesenată sau editată |
grilă | viewBox="0 0 24 24" | markup — grila Lucide, cu 2px padding optic |
grosime | în pixeli de ecran, optic pe trepte: 12→1.25 · 14→1.5 · 16→1.5 · 18→1.75 · 20→1.75 · 24→2 | stroke-width pe fiecare clasă de mărime + vector-effect: non-scaling-stroke. În markup rămâne stroke-width="2" (valoarea Lucide) — CSS-ul o suprascrie |
mărime | .ic.xs 12 · .ic.sm 14 · .ic 16 · .ic.md 18 · .ic.lg 20 · .ic.xl 24 | CSS — clasa din scară, sau regula părintelui: în .btn și .toggle iconul poartă doar .ic și treapta părintelui îi dă mărimea (vezi „În butoane"). Nu atributele width/height |
culoare | currentColor | textul de lângă icon — deci urmează automat tokenul -text al familiei. Pattern-ul de culoare: docs/foundation.md § Iconuri |
a11y | aria-hidden="true" | iconul e decorativ, sensul e în text. Pe un control icon-only, aria-label stă pe buton, nu în SVG |
Ancora e 16px: în playground-ul Lucide, Size 16 · Stroke 1.5 · Absolute stroke width ON. Celelalte trepte urcă sau coboară optic în jurul ei, iar la 24 linia e 2px — glifa Lucide exact așa cum e desenată.
Scara de mărimi — 12 / 14 / 16 / 18 / 20 / 24
Șase trepte, aceeași glifă, linia urcă optic cu mărimea (1.25 → 2px). Mărimea e o clasă; contextele care își știu mărimea (.btn, .toggle) o impun singure, pe treaptă, și acolo iconul poartă doar .ic. .ic.xs (12) există pentru treapta .xs a butonului și pentru text de 12px — nu pentru „mai mic că încape".
.ic.xs · 12.ic.sm · 14.ic · 16.ic.md · 18.ic.lg · 20.ic.xl · 24Grosimea liniei — optică, pe trepte, în pixeli de ecran
Un SVG își scalează linia odată cu desenul: stroke-width="2" pe grila 24 înseamnă 2px doar la 24 — la 16 dă 1.33, la 12 dă 1.0, subțire și tulbure pe ecran 1x. Nici o linie fixă nu merge: 1.5px absolut la orice mărime e 12% din icon la 12px și 6% la 24 — mic și îndesat, mare și palid. .ic pune linia în pixeli de ecran și o urcă optic, ca greutatea unei litere pe corpuri diferite: 1.25 / 1.5 / 1.5 / 1.75 / 1.75 / 2 pentru 12 / 14 / 16 / 18 / 20 / 24 (10% → 8% din icon).
.ic — optic: 1.25 / 1.5 / 1.5 / 1.75 / 1.75 / 2 (DS).ic — linia se scalează cu desenul (ce aveam înainte)În butoane — butonul deține mărimea iconului
În .btn iconul poartă doar .ic. Treapta butonului îi dă mărimea, exact cum îi dă și font-size — o regulă pe treaptă în bono-ds.css, nimic în markup. Două scări: lângă text iconul urmărește litera; singur în cerc (.icon-only) stă o treaptă mai sus, ca să umple constant ~45-53% din buton. scripts/check-icons.py pică pe un .ic.sm/.md/.lg pus într-un buton.
| Treaptă | Buton · text | Icon lângă text | Icon-only | Linie |
|---|---|---|---|---|
.btn.xs | 26px · 12px | 12 | 12 | 1.25px |
.btn.sm | 30px · 13px | 14 | 16 | 1.5px |
.btn | 40px · 14px | 16 | 18 | 1.5px · 1.75px |
.btn.lg | 44px · 16px | 20 | 20 | 1.75px |
Înainte de 2026-09-10 icon-only avea două valori (14 pe .xs/.sm, 18 pe implicit/.lg) — .xs citea aglomerat, .lg gol — iar butonul cu text nu-și dimensiona iconul deloc: un glif de 16px stătea și în 26, și în 44 de pixeli.
În context — culoarea vine din text
--c-warn-text de la textul alertei — nu are nevoie de o culoare proprie.Setul — assets/icons/
Doar glifele pe care le folosește sistemul. Lipsește una? O copiezi de pe lucide.dev în assets/icons/<nume>.svg, verbatim, și rulezi scripts/check-icons.py --write — grila de mai jos se regenerează singură. Nu se editează de mână.
arrow-leftarrow-rightbellboldbookcalendarcameracheckchevron-downchevron-leftchevron-rightcircle-alertcircle-arrow-rightcircle-question-markcircle-xclockcolumns-2compasscopycredit-carddatabasedownloadellipsiseyefilefile-textfile-upglobehouseinfoitaliclayerslayout-dashboardlayout-templatelog-inlog-outmailmenumessage-circlepencilplusreceiptrows-2savesearchsettingsshieldtext-align-centertext-align-endtext-align-starttrash-2triangle-alerttypeuploaduserxReguli
- Nu desena și nu edita o glifă. Fiecare icon e Lucide, copiat verbatim în
assets/icons/.scripts/check-icons.pypică pe orice<svg stroke="currentColor">care nu e o glifă vendorizată. - Nu regla grosimea din markup.
stroke-width="2"rămâne (valoarea Lucide); clasa de mărime o randează pe scara optică (1.25 → 2px pe ecran). Alt număr = cineva a încercat să repare local deriva pe care CSS-ul a rezolvat-o deja. - Nu dimensiona din atribute și nu pune o mărime în buton. Mărimea e o clasă din scară; în
.btniconul poartă doar.icși treapta butonului decide. Excepție: referințele-aligned, unde lint-ul #13 cere încăwidth/heightpe un SVG din<button>— acolo atributul oglindește clasa, nu o contrazice. - O singură grilă: 24. O cale desenată pe 16 sau 20 nu va sta niciodată pe aceeași mărime optică lângă una Lucide.
- O singură bibliotecă. Fără Heroicons / Feather / Material / Phosphor „doar pentru unul". Lucide are 1700+; dacă chiar lipsește, glifa se desenează pe grila și în stilul Lucide și intră ca schimbare de DS.
- Stroke, nu fill. Lucide e stroke-only; o formă umplută citește ca altă familie. Fill au doar punctul din chipul de status și steagurile din
.money-input— care nu sunt iconuri. - Culoarea nu e a iconului.
currentColoria culoarea textului de lângă el, deci tokenul-textal familiei. Iconurile de trust (lacăt, scut, ochi, semnătură) —--c-successsau neutru, niciodată brand. Pattern-ul complet:docs/foundation.md § Iconuri.