ACRM Design System — analýza stavu a plán přestavby na špičkový DS

Datum: 2. 9. 2026 · pro Štěpána (Art Director) · vzor kvality: atlassian.design Čísla jsou změřená (skripty v této session), ne odhadnutá. Zdroj appky = origin/main acrm (ne checkout /root/crm, který je 1 119 commitů pozadu).

0. Shrnutí

Diagnóza. To, čemu říkáme „kanon DS", je export z claude.ai/design: 97 HTML mockupů, tři paralelní kopie CSS a vlastní JavaScriptové „enginy", které znovu implementují obrazovky appky. Od exportu (9. 8.) se 35 z 36 komponentových karet nezměnilo, zatímco appka udělala 354 commitů do DS kódu. Tokeny naopak sedí (136 tokenů, shoda s tokens.css na mainu až na uvozovky). Pravda o komponentách dnes žije v kódu — @acrm/ui (39 komponent, typované props, 33 stories, 66 vizuálních snímků) a ds/*.css — a RULES §0.1 to už dnes říká: „zdroj pravdy je reálná appka, portuj z ní". DS web (fáze 1 z dneška) má správnou kostru, ale ukazuje zastaralé mockupy.

Cíl. DS na úrovni vzoru: rodiny komponent → podkomponenty, každá se stejnou anatomií stránky (Examples · Code · Usage · Accessibility · Changelog), příklady = živé komponenty z kódu s ukázkou kódu, props tabulky generované z typů, usage s Do/Don't, verzování a changelog, distribuce balíčkem do všech rep.

Cesta. Otočit zdroj pravdy na kód (packages/ui = komponenty + tokeny + stories + styly), DS repo = dokumentace + registr + web, HTML export → legacy/. Pět fází, měřitelné „hotovo" u každé komponenty, appka se konsoliduje ratchetem, distribuce balíčkem @acrm/ui místo zrcadel. Detail v §5–§8.


1. Současný stav — DS interně (/root/ds-export/extracted, repo acrm/design-system)

1.1 Obsah

PoložkaStavHodnocení
Karty97 HTML (95 s @dsCard), 91 v manifestu: 19 Foundations · 36 Components · 27 Screens · 8 Registrace · 1 Shell; 6 mimo manifestStruktura plochá, „karta" = mockup, ne dokumentace
Stáří35/36 Components karet netknuto od exportu 9. 8.; appka od té doby 354 commitů do packages/ui/src/components + apps/web/src/ds (RecordRail 10×, EntityPreview 9×, DealCard 7×, TaskList 5×, Dialog 3×…)Karty jsou snímek léta, ne pravda
Tokenycolors_and_type.css 136 tokenů vč. dark bloku = tokens.css na mainu (liší se jen uvozovky/mezery ve 4 hodnotách)✅ jediná vrstva, která sedí
Enginy _ds/18 CSS (2 497 ř.) + 14 JS (2 956 ř., segment-screen.js 52 KB) — vanilla JS, které kreslí obrazovky do mockupůDruhá implementace appky; nikdo ji nespouští v produktu
rt-real/11 souborů, 11 285 řádků zkopírovaného app CSSTřetí kopie téhož CSS
Kvalita mockupů1 857 inline style="", 836 použití app tříd .acrm-* smíchaných s vlastnímiMockupy nejsou strojově porovnatelné s appkou
Duplicity konceptuentity-ref ×3 karty, dialog ×6, taby ×3 (tabs, Record tabs (unified), Record tabs – handoff), výpisy ×3 (Record list, list-view, table-row), Person detail ×2Jeden vzor = víc karet → čtenář neví, která platí
Pracovní dokumenty jako karty„Tab system – plán sjednocení", „Record tabs – handoff", „Person detail – migrated (ukázka)", 3 karty „(návrh)"Kanon obsahuje ne-kanon
Balastuploads/ 20 MB (120 souborů), screenshots/ 1,5 MB (41), vnořený legacy bundle 972 KB, _zachraneno 1 MB~85 % objemu repa není DS
Jazyknázvy karet 69 EN / 22 CZ, skupina „Registrace", popisky CZNekonzistentní; web je EN
DokumentaceRULES.md (18 KB, silná pravidla: containment budget, jeden accent, App Shell master…), CONSOLIDATION.md, DS_UPDATE_CHECKLIST.md; popis karty = 1 věta až odstavec v @dsCard subtitle (medián 200 znaků, max 664)Pravidla existují, ale nejsou navázaná na komponenty; žádná per-komponentová dokumentace (kdy použít, props, kód, a11y)
Verzování / changeloggit až od 2. 9. 2026; před tím nicHistorie designových rozhodnutí je jen v paměti a v MR appky
Stavový životní cyklus„(návrh)" v názvu; jinak nic (kandidát/beta/kanon/zastaralé)Nelze rozlišit platné od rozpracovaného

1.2 Vazba na appku (měřeno ds:sync-check + porovnání souborů)

  • Zrcadlo v repu (packages/ui/reference/screens): 20 karet z kanonu chybí, 23 se liší, 8 enginů _ds/* se liší → zrcadlo je kurátorská, zastaralá podmnožina.
  • ds:sync-check (29 portů): 0 hodnotových driftů proti zrcadlu, ale 161 neadoptovaných selektorů (Person detail 82, segment-screen 22, app-shell 16), 85 chybějících, 148 schválených odchylek (ds-ok). Appka od karet vědomě odchází.

Závěr §1: Interní DS není systém, je to archiv designových záměrů z jedné epochy + tři kopie CSS. Tokeny a pravidla mají hodnotu; mockupy a enginy ne.


2. Současný stav — prezentace (:3777/ds, fáze 1 z 2. 9.)

Co jeStav
IAHome · Get started · Rules · Foundations (tokeny z CSS) · Components v 7 schválených kategoriích · Patterns · Adoption · Candidates · Changes; strom v levé navigaci; ⌘K hledání; EN UI ✅
Stránka komponenty4 taby (Examples · Usage · Code · Status); Examples = jeden iframe mockupu; Usage = subtitle + CSS komentáře; Code = import + třídy + port; Status = zrcadlo + kde se používá ✅ kostra
Chybí proti vzoruúroveň rodina → podkomponenta (Button → Icon button → Split button); příklady per stav s kódem; props tabulky; snippety; Accessibility; changelog a verze per komponenta; lozenge stavu (beta/GA/deprecated); dark-mode přepínač (tokeny ho mají, appka ho používá v 18 souborech); Content guidelines; Contributing; Release notes; obsah CZ/EN smíšený

Závěr §2: kostra webu je správná a stojí na tokenech; obsah, který ukazuje, je špatný (mockupy). Web musí číst z kódu.


3. Aplikace a reálná implementace kanonických komponent (origin/main)

3.1 Co existuje

VrstvaRozsahPoznámka
packages/ui (@acrm/ui)39 komponentových souborů, 8 050 řádků; exporty: Button, IconButton, Input, Textarea, Field, Select, MultiSelect, Combobox, RecordSelect, NavSelect, PickerMenu, Popover, Tooltip, Dialog, Confirm, DrawerForm/DrawerField, Segmented, Checkbox, TabStrip, DateField/TimeField/DateRangeField/DateTimeRangeField/Calendar/PickerPanel, RecordList, RecordRail/EditableField, TaskList, DealCard, Avatar, EntityRef, EntityPreview, EmptyState, ErrorState, Skeleton, Loader/ListLoader, DetailStateScreen, SectionTopBar, ds-iconsTypované props (ButtonProps: variant primary·default·ghost·danger, kbd, loading…) → props tabulky jdou generovat
Tokenytokens.css 310 ř., 136 tokenů, dark blok= kanon
Sdílené třídyds.css 2 808 ř., 457 selektorů .acrm-* (input, inputwrap, textarea, slider, radio, switch, optchip, taginput, rmchip, checkbox, segmented, select-trigger, popover, dialog 38 pravidel, tab(s), pill, count, avatar, dealcard, icobtn…)Kanonické primitivy jako třídy
Obrazovkové vrstvyds/*.css 73 souborů, 31 055 řádků; prefixy .sgb- 168 · .kalendar- 161 · .mr- 150 · .acc- 150 · .dp- 139 · .dlr- 138 · .rr- 131 · .aichat- 127 · .as- 122 · .pr- 113 · .au- 110 · .nastaveni- 109 · .pdr- 104 … (25+ prefixových systémů)Většina DS CSS je screen-specifická; enginy (record-rail, record-list, task-list, email-list, dialog-window, filter-bar, stat-tile, section-block, timeline, note-card, toast, notifications…) tu jsou, ale v appce, ne v balíčku → jiná repa je nemají
KatalogLadle: 11 story souborů, 33 stories; catalog:build existuje; vizuální CI: 66 snímků (33 × light/dark)Základ pro živé příklady; pokrytí ~1 story na komponentu, ne per stav
Brány CIds-validate = ds:validate:strict + ratchet (baseline 80 souborů: DIM 835 · TYPE 183 · TONE 12 · suppressed 361) + ds:index:check + ds:sync-check --check; visual (Ladle × Playwright); validate-ds-usage 11 pravidel (4 hard)Vynucování existuje a funguje — jen měří proti špatné referenci (zrcadlo)
DS index38 řádků: 35 OK · 2 ★ · 1 NÁVRH; 5 „app-only" (DrawerForm, Segmented, Empty/Error, DetailStateScreen, Skeleton) + řada komponent bez karty vůbec (Date rodina, Combobox, RecordSelect, MultiSelect, NavSelect, TabStrip, Loader, ListLoader)Kód je před DS

3.2 Dluh v appce

MetrikaHodnota
Inline style={{ v TSX1 250 ve 191 z 655 souborů
Hex barvy v TSX17
Schválené odchylky ds-ok462 v CSS + 84 v TSX = 546
Paralelní třídní systémy25+ prefixů; historicky 3 topbary (.sgb-top/.tbar/.acrm-page-head) — .sgb-top už migrován na SectionTopBar ✅
Komponenty bez story~½ exportů @acrm/ui (Date rodina, Combobox, MultiSelect, RecordSelect, Loader, TabStrip, SectionTopBar varianty…)
Distribuce@acrm/ui je private, main: ./src/index.ts — jiná repa ho nemohou nainstalovat; enginy CSS žijí v apps/webSdílení do jiných rep dnes technicky neexistuje

Závěr §3: appka má skutečný, typovaný, testovaný komponentový systém a brány. Chybí mu (a) rozdělení „balíček vs. obrazovky" — enginy jsou v appce, (b) pokrytí stories per stav, (c) dokumentace, (d) publikace. To jsou přesně věci, které špičkový DS web potřebuje jako vstup.


4. Rozdíl proti vzoru (atlassian.design)

OblastVzorMy dnesMezera
Zdroj pravdykód (@atlaskit/*), web z něj generovanýHTML export; kód odděleněotočit
HierarchieComponents › Button › {Button, Icon button, Link button, Link icon button, Split button, Button group}40 plochých karet v 7 kategoriíchrodiny + podkomponenty
Anatomie stránkyhlavička (název, věta, stav, balíček, odkazy: zdroj · npm · Figma · changelog) · taby Examples · Code · Usage · Accessibility · Changelog4 taby, bez props/a11y/changelogudoplnit + sjednotit
Examplespevný sled sekcí (Default · Appearance · Spacing · States · Icons · …), každý = živý render + přepínač kódu1 iframe mockupustories per sekce + snippet
Codeinstall/import, props tabulka (name · type · default · description) z typůimport + třídygenerátor z TS
UsageWhen to use · When not · Anatomy · Best practices (Do/Don't páry) · Content · Relatedsubtitlepsát (máme AD rulingy jako zdroj)
Accessibilityklávesnice, ARIA, kontrast per komponentanicpsát + testovat
Stav a verzelozenge (alpha/beta/GA/deprecated), semver balíčku, changelog per komponenta„(návrh)" v názvuživotní cyklus + changesets
Foundationstokeny s ukázkou, kopírování, dark✅ (od dneška)dark přepínač na webu
Patternssložené vzory s reálnými ukázkami27 ručních mockupůreálné screenshoty + kompozice
Distribucenpm balíčky, verze, migracezrcadlo HTML v repu + ruční portbalíček
PřispíváníContributing, RFC/kandidát, release phasescandidates/ (od dneška)proces + DoD

5. Cílová architektura

acrm/acrm (monorepo)                                   acrm/design-system (DS repo)
┌──────────────────────────────────┐                   ┌──────────────────────────────────────┐
│ packages/ui  = @acrm/ui          │  build artefakty  │ site/registry.json  (rodiny → pod-    │
│  ├ src/components  (39+)         │ ───────────────▶  │   komponenty → {react, třídy, stories,│
│  ├ src/tokens/tokens.css         │  • ladle static   │   status, since, docs})               │
│  ├ styles/*.css  (enginy z ds/)  │  • props.json     │ docs/<family>/<sub>.usage.md          │
│  ├ stories/**  (per podkomp.)    │  • tokens.css     │ docs/<family>/<sub>.a11y.md           │
│  └ CHANGELOG (changesets)        │  • git changelog  │ patterns/*.md + screenshoty devu      │
│ apps/web  = obrazovky (jen       │                   │ rules/*.md  (RULES rozdělený)         │
│   kompozice, žádný vlastní styl) │                   │ site/  (renderer :3777/ds, CSS)       │
│ CI: ds-validate · visual · ratchet│                   │ legacy/  (HTML export, read-only)     │
└──────────────────────────────────┘                   └──────────────────────────────────────┘
          │ publish @acrm/ui (GitLab package registry, semver)
          ▼
  jiná repa: `pnpm add @acrm/ui` — tokeny + komponenty + enginy; žádné zrcadlo, žádný ruční port

Principy

  1. Kód je pravda. Komponenta existuje, když má typovaný export v @acrm/ui (nebo kanonickou třídu v styles/), stories per stav a vizuální snímek. Mockup není důkaz.
  2. DS repo = dokumentace, registr, web. Nic, co by muselo být duplikátem kódu. Web vše ostatní generuje z artefaktů buildu.
  3. Jedna rodina = jedna stránka na podkomponentu, stejná anatomie. Registr (registry.json) je jediné místo, kde se definuje hierarchie a mapování na kód.
  4. Distribuce balíčkem. Zrcadla a ds:sync-check skončí; nahradí je verze balíčku + changelog + migrace.
  5. Export z claude.ai → legacy/. Zůstane čitelný jako historie záměru; není linkovaný jako kanon; nic z něj se neportuje bez rozhodnutí AD.

6. Taxonomie: rodiny → podkomponenty (návrh, ukotveno v kódu)

Legenda: ✅ v kódu (@acrm/ui / .acrm-*) · ◐ v kódu jen jako obrazovková vrstva ds/*.css · ◯ jen v mockupu (kandidát).

Forms & input

  1. Button — Button (primary · default · ghost · danger) ✅ · Icon button ✅ · Split button ◯ · Save button (dialer completion) ◐ · Kbd hint ✅
  2. Text field — Input (text · email · url · code · number · short) ✅ · Textarea ✅ · Field (label · hint · error) ✅ · Input with icon/kbd ✅ · Slider ✅ · Tag input ✅ · Mention input ◐
  3. Select — Select ✅ · Multi-select ✅ · Combobox ✅ · Record select ✅ · Nav select ✅ · Picker menu ✅
  4. Choice — Checkbox ✅ · Radio ✅ · Switch ✅ · Segmented control ✅ · Option chips ✅
  5. Date & time — Date field ✅ · Time field ✅ · Date range ✅ · Date-time range ✅ · Calendar ✅ · Picker panel ✅
  6. Filter — Filter bar ◐ · Filter chip ◐ · Removable chip ✅

Overlays & dialogs

  1. Dialog — Dialog (s · m · l) ✅ · Confirm ✅ · Window states (modeless · compact · min) ◐ · Drawer form ✅ · Record drawer ◐
  2. Popover — Popover ✅ · Tooltip ✅ · Entity preview ✅

Navigation

  1. App shell — Sidebar nav item ◐ · Top bar ◐ · Drawer slot ◐
  2. Section top bar — Section top bar ✅ · Title with entity tile ✅
  3. Tabs — Tab strip ✅ · Record tabs ◐

Records & data

  1. Record list ✅ · 13. Record rail — Rail ✅ · Key-value row ✅ · Editable field ✅ · Multi-value ◐ · 14. Table — Segment table ◐ · Table row ◐ · 15. Task list ✅ · 16. Email list ◐ · 17. Deal card ✅ · 18. Stat tile ◐ · 19. Section block ◐ · 20. Timeline ◐ · 21. Note card ◐

Identity

  1. Avatar — person · company × 16/24/32 ✅ · 23. Entity reference — default · mini · removable ✅ (jedna komponenta, 3 varianty — dnes 3 karty)

States & feedback

  1. Empty state ✅ · 25. Error state ✅ · 26. Loading — Skeleton line · Skeleton list · Loader · List loader · Detail state screen ✅ · 27. Toast ◐ · 28. Notifications ◐ · 29. Status — Pill · Count badge ✅

AI

  1. AI assistant ◐ · 31. Discussion ◯ (návrh)

Výsledek: 31 rodin, ~75 podkomponent; z toho ✅ 44, ◐ 27 (přesun ds/*.css → packages/ui/styles + story), ◯ 4 (kandidáti).


7. Anatomie stránky podkomponenty (pevná, generovaná z registru)

Components › Button › Icon button
Icon button   [canon ▾ since 0.3.0]   @acrm/ui · <IconButton>   Source · Story · Changelog
„Tlačítko, jehož význam nese ikona; vždy s tooltipem."
────────────────────────────────────────────────────────────────
 Examples │ Code │ Usage │ Accessibility │ Changelog
────────────────────────────────────────────────────────────────
Examples  = sekce v pevném pořadí per rodina: Default · Variants · Sizes · States (hover/focus/
            disabled/loading/selected) · With icon/kbd · Composition; každá = živý render (Ladle
            story v iframe) + přepínač „Code" se snippetem přesně té story.
Code      = install/import · Props (name · type · default · description — z TS typů) · CSS classes
            (kanonické třídy + tokeny, které komponenta používá) · Related.
Usage     = When to use · When not to use · Anatomy (očíslované části) · Best practices (Do / Don't
            páry s živým renderem) · Content (copy pravidla: sentence case, datum, částky…) · Related.
Accessibility = klávesnice · ARIA · fokus · kontrast (měřeno) · známé limity.
Changelog = commity mainu dotýkající se souborů komponenty + verze balíčku (changesets).
Vpravo: On this page · Implementation (verze, adopce per repo, počet použití).

Do/Don't a Content se plní z existujících AD rozhodnutí (RULES §0–§10, pilulky-střízlivost, tabular-nums jen tabulky, konvence roku, kompaktní částky, popisek = --label, nápověda = --hint, mono jen výkazy, žádný eyebrow v menu, FilterBar = Notion model…) — obsah už máme, jen je rozptýlený v paměti a MR.


8. Postup přestavby (fáze, DoD, odhad)

FázeObsahDoDOdhad
0 · Rozhodnutí + úklidschválit §5 architekturu a §6 taxonomii; HTML export → legacy/, balast (uploads/screenshots/legacy bundle) mimo repo; site/registry.json kostra (31 rodin, 75 podkomponent, EN názvy, stav); RULES rozdělit do rules/registr existuje, web ho čte, každá podkomponenta má stránku (byť prázdnou) se správným místem ve stromu2 dny
1 · Kód jako zdrojna FE boxu čistý klon origin/main (timer fetch); pnpm --filter @acrm/ui catalog:build → /ds/catalog/; generátor props.json z TS (TypeScript compiler API) a changelog.json z gitu; web: Examples = stories z registru, Code = props + import, Changelog = git; lozenge stavu; dark přepínačstránka Button rodiny je kompletní ze živého kódu; tokeny na webu z tokens.css mainu5 dní
2 · Pokrytí rodin (iterativně, rodina po rodině, každá = MR do acrm + MR do DS)per podkomponenta: stories per sekci (~5), vizuální snímek, usage.md (When/When not/Do–Don't/Content/Related), a11y.md, pravidlo do validate-ds-usage; ◐ položky = přesun CSS z apps/web/src/ds do packages/ui/styles + story„hotová komponenta" = 5 artefaktů (story · snímek · props · usage · a11y) + zelené brány; web ukazuje % pokrytí~1 rodina/den pro ✅, 2–3 dny pro ◐ → 6–8 týdnů pro 31 rodin
3 · Konsolidace appky (souběžně, ratchet)inline styly 1 250 → 0; ds-ok 546 → revize (odchylka = buď nová varianta v balíčku, nebo pryč); 25 prefixových systémů → obrazovky skládají jen z balíčku; duplicity (3 topbary hotovo, další: dialogy, pilulky, výpisy)ratchet baseline klesá každý týden; apps/web/src/ds obsahuje jen layout obrazovekprůběžně, 2–3 měsíce
4 · Distribuce@acrm/ui publikovat (GitLab package registry), semver + changesets, release notes na webu; konzumentská repa: pnpm add @acrm/ui, zrcadla a ds:sync-check zrušit; adoption matice z verzíjiné repo postaví obrazovku jen z balíčku, bez kopírování3 dny + migrace konzumentů
5 · Patterns & contentvzory obrazovek = reálné screenshoty devu (timer) + kompozice („z čeho je složeno"), 65 stránek → 4 skeletony (master šablony); Content guidelines (CZ copy); dark mode showcase; kandidátský proces jako RFC šablona; Figma až budePatterns bez ručních mockupů; každý vzor odkazuje na podkomponenty2 týdny

Pořadí: 0 → 1 → (2 ∥ 3) → 4 → 5. Fáze 2 je největší a jediná, kde se píše obsah — ten schvaluje AD po rodinách, ne najednou.


9. Governance

  • Role: Art Director (Štěpán) — schvaluje taxonomii, kanon, usage texty; DS maintainer (Claude/FE) — registr, generátory, web, brány; přispěvatel (kterýkoli tým) — MR do acrm (kód + story) a do DS (docs, kandidát).
  • Životní cyklus: candidate (MR v candidates/) → beta (v balíčku, bez záruky API) → canon (5 artefaktů, brány) → deprecated (náhrada + migrace v changelogu) → odstranění.
  • Definition of done komponenty: story per sekci · vizuální snímek light+dark · props doc z typů · usage.md · a11y.md · usage pravidlo ve validátoru · záznam v registru.
  • Pravidlo „kanon nahrazuje": nová varianta = stará mizí v témže MR (migrace), ne vedle sebe.
  • Metriky na webu (Adoption): % podkomponent s DoD · dluh appky (inline styly, ds-ok, prefixy) · verze balíčku per repo.

10. Co rozhodnout teď (jedno rozhodnutí)

Schválit §5 (zdroj pravdy = kód, DS repo = docs + registr + web, export → legacy/) a §6 (31 rodin / 75 podkomponent). Po schválení začnu fází 0 a 1 (Button rodina end-to-end jako pilot, ~1 týden). Názvy podkomponent, pořadí sekcí v Examples a texty usage se ladí na webu pickerem, rodina po rodině.

Source: docs/ANALYZA-a-PLAN-spickovy-DS.md · GitLab