Inventura nativních <button> v apps/web/src — matice A/B/C

Zdroj: node /root/.claude/jobs/d1322dc8/tmp/raw-buttons-full.mjs — 480 <button>, 192 unikátních klíčů tříd, 539 souborů. Referenční kanon pro posouzení vizuální změny (vše apps/web/src/):

  • .acrm-btn (ds.css:1136): výška --control-h=30px, padding 0 var(--sp-4)=12px, border 1px transparent, radius --radius-sm=8px, font 500 13px sans. Varianty primary/default/ghost/danger (ds.css:1157-1201). .icon (ds.css:1202): width=30px, padding 0.
  • .acrm-btn.compact (ds/button.css:13): výška --control-h-sm=24px, padding 0 var(--sp-3)=8px, gap --sp-2=6px, font --small=500 12px. Ikona 14px (--ico-xs). .compact.icon: width --sp-6=24px, padding 0.
  • .acrm-icobtn (ds.css:205): 30×30 (--control-h), radius 8px, bg transparent, barva --fg-secondary (--ink-500), hover --hover-surface, active/open --active-surface, disabled opacity .5. .sm (ds.css:241): 24×24 (--control-h-sm).
  • .acrm-icobtn.framed (ds.css:249): 32px šířka (pevná, size se neuplatní), border 1px --border-strong, bg --surface-100, shadow-xs, barva --ink-700, hover bg --surface-75.
  • Tokeny: --radius-md=11px, --sp-2=6px, --sp-3=8px, --sp-4=12px, --sp-6=24px, --field-h=32px, --ico-xs=14px, --ico-sm=16px, --surface-75 #fbfbfb/#161719, --surface-100 #fff/#1b1c1f, --ink-700 #303135/#cccdd1 (packages/ui/src/tokens/tokens.css).

Klasifikace: A — samostatné akční tlačítko re-implementované vlastním stylem (cíl <Button>/ <IconButton>); B — součást kanonického primitivu (menu/popover item, chip, tab, řádek, disclosure, kalendářní buňka, rich-text toggle…), žádná akce potřebná; C — nejasné, patří na stůl Art Directora.

