Shell & layout
Un singur breakpoint în tot DS-ul: 1024px. Sub el — layout mobil: o coloană, sidebar absent, două shell-uri — .app-mobile (produs: header voalat + .tabbar) și .flow-chrome (fluxuri). De la el în sus — layout desktop: .app-shell cu sidebar opțional (rail fix, în afara grilei) și .layout-12, grila de 12 coloane capată la 1440px — lățimea canvasului pe care se desenează, deci layout-ul nu se întinde peste ce a fost văzut la design.
Markup canonic · components/foundation-layout.json
Conținut principal
Breakpoint unic — 1024px
Nu există prag intermediar. Tabletele intră în banda mobile: același shell, aceleași reguli, doar coloana se centrează. Valoarea trăiește în tokenul --bp-desktop; în @media se scrie literal (custom properties nu funcționează în media queries).
Redimensionează fereastra peste / sub 1024px — indicatorul de mai sus reflectă banda reală, nu o simulare.
O coloană, sidebar ascuns. Două shell-uri: ecranele de produs stau în .app-mobile — .app-mobile-top sus, .tabbar jos (App navigation, Header); fluxurile în .flow-chrome — bară sus (back · titlu · meniu), CTA jos. Coloana e fluidă până la --flow-max (560px), apoi centrată.
Sidebar opțional (rail 240px / 64px icon-only) + .layout-12. Cele 12 coloane trăiesc în zona de conținut, capate la --layout-max și centrate. Fluxurile folosesc .app-footer.
Tokens
--bp-desktop 1024px /* SINGURUL breakpoint din DS */ --layout-max 1440px /* lățimea canvasului de design · peste atât grila se lipește de rail (centrată doar fără sidebar) */ --layout-pad 32px /* gutter exterior desktop */ --layout-pad-mob 20px /* gutter exterior mobile */ --grid-cols 12 /* coloane pe desktop — cu sau fără sidebar */ --grid-gutter 24px /* gutter între coloane */ --sidebar-w 240px /* sidebar full — rail fix, în afara grilei */ --sidebar-w-icon 64px /* sidebar icon-only */ --flow-max 560px /* lățimea coloanei .flow-chrome în banda mobile */
--layout-max e lățimea canvasului de design: 1440px. Pe full HD zona de conținut de lângă rail e mai lată (1920 − 240 = 1680), deci grila se oprește la 1440, lipită de rail — cei 240px rămași cad în dreapta și devin aer, nu coloane. Cu railul icon-only: 1920 − 64 = 1856, 416px aer în dreapta.
1920 viewport 240 rail sidebar 1680 zona de conținut (mai lată decât capul) 0 aer stânga (grila e lipită de rail) 1440 grila = --layout-max 32 --layout-pad stânga 1376 cele 12 coloane + 11 gutters 264 --grid-gutter × 11 92.67 o coloană = (1376 − 264) / 12 32 --layout-pad dreapta 240 aer dreapta = 1680 − 1440
Grila de 12 coloane · .layout-12 + .col-*
Spanurile .col-1….col-12 se aplică doar peste breakpoint. Sub 1024px grila are o singură coloană și fiecare copil ocupă toată lățimea — fără clase suplimentare, fără variante mobile de span.
Shell cu sidebar — .app-shell
Sidebar-ul e un rail fix în afara grilei — nu consumă coloane. Grid-ul părinte îi măsoară lățimea cu :has(): 240px default, 64px pentru .icon-only. Sub breakpoint dispare (display:none) și shell-ul rămâne o coloană. Conținutul are padding egal stânga/dreapta (--layout-pad) — aceeași respirație spre rail și spre marginea opusă. Peste cap-ul de 1440px grila rămâne lipită de rail și aerul cade în dreapta; se centrează doar în shell-ul fără sidebar.
Shell cu rail icon-only — .sidebar.icon-only
Același shell, alt rail: 64px, măsurat tot cu :has(). Grila rămâne lipită de rail, iar etichetele meniului (.sidebar-label) apar ca tooltip la dreapta railului, la hover și la focus — treci cu mouse-ul peste iconuri. Railul icon-only nu scrollează. Markup-ul complet și regulile railului → templates/sidebar.html.
Shell fără sidebar — aceleași 12 coloane
Sidebar-ul e opțional. Fără el nu se schimbă nici numărul de coloane, nici spanurile — doar lățimea disponibilă. O pagină nu are nevoie de un al doilea set de reguli ca să meargă în ambele ipostaze.
Lățimi
| Ce | Valoare | Note |
|---|---|---|
| Layout funcțional desktop | max 1440px | lățimea canvasului de design — grila se oprește acolo, lipită de rail (centrată doar fără sidebar); fundalul curge la edge |
| Coloană de citit / document | max 800px | lizibilitate — vezi docs/layout.md |
| Coloană mobile (flow chrome) | max 560px | --flow-max; fluidă sub, centrată peste |
| Sidebar | 240px / 64px | rail fix, în afara grilei |
Reguli ferme
- Un singur breakpoint: 1024px. Nu se adaugă praguri intermediare („tablet" la 768px). Dacă un layout pare să aibă nevoie de unul, problema e layout-ul.
- Sub 1024px = mobile complet — o coloană, sidebar absent. Nu un desktop strâns.
- Două shell-uri pe mobil, după ce e ecranul — produs (acasă, liste, setări, detalii) în
.app-mobile:.app-mobile-scroll+.app-mobile-top+.tabbar(+.mobile-menu); flux (wizard, semnare, onboarding) în.flow-chrome. Un ecran de detaliu e.app-mobile.no-barcu header-ul.detail. Nu le combina. - Insetele de sistem stau pe shell —
--safe-top/--safe-bottomsunt declarate pe.app-mobileși.flow-chrome(nu în:root); paginile de referință le simulează cu valori fixe pe ramă. - Sidebar-ul nu consumă coloane — rail fix în afara grilei. Cele 12 coloane sunt aceleași cu și fără el.
- Respirație egală, grilă lipită de rail — padding
--layout-padidentic spre sidebar și spre marginea opusă; peste 1440px grila stă lipită de rail și aerul cade în dreapta (centrare doar fără sidebar). Cu panou lateral dreapta (ex: ticker-ul Dublin), panoul nu are padding stânga propriu — golul vine din padding-ul coloanei, deci rail → conținut = conținut → panou. - Spanurile există doar peste breakpoint — sub el, fiecare copil e full width automat.
- Nicio grilă ad-hoc —
grid-template-columns: repeat(3, 1fr)pe o secțiune e drift; compune cu.col-*. - Conținutul funcțional nu trece de 1440px (lățimea canvasului de design) — peste atât grila se oprește, lipită de rail sau centrată fără sidebar; fundalul face bleed la edge.
DON'T
@media (min-width: 768px)— breakpoint inexistent în DS. Singurele forme corecte:min-width: 1024pxșimax-width: 1023.98px..flow-chrome/.app-mobilepeste 1024px sau.app-footer/.sidebarsub — regula e bidirecțională, vezicomponents/flow-chrome.htmlșicomponents/app-nav.html..tabbarîntr-un.flow-chrome, sau.flow-barpe un ecran de produs — fiecare shell își are chrome-ul.- Sidebar pus în grilă (ex.
.col-3pe<nav class="sidebar">) — railul stă în afara celor 12 coloane. - Panou lateral dreapta cu padding stânga propriu — dublează golul (32 + n) și strică respirația egală; golul vine exclusiv din padding-ul coloanei de conținut.
- Grilă centrată cu
margin: autopropriu lângă un rail — la 1920px, lângă railulicon-only, asta lasă 208px de gol între rail și conținut; centrarea e a shell-ului fără sidebar. - Un al doilea set de spanuri „pentru mobile" — sub breakpoint nu există coloane de împărțit.