# Pravidla projektu — Datamart & CRM ## 0. Jednoduchost především — „containment budget" (META-PRAVIDLO) **Tohle pravidlo je nad všemi ostatními.** Cílem není mít hodně prvků — cílem je mít **právě jeden, a ten perfektně vyladěný** (Apple/Attio). Méně rámečků = víc přehlednosti a prostoru. **Containment budget — maximálně 1 úroveň rámování.** Rám (okraj / pozadí / dlaždice) si MUSÍ zasloužit místo jako **skutečná hranice**: krok onboardingu, input, pravý preview panel, opravdový overlay. Jinak ne. - **Nikdy rámeček kvůli „uspořádání" seznamu.** Položky seskupuj **prostorem + hierarchií** (váha / barva / velikost), ne krabičkami. Seznam = ikona + text oddělený mezerou — **žádný okraj kolem každého řádku**. - **Ikona je ikona, ne dlaždice.** Žádné pozadí/okraj kolem ikony jen aby „seděla". Barevná ikona, hotovo. - **Zákaz „rámeček v rámečku v rámečku".** Když je obsah už uvnitř karty/zóny, jeho položky jsou ploché. **Proč to píšu (a proč se to opakovalo):** instinkt „seskup → zabal do boxu; ikona → na dlaždici" se vrací u každé nové obrazovky. DS dosud popisoval jen *slovník* (tokeny + jak nakreslit okraj), ne *gramatiku zdrženlivosti* (kdy okraj NEpřidat). Bez **viditelného anti-patternu** a bez **kontroly před publikací** ten habit vždycky vyhrál. Tahle sekce + DO/DON'T karta + checklist to mění z prózy na vynutitelnou bránu. **Povinná self-review PŘED publikací KAŽDÉ obrazovky:** 1. Spočítej úrovně zanoření (karta → zóna → položka → …). **>1 dekorativní rám = STOP a zploštit.** 2. U každého okraje/pozadí/dlaždice řekni jednou větou „jakou skutečnou hranici tvoří". Když to nejde → pryč. 3. „Šlo by to jen prostorem a hierarchií?" Pokud ano → udělej to tak. Referenční anti-pattern: karta **`Layout · Containment` (DO / DON'T)**. Referenční flat implementace: **`Registrace · Propojení Google`** + `_ds/auth.css`. ## 0.1 Portuj z reálné appky — NEimprovizuj (META-PRAVIDLO) **Zdroj pravdy je reálná appka `apps/web/src/`, ne obrázek před tebou.** Než postavíš nebo přestyluješ JAKÝKOLIV prvek (dialog, picker, ovládací prvek, karta, seznam, tabulka), **nejdřív prohledej appku**: - `apps/web/src/components/*.tsx` + balíček `@acrm/ui` (komponenty), `apps/web/src/ds.css` (sdílené `.acrm-*` třídy) a `apps/web/src/ds/*.css` (screen vrstvy), tokeny v `packages/ui/src/tokens/tokens.css`. Grepuj podle názvu funkce (`SaveSegment`, `IconPicker`, `seg-ic`, `dlg-`, `segpick`…). **Když kanonická implementace existuje → portuj ji 1:1** do bundle: stejné názvy tříd, stejné velikosti, stejná paleta (**tokeny / tone-třídy, NIKDY natvrdo hex**), stejná struktura i chování. CSS zkopíruj doslova ze zdrojové vrstvy (`ds.css` / `ds/*.css`). **Zakázáno:** paralelní třídní systém (`.ssg-*`, ad-hoc hex, vlastní velikosti) pro něco, co appka už řeší; natvrdo barvy tam, kde jsou `--ic-*` / pill tóny / tone-třídy; velikost dlaždice „od oka" (segment tile = 20 px v navigaci/Home, 40 px editovatelný picker trigger v save dialogu). Teprve když v appce NIC není, navrhuj nově — i tak s DS tokeny a nejbližším existujícím vzorem. **Krok „prohledej appku jako první" je povinný a jde PŘED prvním řádkem kódu.** (Doloženo: Save dialog jsem improvizoval místo portu `save-segment-dialog.tsx` + `segment-icon-picker.tsx` → muselo se zahodit.) ## 1. App Shell je MASTER pro všechny obrazovky (bez výjimky) **Pravidlo.** App Shell (`_ds/app-shell.js` + `_ds/app-shell.css`, komponenta `DS.AppShell`) je jediná master šablona aplikačního rámu. **Každá obrazovka, kterou aplikace obsahuje, se vykresluje skrz `DS.AppShell`** — topbar (logo · přepínač Datamart/CRM · hledání · notifikace · účet) a levou navigaci nesmí žádná obrazovka kreslit sama. Strukturální změna v App Shell se musí promítnout do všech obrazovek automaticky. **Jak to dodržet:** - Obrazovka renderuje `{obsah}` a do `DS.AppShell` vkládá pouze svůj **obsah** (centrální plocha) a případně `drawer` (pravý náhledový panel). - Sdílené obrazovkové enginy jdou taky přes shell: - `DS.SegmentScreen` (tabulky Lidé/Firmy, Průvodci) vykresluje obsah do `DS.AppShell` (viz `_ds/segment-screen.js`). - `DS.PersonDetail` (detail osoby) vykresluje do `DS.AppShell` (viz `_ds/person-detail.js`). - Žádné lokální `gbar` / `sidebar` / `pd-gbar` rámy v jednotlivých souborech. Každá obrazovka musí načíst `_ds/app-shell.css` + `_ds/app-shell.js`. - Drawery (record / preview) se dokují do slotu `.as-drawer` shellu — elevaci (stín) určuje **jen** slot, jednotlivé drawery vlastní stín nemají. **Hranice pojmu „obrazovka".** Obrazovka = navigovatelný pohled aplikace (Domů, Pipeline, Lidé, Firmy, Company/Deal/Person drawer, Person detail, Průvodci). Referenční katalogy stavů a komponent (Prázdné stavy, Chybové stavy, Loading, Notifikace, Toasty) **nejsou** obrazovky — dokumentují stavební prvky v izolovaných rámech; samotné stavy (loading/empty/error) se v reálných obrazovkách už dnes zobrazují uvnitř shellu. > **Výjimka — plnoplošné brány mimo shell.** Registrace / login / onboarding a > podobné fokusní brány (před vstupem do aplikace) shell NEpoužívají; řídí se > pravidlem 4 (čisté plochy). Vše ostatní jde přes shell. ## 2. Bonita — barvy odvozuj z ratingu (DS tokeny) Barva bonity se **odvozuje z písmena ratingu**, nikdy se nezapisuje natvrdo u dat. Kanonická mapa (zdroj pravdy: `DS.SegData.BONITA_BANDS`): | Tón (DS token) | Ratingy | |---|---| | `green` (`--bonita-green`) | AAA, AA | | `lime` (`--bonita-lime`) | A, BBB | | `amber` (`--bonita-amber`) | BB, B | | `rose` (`--bonita-rose`) | CCC, CC, C | | `grey` (`--bonita-grey`) | D | Helper: `DS.gradeTone(grade)` (v `_ds/segment-screen.js`). Vizuál = tlumená „pill" `.grade ` (světlé pozadí + barevný text z DS tokenů) — stejně v tabulkách, scale i detailech. ## 3. Avatary — DS styl (hashHue) Avatary používají DS treatment: světlé pozadí `--surface-75`, 1.5px barevný okraj a barevný iniciál z `hsl(var(--av-hue) …)`, kde `--av-hue = hashHue(jméno)`. Kruh pro osoby, zaoblený čtverec pro firmy. Žádné plné syté pozadí s bílým iniciálem. ## 4. Čisté plochy — bílé pozadí, tenký rámeček, vzdušné (Attio) Fokusní plochy mimo aplikační shell (přihlášení, registrace, onboarding kroky, dialogy) musí působit **čistě a vzdušně jako Attio**: - **Pozadí = bílá** (`--surface-100`). Šedý `--shell-bg` je vyhrazen JEN pro aplikační rám (topbar + sidebar), nikdy pod fokusní obsah. - **Každý krok ohranič tenkým jemným rámečkem** — `1px solid var(--border)`, `--radius-xl`, **velký a vzdušný** (štědrý padding). Přesně jako kroky onboardingu v Attio. (Tohle Štěpán chtěl — rámeček ano, jen tenký a bez stínu.) - **Žádný stín — vůbec.** Rámeček = jen tenká linka (`box-shadow: none`). Drop-shadow (`--shadow-pop`) patří **jen** skutečným **overlayům** (pop-upy, menu, drawery), nikdy fokusním kartám. - Vzdušnost přes DS spacing (`--sp-*`): štědré mezery, méně prvků, restraint (Apple/Attio). Hierarchie váhou + barvou. - Vnitřní prvky (inputy, řádky zdrojů, preview panely) mají jemný hairline `--border` nebo tlumené pozadí `--surface-75`. Referenční implementace: `_ds/auth.css` (`.au-card`) + karty `Registrace · *`. ## 5. Tlačítka — vždy DS tlačítko v jeho definované velikosti Tlačítka jsou **jediná DS komponenta** (`Components · Buttons`): kanonická třída `.acrm-btn` v `apps/web/src/ds.css` (`.btn` je alias), v Reactu ji emituje `@acrm/ui` `