Metodická poznámka: inventura je regex nad literálním textem <button, takže občas zachytí i citaci <button> uvnitř českého JSDoc komentáře (viz sekce „(bez třídy)" níže) a u dynamických className={...} výrazů vytáhne jen první token výrazu, ne skutečnou třídu — u těch je nutné přečíst JSX a dohledat reálnou třídu (např. klíč chip je ve skutečnosti tk-chip/fl-in, klíč entity/dedup je segmentovaný přepínač .acrm-segmented).


A — samostatné akční tlačítko re-implementované (45 tříd)

TřídaPočetUmístění (file:line)CSS pravidloNavrhovaný cílVizuální změna
pdr-ico9drawer/RecordDrawer.tsx:242,275,310,313,340; pages/BankaPage.tsx:323; DochazkaPage.tsx:539; DokumentyPage.tsx:107; RozpoctyPage.tsx:273ds/record-drawer.css:55-72<IconButton icon="…">ano — barva --fg-muted místo --fg-secondary, disabled opacity .35 místo .5
aichat-act5components/assistant/AssistantChat.tsx:388,398,408,421; mail/compose/AiThreadPane.tsx:221ds/ai-chat.css:205-224<IconButton size="sm">malá — barva --fg-muted v klidu místo --fg-secondary (rozměr 24×24 sedí)
gsp-cancel2GlobalSearch.tsx:1638; deal/DealSubjectStep.tsx:221ds/global-search.css:551-559<Button variant="ghost" compact>ano — žádná fixní výška (jen padding) vs. compact 24px
gsp-back2GlobalSearch.tsx:1664; search/AnswerPane.tsx:107ds/global-search.css:570-584<Button variant="ghost"> s ikonouano — má vlastní border-bottom (hlavičkový řádek), Button ho nemá
toast-x2GoogleConnectBanner.tsx:54; notifications/ToastProvider.tsx:177ds/toast.css:108-124<IconButton icon="x" size="sm">ano — 22×22 neodpovídá žádné DS velikosti (24/30)
aichat-prompt-act2assistant/AssistantPrompts.tsx:498,507ds/ai-chat.css:814-826<IconButton>ano — 28px není ani sm(24) ani default(30)
acrm-bulkbar-act2bulk/BulkActionBar.tsx:119,132components/bulk/bulk-bar.css:83-112<Button variant="ghost"> / variant="danger"ano — výška 34px (Button 30/24), font-weight 550 vlastní
gsp-act2global-search/PaletteResultsColumn.tsx:381,384ds/global-search.css:236-246<Button variant="default">ne — hodnoty 1:1 s .acrm-btn.default
wf-parbtn2products/PricingSections.tsx:376,435ds/orders.css:198-217<Button variant="default"> (chybí „pressed/on" tón)ne pro klid; ano pro .on (žlutý accent, Button pressed nemá)
tbar-mark2CompanyRecordPage.tsx:2579; PersonRecordPage.tsx:1359ds.css:2582-2596<IconButton icon="star" size="sm">ano — hit-box ~26px, focus box-shadow místo outline
pr-ico2DocumentDetailPage.tsx:325; PortfolioBuilderPage.tsx:687ds/person-record.css:40-55<IconButton icon="…">malá — barva --fg-muted vs --fg-secondary
fin-cash-doc2PokladnaDetailPage.tsx:416,441ds/finance.css:218-230<IconButton icon="receipt" variant="framed">ano — 26×26 s borderem vs framed pevných 32px
col-new1components/Board.tsx:215ds/board.css:98<Button variant="ghost" className="w-full">ano — výška 34 vs 30, radius-md vs radius-sm, font display 600/12 vs sans 500/13
fb-add1components/FilterBar.tsx:504ds/filter-bar.css:146<Button variant="ghost">ano — radius-md vs radius-sm, padding 10px vs 12px, font 12 vs 13
fb-reset1components/FilterBar.tsx:517ds/filter-bar.css:147<Button variant="ghost">ano — stejně jako fb-add (sdílené pravidlo)
sigpad-clear1components/SignaturePad.tsx:89ds/signature-pad.css:35<Button variant="ghost" compact>ano — bez pevné výšky, font-weight 600/12, hover mění barvu textu místo pozadí
file-menu1components/SubjectFilesTab.tsx:185ds/person-record.css:617<IconButton icon="dots-vertical" size="sm">ano, drobně — 26×26 vs 24×24
aichat-slash1assistant/AssistantChat.tsx:740ds/ai-chat.css:609<IconButton icon="slash" variant="framed">ano — 24px vs framed pevných 32px (framed nemá size)
aichat-send1assistant/AssistantChat.tsx:757ds/ai-chat.css:474<Button variant="primary" className="icon">ano jen v disabled stavu — vlastní surface-75/border-strong/fg-muted vs pouhé opacity .5; klidový/hover stav sedí 1:1
aichat-thread-more1assistant/AssistantThreads.tsx:144ds/ai-chat.css:537<IconButton icon="dots-vertical" size="sm">ano — 26×26 vs 24×24
acrm-bulkbar-link1bulk/BulkActionBar.tsx:113components/bulk/bulk-bar.css:61<Button variant="ghost" compact>ano — bez pevné výšky, barva accent vs fg
acrm-bulkbar-close1bulk/BulkActionBar.tsx:165components/bulk/bulk-bar.css:116<IconButton icon="x">ne/minimálně — 30×30 = --control-h sedí; hover color-mix(fg 7%) vs token --hover-surface, vizuálně blízké
fl-copy1calendar/EditMeetingForm.tsx:713ds/dialog-formless.css:224<IconButton icon="copy" size="sm">ano — radius-xs vs radius-sm, barva fg-muted vs fg-secondary
cell-add1calendar/MonthGrid.tsx:214ds/calendar.css:356<IconButton icon="plus" variant="framed" size="sm">ano — 20px neodpovídá framed (32px) ani žádné jiné DS velikosti
itm-add1deal/deal-parts.tsx:129ds/person-record.css:1316<Button variant="ghost">ano — výška 32 vs 30, barva fg-secondary vs fg
mc-fundx1mail/compose/PortfolioFields.tsx:204components/mail/mail.css:626<IconButton icon="x" size="sm">ano, drobně — 26 vs 24 (komentář: „1:1 z .rowx")
dismiss1meetings/CrmChangesBlock.tsx:142ds/task-list.css:421,441<IconButton icon="x" variant="framed" size="sm">ano — framed pevných 32px vs 24px, vlastní bordered vzhled
approve1meetings/CrmChangesBlock.tsx:150ds/task-list.css:421,445<Button variant="primary" compact className="icon">minimální — 24px = compact shoda, jen padding/font-weight drobně jiné
npanel-link1notifications/NotifBell.tsx:312ds/notifications.css:84<Button variant="ghost" compact>ano — bez pevné výšky, barva accent vs fg
npanel-ico1notifications/NotifBell.tsx:315ds/notifications.css:97<IconButton icon="x" size="sm">ano — 28×28 vs 24×24
all1notifications/NotifBell.tsx:367ds/notifications.css:295<Button variant="ghost" className="w-full">ano — výška 34 vs 30, radius-md vs radius-sm, barva accent vs fg
icobtn1notifications/NotifBell.tsx:456ds/app-shell.css:227<IconButton icon="bell">ano — šířka --field-h=32px vs 30/24, radius-md vs radius-sm
ac-clear1segment/SegmentBuilder.tsx:210ds/segment-screen.css:909<IconButton icon="x" size="sm">ano — 28px šířka vs 24, bez pevné výšky
sgb-clearall1segment/SegmentBuilder.tsx:1044ds/segment-screen.css:1069<Button variant="ghost" compact>ano — žádný border/výška/hover nyní
sgb-th-kebab1segment/SegmentScreen.tsx:905ds/segment-screen.css:486<IconButton icon="dots-vertical">ano — 20×20 vs 24/30, navíc vlastní hover-reveal (opacity 0→1)
sgb-ctl1segment/SegmentScreen.tsx:1592ds/segment-screen.css:244<Button variant="default">ano — radius-md vs radius-sm, font 12 vs 13, padding 8 vs 12
cd-ai-send1pages/CrmDashboardPage.tsx:125ds/crm-dashboard.css:98<IconButton icon="arrow-up">ano — klidové pozadí accent-tint a plný accent na hover (IconButton má transparent/hover-surface)
cd-ctl1pages/CrmDashboardPage.tsx:477ds/crm-dashboard.css:157<IconButton icon="dots-vertical" size="sm">ne — 24×24, radius-sm, hover-surface sedí
fx1pages/ImportPage.tsx:623ds/import.css:258<IconButton icon="x" variant="framed">ano, drobně — 30px vs framed pevných 32px
rowx1pages/ObchodDetailPage.tsx:555ds/person-record.css:1291<IconButton icon="x" size="sm">ano, drobně — 26×26 vs 24×24
set-back1pages/settings/SettingsLayout.tsx:227ds/settings.css:113<IconButton icon="arrow-left" size="sm">ano — 26×26 vs 24×24, hover --active-surface místo --hover-surface
set-help1pages/settings/SettingsLayout.tsx:310ds/settings.css:208<Button variant="ghost" compact>ano — bez pevné výšky, padding sp-1/sp-2 vs sp-3, barva fg-secondary vs fg
as-navtoggle1components/AppShell.tsx:292ds/responsive.css:22-36<IconButton icon="menu-2">ano — 32×32/radius-md vs 30(24 sm)/radius-sm; záměrně zarovnáno na --field-h k vyhledávání
as-icobtn1components/AppShell.tsx:359ds/app-shell.css:184-202<IconButton icon="…">ano — stejný důvod jako as-navtoggle (--field-h/radius-md)

Dvě položky navíc potřebují variantu, kterou <Button> dnes nenabízí: dlr-dial (zelený „positive" tón, viz sekci C) a wf-parbtn (pressed/„on" tón) — wf-parbtn je zařazen sem do A, protože klidový stav sedí a jen .on chybí.

B — součást kanonického primitivu (128 tříd)

Popover/menu/option řádek (kanon .acrm-popover-item, ds.css:1963, a příbuzné option-row rodiny): acrm-popover-item (93), acrm-optchip (12, inputs.css:790), acrm-recordselect-opt (9, inputs.css:538), acrm-recordselect-trigger (1, inputs.css:437 — vzhled inputu/kombobox, ne tlačítka), fb-opt (9, filter-bar.css:260), fb-clear (1, filter-bar.css:338 — „kanon dropdownu, řádek 32px jako .acrm-popover-item"), rcpt-opt (2, option řádek příjemce v mail menu), phe-ccrow (2, multi-value.css:178, „1:1 z DS Multi-value editor"), phe-cc (1, multi-value.css:145, spouštěč DialCodePicker), segpick-trigger/segpick-tone/segpick-ic (3, .segpick popover primitiv), o (1) / seg (1) / seg2 (1) / speakerFilter (2) / unreadOnly (2) / dedup (2) — volby v .acrm-segmented skupině (dedup má lokální pill-segmented, ale bucket B jako option).

Chip primitivy (kanonická rodina .tk-chip/.acrm-pill): tk-chip (7, task-dialog.css:158), tchip (6, „kanon Section top bar chip", ds.css:2632), acrm-tag-x (5, inputs.css:940, odstraňovací glyf uvnitř tagu), add-ref (3, dialog-formless.css:392), fb-chip (3, filter-bar.css:39), acrm-fchip-x (3, inputs.css:1001), acrm-rmchip-x (1) / acrm-rmchip-add (1) — demo kanonu na /ds/inputs, pipe-btn (1, kanonický pipeline selector), dlr-chip (2, dialer.css:290, option chip produktů — stejná rodina jako acrm-optchip), chip (1, dynamický klíč → skutečná třída tk-chip, meetings/reminder-select.tsx:50), chip-morph-hit (1, chip-morph.css:36, klikací plocha uvnitř ChipMorph řady), x (2, remove-× v .acrm-pill/.chip), tk-id (1) / wf-id (2) — kopírovací mono-chip afordance, acrm-pill (1, přímé použití kanonické třídy .acrm-pill, ds.css:962), ord-tier (1, orders.css:78 — výběrová dlaždice cenové úrovně, radio-card vzor, ne akce).

Tabs/segmenty/toggly: npanel-tab (2, notifications.css:124, pill tab), sgb-tab (1), eml-tab (2, tablist e-mailového listu), ctype-sw (2) / ctype-main (1, calendar.css:1578-1592, barevný radio přepínač / řádek typu se sourozencem kebab), cal-row (2, checkbox řádek filtru), mgt-cell (2, „button musí vypadat jako obsah tabulky, ne jako tlačítko", merge-table.css:132), sgb-grade (2, „bonita rating ladder — clickable tag toggles"), on (2) / b (1) / i (1) / s (1) — rich-text toolbar toggle v .nt-bub (note-dialog.css:255-285), re-tb (1, mail.css:1126, rich-text toolbar toggle composeru), tl-state (1, task-list.css:220, stavový glyf-přepínač bez rámečku uvnitř řádku úkolu).

Řádky výpisů/karet (row-as-whole nebo title-in-row): cls (2, jádro ItemList.Row), rr-row (1), pr-seg (1, nav-item vzor), sr-hl-row (1, „klikatelný řádek je skutečné <button>"), acc-cls-row (1), jrn-account (1), rooms-room (1, rooms.css:24, „hairline list, žádný box per řádek"), acrm-row (1, přímo kanonická třída), atl-txt (1, DuplicatesPanel.tsx:154, inline-reset — celý název/podnadpis řádku je proklik), mt-sum (1) / mt-hd-main (1) / mt-older (1) — thread.css:92, 180, 260, celé řádky karty zprávy, aichat-mail-row (1) / aichat-mail-foot (1), tl-meeting (1, settings.css:971, translucentní blok schůzky na timeline docházky — vizualizace, ne tlačítko), ptsk-state (1) / ptsk-name (1) — ItemList.Row reset uvnitř ProjectTaskRow, pl-name (1) / pl-val (1) / pl-more (2) — key-value row procesu, stat-stage (1) / cd-ai-model (1) / sgb-sum (2) — PickerMenu-trigger stejné rodiny, hs-drill (1, dialer.css:775, „afordance, ne odkaz pryč" manažerský drill-down), vat-sub-sha (1, accounting.css:814, „kánon kopírovatelné hodnoty, ne tlačítko"), nitem-t (1) / nitem-link (1) — notifications.css:205-244, textová část/odkaz uvnitř položky zvonečku, set-item (1, settings.css:181, položka postranního menu Nastavení — vzor Attio), tmore (1, timeline.css:634, textový odkaz „další" v agregované buňce, stejná rodina jako mr-reclink/hs-drill), prj-msblk-date (1, project-milestones.css:183, tichý spouštěč inline DateField uvnitř řádku milníku).

Kalendář: cwk-allday-ev (2) / cwk-allday-more (2) — kanonický pár celodenních čipů, dp-day (1) / dp-clear (2) / dp-addtime (1) / dp-open (1) — kanonický DatePicker, cell-tasks (1, calendar.css:883, „stejný vzor jako .cwk-allday-more/.more") / more (1, calendar.css:862, kanonický pár s .cwk-allday-more), mb-sd (1, mobilní týdenní pruh), prev (1) / today (1) — AD-schválená výjimka z rodiny Button (ACRM-91/97/103, 27. 9. 2026).

Grafy/vizualizace: sr-ch-mark-btn (1, sales-reports.css:268, značka události pod osou grafu — chart marker, ne UI akce).

AppShell/topbar (nav rail): as-row (1) / as-grp (1) / as-row-chev (1) / as-sub-chev (1) — app-shell.css:311-663, řádky/skupiny navigačního stromu.

FilterBar: fb-conj (1, filter-bar.css:97, logická spojka and/or mezi filtr-chipy, ACRM-50 — bespoke primitiv, ne Button).

**Formless dialog (.fl-*):** fl-in (10) / fl-when (2) — hodnotové řádky, fl-conflict (1, dialog-formless.css:813, značka konfliktu uvnitř .fl-in řádku).

Multi-value editor: rr-ev-tx (2, multi-value.css, telefonní hodnota jako link v RecordRail).

AI chat/asistent: aichat-fup (2, řádek návrhu navazující otázky), aichat-tools-t (1, ai-chat.css:55, boxless textový toggle „ukázat stopu nástrojů"), aichat-ctx-add (1, assistant.css:128, „1:1 .sb-h .a"), aichat-prompt-ico (1, ai-chat.css:724, výběrová dlaždice v mřížce ikon presetů, ne akce).

Sdílený „tichý odkaz" (JEDNA definice sb-h .a, section-block.css:99): a (10), tl-showall (1), dup-link (4, duplicate-panel.css:27), itm-mk (2, person-record.css:1425), mr-reclink (9, meeting-record.css:44), mr-speaker-suggest (1, „týž tvar jako mr-reclink"), ts (1, kombinace ts mr-reclink), chf-errlink (1, record-rail.css:949, „sdílený jazyk odkazů railu").

Record rail: eref-x (1, ds.css:525, „kanonický remove-×, sdílený se .pill .x"), rooms-slot-x (1, rooms.css:208, stejná rodina remove-× jako eref-x), t (1, record-rail.css:89, disclosure toggle titulku sekce railu — stejný vzor jako sb-toggle).

SectionBlock disclosure: sb-toggle (1, section-block.css:61) / sb-peek (1, section-block.css:44) — přesný příklad výjimky „disclosure toggle uvnitř SectionBlock".

Ostatní kanonické/dokumentované vzory: stop (3) / retry (2) — sdílená definice .aichat-err .retry, .aichat-run .stop (ai-chat.css:307-321), nc-composer (1, note-dialog.css:163, note composer v record draweru), note-card (1, note-card.css:68, „port _ds/note-card.css" — kanonická karta poznámky), entity (2, dynamický klíč → segmentovaný přepínač kroku importu), slotClass → pv-val (1) / pv-opt (1) — mail.css:745-761, „1:1 z DS karty Mail compose", chip vyplněného/prázdného slotu v šabloně, pdr-ico (9, drawer/record-drawer.css — POZOR: tato třída je klasifikovaná v A výše jako standalone icon action, zde není duplicitně počítána).

C — nejasné, patří na stůl AD (18 tříd)

TřídaPočetUmístěníProč nejasné
dlr-dial2pages/DialerPage.tsx:1644,1669Reimplementuje tvar .acrm-btn (výška/border/radius shodné), ale barva je vlastní „positive" zelená — Button variantu primary/default/ghost/danger takovou nemá; AD musí rozhodnout nový variant vs. bespoke (ds/dialer.css:463).
cside-toggle2pages/KalendarPage.tsx:1703,1823Asymetrický tvar (border-left:0, radius jen na jedné straně), splývá s hranou panelu kalendáře — IconButton takový tvar nemá (ds/calendar.css:202-214).
as-modebtn1components/AppShell.tsx:319Spouštěč přepínače modulů + menu (workspace-style trigger, ikona+text+výška --field-h) — kandidát na kanonický MenuButton (!3890), ale rozměr/vzhled se liší; potřeba AD (ds/app-shell.css:81-100).
as-search1components/AppShell.tsx:337Vypadá jako vstupní pole (cursor: text, border-strong, bg surface-100), ne tlačítko — nejasné, zda cílem je Button/IconButton, nebo DS Input trigger (ds/app-shell.css:147-160).
className3AppShell.tsx:568; contact-actions/PhoneActionsMenu.tsx:129; meetings/speaker-assign.tsx:68Třída je prop předávaná voláním (generický trigger/nav-row) — skutečný vzhled závisí na volajícím, nedohledatelné bez trasování všech callerů v rámci tohoto auditu.
as-acctbtn1components/AppShell.tsx:386Account/workspace switcher trigger, pill tvar, výška --field-h=32px — stejná nejistota jako as-modebtn (MenuButton vs. bespoke header trigger), ds/app-shell.css:311.
fb-save1components/FilterBar.tsx:523Jediná zvýrazněná akce lišty s podkladem --accent-tint — žádná ze čtyř Button variant takový tón nekreslí (ds/filter-bar.css:172); rozhodnutí je nová varianta, nebo bespoke zůstává.
gsp-foot1components/GlobalSearch.tsx:170244px CTA patka palety „Zeptat se asistenta", ale NENÍ mobilní touch (ten platí jen ≤720px, tahle patka vždy) a nese vlastní border-top/pozadí „ze schváleného návrhu, 1:1" — nejasné, zda cíl je bespoke řádek, nebo rozšíření touch (ds/global-search.css:252).
mc-tplsel1components/mail/ComposeForm.tsx:3690Komentář přímo v CSS říká, že srovnání výšek (32px anatomie Field v railu vs. 30px Button) „je otázka na AD, ne na tenhle MR" (mail.css:511-512).
phe-x1components/multivalue/MvRow.tsx:4620px ikonová afordance je explicitně „1:1 z DS Multi-value editor" (schválená karta, multi-value.css:81-88) — záměna za IconButton size="sm" (24px) by kartu porušila; nutné ověřit u AD, zda karta byla mezitím revidována.
phe-copy1components/multivalue/MvValue.tsx:40Totéž: 16px kopírovací afordance „1:1 z DS Multi-value editor" (multi-value.css:289-300), rozměr neodpovídá žádné IconButton velikosti, ale je to záměrná shoda s kartou.
prj-msblk-add1components/projects/ProjectMilestonesSection.tsx:360„Tichý řádek jako v Linearu" bez border/bg/výšky (project-milestones.css:205), stejný vzor jako .tl-addrow — nejasné, zda cíl je Button ghost compact, nebo samostatný „quiet add row" primitiv.
triggerClass1components/record/RecordActionsMenu.tsx:340Proměnná — komponenta už nabízí kanonickou cestu <IconButton icon="dots-vertical"> o řádek výš; fallback nese cizí třídu (pdr-ico, řešeno zvlášť v A). Rozhodnutí je, zda volající přejít na kanonickou větev.
dlg-gen1components/segment/SegmentBuilder.tsx:786AI „Vygenerovat" (fialová, sparkles-2), bez border/bg/výšky (segment-screen.css:1267) — nejasné, zda cíl Button ghost compact, nebo záměrný „AI text action" vzor.
shd-empty1components/segment/ShareDialog.tsx:492Přerušovaný rámeček přes celou šířku (segment-screen.css:1861) — vlastní „empty-state add" vzor; nejasné, zda cíl Button ghost/w-full, nebo zůstat u dashed vzoru.
dlr-lock-ext1pages/DialerPage.tsx:1162Text akce „Prodloužit" uvnitř útlé pilulky odpočtu zámku (dialer.css:217), bez border/bg/výšky — nejasné, zda tam Button chrome vůbec patří.
dlr-lock-cancel1pages/DialerPage.tsx:1170Totéž pro „Zrušit" (barva na hover → critical, dialer.css:231) — stejná nejistota.
drop1pages/ImportPage.tsx:591Celá drop-zone (ikona+text+hint, přerušovaný rámeček, drag&drop, import.css:183) — není akční tlačítko ani položka primitivu, spíš samostatný DS vzor „upload dropzone" bez kanonu.

Speciální bucket „(bez třídy)" / dynamický klíč (62 výskytů)

Vzorkováno ~35 z 62 lokací napříč dvěma nezávislými prověrkami. Zjištění:

  1. Naprostá většina jsou FALSE POSITIVES regexu, ne skutečná netříděná tlačítka: skript hledá literální text <button a tento kodebase hojně cituje <button> v českých JSDoc/inline komentářích vysvětlujících, proč komponenta používá <span role="button"> nebo naopak proč NEpoužívá <button> (např. components/AppShell.tsx:534, components/Board.tsx:249, components/ItemList.tsx:184/187/192/263/274/369, components/GlobalSearch.tsx:20/262, components/deal/DealRail.tsx:464, components/dialog/MetaChip.tsx:9/37, components/mail/EmailRow.tsx:148, components/notes/ChipMorph.tsx:15, components/notifications/NotifBell.tsx:194, components/relations/RelationRow.tsx:63, components/company/CompanyMergeTable.tsx:335) — na daném řádku není žádný skutečný JSX <button>. Odhad ze vzorku: cca 70–75 % bucketu jsou takové artefakty.
  2. Několik je skutečných tlačítek, ale s třídou, kterou jednoduchý regex nezachytil kvůli složitějšímu atributu před className (např. ref={...} nebo více atributů na řádku): components/FilterBar.tsx:447 je ve skutečnosti fb-chip (kanonický, B); components/company/CompanyMergeTable.tsx:319 je mgt-cell (B); components/drawer/RecordDrawer.tsx:310/313 je pdr-ico (A, jen jiný řádek téhož souboru); components/record/RecordActionsMenu.tsx:339 je triggerClass (C, řešeno výše).
  3. Několik je skutečně bez CSS třídy, stylováno inline style={} — legitimní B (volba/option, ne akce): barevný výběr týmu (pages/TeamDetailPage.tsx:456, pages/TymyPage.tsx:114 — swatch barev týmu, aria-pressed), disclosure toggle oprávnění (pages/settings/ModuleRights.tsx:122), výběr osoby v řádku (pages/settings/OpravneniLide.tsx:75).
  4. Jediný nalezený nezpochybnitelný „bez třídy" A-kandidát: pages/KalendarPage.tsx:677 a :685 (.czoom button — kolečka zoomu +/− v týdenním pohledu kalendáře, ds/calendar.css:1327: 24×24, radius-pill, bordered, shadow-sm). Komentář u nich (ACRM-89) říká, že jsou ZÁMĚRNĚ menší/jiné než ghost tlačítka navigace vedle nich, ale bez explicitního AD razítka jako u výjimky prev/today → zařazeno raději do C než A: „vlastní zoom-kolečka, dokumentované inženýrské zdůvodnění, ale bez AD podpisu."
  5. pages/KalendarPage.tsx:1586 („next" šipka) — bez třídy, ale sdílí selektor .nav button:not(.today) se sourozenci prev/today (schválená výjimka rodiny Button, ACRM-91/97/103) → B.

Závěr k „bez": nebyl nalezen žádný nezpochybnitelný A-kandidát mimo dvojici .czoom button (klasifikováno jako C kvůli chybějícímu AD razítku). Doporučení pro budoucí inventury: opravit regex skriptu, ať vylučuje řádky uvnitř /* ... */ a // ... komentářů — sníží to šum v tomto bucketu z ~62 na odhadem ~15-18 skutečných výskytů.

Totals

BucketPočet tříd
A45
B128
C18
„bez" (speciální, viz výše)1 (62 výskytů, ~70-75 % false positives regexu)
Celkem tříd192

Source: docs/button/INVENTURA-nativni-button-2026-09-28.md · GitLab