diff --git a/packages/twenty-ui/README.md b/packages/twenty-ui/README.md
index c21b3a3cd2..2eac78b28d 100644
--- a/packages/twenty-ui/README.md
+++ b/packages/twenty-ui/README.md
@@ -1,385 +1,75 @@
# twenty-ui
-> **Status:** Cut-over complete (June 2026). All 192 components and all 70 stories were
-> migrated from the legacy library with full public-API parity (export-identifier diff:
-> 0 missing / 0 extra across all 13 subpath modules), `twenty-front` was switched over to
-> `twenty-ui`, and the legacy `twenty-ui-deprecated` package was removed. Gates green:
-> typecheck, lint, jest, build, storybook:build,
-> storybook:test (225 stories incl. play functions + live axe gate), size.
-> Remaining: the Argos visual-parity triage, the a11y fix pass (119 stories carry
-> inherited-violation `a11y: 'todo'` overrides), the CI diff-table workflow, the
-> `modules/ui` triage (Phase 4), and the publish pipeline (Phase 5).
-> The sections below remain the design document for the full effort; see
-> [Migration outcomes](#migration-outcomes-june-2026) for decisions taken during the port.
+Twenty's open-source React UI component library: components, icons, and design tokens built on a zero-runtime, CSS-variable styling layer.
-`twenty-ui` is Twenty's UI library, the successor to the legacy `twenty-ui-deprecated` package
-(now removed). It is built on a headless component library and a zero-runtime, CSS-variable styling layer.
+# Installation
-## Goals
-
-1. Publish as a standalone, versioned **npm package**.
-2. Replace `twenty-ui` in `twenty-front` with **no visual change** (same design, token for token).
-3. **Migrate every component** currently exported by `twenty-ui-deprecated`. *(Done — June 2026.)*
-4. **Absorb the generic, reusable UI** currently living in `twenty-front/src/modules/ui` (dropdowns, modals, tab lists, side panels, navigation, field inputs/displays, etc.), decoupling it from application concerns so it ships from the library.
-5. Enforce a **quality bar in CI**: bundle size, render/load time, and accessibility, measured against the old library.
-
-## Current state (`twenty-ui-deprecated`)
-
-| Aspect | Today |
-| --- | --- |
-| Exports | ~180 components across 13 subpath entry points (`display`, `input`, `layout`, `navigation`, `feedback`, `components`, `theme`, `theme-constants`, `utilities`, `accessibility`, `assets`, `json-visualizer`, `testing`) + 3 CSS files |
-| Styling | Linaria (`@linaria/react`) compiled via `@wyw-in-js/vite`; theming via generated `--t-*` CSS variables |
-| Behavior | Hand-rolled (modals, menus, tooltips, selects, etc.); `react-tooltip` for tooltips |
-| Build | Vite library mode, dual ESM/CJS, `vite-plugin-dts`, auto-generated barrels |
-| Icons | `@tabler/icons-react` re-exports + custom icons + Jotai-backed `IconsProvider` |
-| Consumption | ~1,730 files in `twenty-front` import it (mostly `display` and `theme-constants`), plus `twenty-front-component-renderer` and `twenty-sdk`; imported by package name |
-| Published | No (`private: true`) |
-
-`twenty-front/src/modules/ui/` (application-level UI) consumes `twenty-ui-deprecated` today. Its **generic, reusable**
-components are now **in scope** — they migrate into `twenty-ui` (see [Application-level UI migration](#application-level-ui-migration-twenty-frontsrcmodulesui)).
-
-## Decision 1 — Headless library: Base UI
-
-Adopt **Base UI** ([`mui/base-ui`](https://github.com/mui/base-ui), published to npm as
-[`@base-ui/react`](https://base-ui.com), MIT) as the behavioral foundation; build Twenty's visual
-design on top of it.
-
-| | Base UI | shadcn/ui | Radix |
-| --- | --- | --- | --- |
-| Distribution | npm package | copy-paste source | npm package |
-| Styling | bring your own | Tailwind | bring your own |
-| State styling | `data-*` + `className`-as-function | (underlying primitive) | `data-*` |
-| Maintenance | MUI team, full-time; frequent stable releases | community | WorkOS; slower cadence, creators departed |
-
-**Rationale**
-
-- **Publishable and unstyled** — Base UI ships as an npm dependency and imposes no styling, so consumers apply their own tokens. shadcn is copy-paste source (not installable) and Tailwind-coupled; it is suitable only as a scaffolding/reference tool, not the foundation.
-- **Active long-term investment** — Base UI is maintained by the team behind Radix, Floating UI, and Material UI. Radix is a viable, still-maintained fallback, but its core authors now work on Base UI and its stable-release cadence has slowed.
-- **Modern, broad primitives** — Combobox/Autocomplete with built-in search, Select, Number Field, Navigation Menu, Toast, etc., several of which replace hand-rolled or single-purpose dependencies in `twenty-ui`.
-- **`className`-as-function-of-state** pairs cleanly with CSS/SCSS Modules.
-- **Small, tree-shakeable dependency tree**; peer-compatible with the repo's React 18.
-
-Pin the latest **stable** release at implementation time; isolate Base UI behind the package's own
-component APIs so upgrades stay localized.
-
-## Decision 2 — Styling: SCSS Modules (drop Linaria)
-
-Use **SCSS Modules** (`*.module.scss`) over the existing CSS-variable theme. Drop Linaria.
-
-| Approach | Runtime | Build complexity | Scoping | Verdict |
-| --- | --- | --- | --- | --- |
-| Linaria (today) | zero | high (Babel + wyw-in-js) | auto | overkill |
-| Plain global CSS | zero | none | none (collision risk) | unsafe for a library |
-| CSS Modules | zero | none (native Vite) | auto | strong baseline |
-| **SCSS Modules** | zero | low (`sass` only) | auto | **recommended** |
-| vanilla-extract | zero | medium (TS compile) | auto | viable alternative (typed tokens) |
-
-**Rationale**
-
-- Theming is already CSS variables and component state comes from Base UI as `data-*` attributes, so the two features Linaria provides (JS theming and prop interpolation) are not needed.
-- SCSS Modules are zero-runtime and auto-scoped, native to Vite (no Babel/`wyw-in-js`), and faster to build.
-- Sass mixins, maps, and `@each` cover variant/size generation and responsive breakpoints.
-- Type-safe class names via generated `*.module.scss.d.ts` (`vite-plugin-sass-dts`).
-
-**Conventions:** one `Component.module.scss` per component; tokens only via `var(--t-*)`; state via
-`data-*` selectors; multi-variant composition via `clsx` (or `cva` for a typed variants API);
-shared `mixins.scss` / `breakpoints.scss`; global unscoped CSS only for theme variables, reset, and keyframes.
-
-## Architecture
-
-```
-packages/twenty-ui/
-├── package.json # public exports mirror twenty-ui's subpath map
-├── project.json # Nx targets: build, lint, test, storybook, size
-├── vite.config.ts # library mode, no wyw-in-js
-├── vitest.config.ts # storybook component tests
-├── .storybook/
-├── .size-limit.json # per-entry bundle budgets
-├── scripts/ # generateBarrels.ts
-└── src/
- ├── styles/ # global: reset, theme vars, mixins, breakpoints
- ├── theme/ theme-constants/
- ├── display/ input/ layout/ navigation/ feedback/ components/
- ├── accessibility/ utilities/ json-visualizer/ assets/ testing/
+```bash
+npm install twenty-ui
```
-**Public API parity.** Keep the same subpath exports, component names, and prop signatures as
-`twenty-ui-deprecated` so the final swap is a codemod + dependency rename, not a rewrite of ~1,730 files.
-Keep auto-generated barrels and dual ESM/CJS + `dts` output. *(Achieved: the export-identifier sets of
-all 13 module barrels are identical between the two packages.)*
+`react`, `react-dom`, and `monaco-editor` are peer dependencies (install them in your app). `monaco-editor` is only required if you use the code editor components.
-**Internal changes vs `twenty-ui-deprecated`:** Linaria → SCSS Modules; hand-rolled behavior + `react-tooltip`
-→ Base UI; prefer Base UI/CSS transitions over `framer-motion` where possible; keep the icon system
-as-is. The internal path alias is `@ui/*` (same convention as the deprecated package, so ported files
-diff cleanly against their sources).
+# Usage
-## Theming
+Import the base styles once, pick a theme stylesheet, and wrap your app in `ThemeProvider`:
-`theme-constants` has ~943 importers and must be a drop-in replacement.
+```tsx
+import { ThemeProvider } from 'twenty-ui/theme-constants';
+import { Button } from 'twenty-ui/input';
-- Keep the public API identical: `ThemeProvider`, `ThemeContext`, `useTheme`, the `themeCssVariables` shape, `ThemeType`, color helpers, and the `theme-light.css` / `theme-dark.css` exports.
-- Reuse `twenty-ui-deprecated`'s token values verbatim to guarantee identical design.
-- Tokens live in `src/theme/` (`THEME_LIGHT` / `THEME_DARK`); the `--t-*` CSS variables and the `themeCssVariables` accessor are static files mirrored token-for-token from `twenty-ui-deprecated` (matching its own static-CSS approach).
-- A theme parity test asserts the theme CSS and `themeCssVariables` stay identical to `twenty-ui-deprecated`'s `--t-*` values.
+import 'twenty-ui/style.css';
+import 'twenty-ui/theme-light.css';
-### Consuming the theme
+export const App = () => (
+
+
+
+);
+```
-- Wrap the app once in `ThemeProvider` and import `twenty-ui/theme-light.css` and `twenty-ui/theme-dark.css`.
-- Read theme values with the public hooks, not the raw context:
- - `useTheme()` returns the resolved `ThemeType` (numeric tokens such as `theme.icon.size.sm`). Outside a provider it yields the default light theme.
- - `useThemeColorScheme()` returns the active `'light' | 'dark'`.
-- Colors are consumed as `var(--t-*)` strings via `themeCssVariables` (the browser resolves them against the in-scope `--t-*`), so overriding the variables re-themes color automatically.
+Components are available from the root entry point or from a specific subpath for better tree-shaking:
-### Customizing the theme (`--t-*` override contract)
+```tsx
+import { Button } from 'twenty-ui';
+import { Button } from 'twenty-ui/input';
+```
-The supported way to re-theme is to override the `--t-*` CSS variables. Their names are exactly the keys declared in `theme-light.css` / `theme-dark.css`. Two mechanisms:
+# Entry points
-1. **Globally** — ship a stylesheet that redefines `--t-*` under `.light` / `.dark`. This covers the whole document, including overlays portaled to `document.body`.
-2. **Per `ThemeProvider`** — pass `overrides` (a `ThemeOverrides` map of `--t-*` name to value). The variables are applied to the provider's subtree.
-
-`ThemeProvider` props:
-
-- `colorScheme: 'light' | 'dark'` — required.
-- `applyToRoot?: boolean` (default `true`) — toggles the `.light` / `.dark` class on `document.documentElement`. Keep it `true` so the whole document, including portaled overlays (tooltips, dropdowns, modals) rendered to `document.body`, stays themed. Set it `false` when the host manages its own color-scheme class or when mounting more than one provider, so the providers don't clobber the root.
-- `overrides?: ThemeOverrides` — `--t-*` variable overrides scoped to this provider's subtree.
-- `className?: string` — extra class on the scoped wrapper.
-
-**Scoped theming and portals.** When `applyToRoot` is `false` or `overrides` is set, the provider scopes the variables to a wrapper element. Overlays portal to `document.body` (outside that wrapper), so for them to inherit the scoped variables the provider also exposes a themed portal container via `ThemeScopeContext`; read it with `useThemeContainer()` and pass it as the overlay's portal container. The library's `AppTooltip` and `Modal` already do this, falling back to `document.body` when no scoped provider is present (the default global path is unchanged).
-
-## Component migration map
-
-Components split into two buckets. *(The migration is complete; see
-[Migration outcomes](#migration-outcomes-june-2026) below for where reality diverged from this map.)*
-
-**Backed by a Base UI primitive (behavioral):**
-
-| `twenty-ui-deprecated` | Base UI |
+| Subpath | Contents |
| --- | --- |
-| `Modal` | `Dialog` / `AlertDialog` |
-| `AppTooltip`, `OverflowingTextWithTooltip` | `Tooltip` (removes `react-tooltip`) |
-| `Toggle` | `Switch` |
-| `Checkbox` / `Radio` | `Checkbox` / `Radio` (+ groups) |
-| `Menu`, `MenuItem` | `Menu` / `ContextMenu` / `Menubar` |
-| `TabButton` | `Tabs` |
-| `SearchInput`, text inputs | `Input` + `Field` |
-| `CardPicker` | `RadioGroup` / `ToggleGroup` |
-| `ColorPicker` | `Popover` + custom |
-| `ProgressBar` | `Progress` |
-| `Avatar`, `AvatarGroup` | `Avatar` |
-| `AnimatedExpandableContainer` | `Collapsible` / `Accordion` |
+| `twenty-ui` | All components, icons, theme tokens, and utilities |
+| `twenty-ui/accessibility` | Accessibility helpers |
+| `twenty-ui/assets` | Logos and static assets |
+| `twenty-ui/data-display` | Avatars, chips, tags, and other display components |
+| `twenty-ui/feedback` | Progress bars, loaders, and status feedback |
+| `twenty-ui/icon` | Icon components and the icon provider |
+| `twenty-ui/input` | Buttons, toggles, and form inputs |
+| `twenty-ui/json-visualizer` | JSON tree viewer |
+| `twenty-ui/layout` | Layout primitives |
+| `twenty-ui/navigation` | Menus, links, and navigation components |
+| `twenty-ui/surfaces` | Cards, tooltips, and surface components |
+| `twenty-ui/testing` | Storybook and test decorators |
+| `twenty-ui/theme` | Theme types and helpers |
+| `twenty-ui/theme-constants` | Design tokens, `ThemeProvider`, and `useTheme` |
+| `twenty-ui/typography` | Text and typography components |
+| `twenty-ui/utilities` | Hooks and shared utilities |
-**Pure presentation, built in-house (SCSS Modules):** button family, typography, `Chip`/`Pill`/`Tag`/`LinkChip`,
-`Banner`/`Callout`/`Info`/`Status`, `Card`/`Section`/`Separator`, `Loader`, `TintedIconTile`,
-`ColorSample`, `Checkmark`, placeholders, the icon system, `CodeEditor` (Monaco), `json-visualizer`,
-and the `utilities` / `theme` / `testing` / `accessibility` helpers.
+# Theming
-### Migration outcomes (June 2026)
+- `twenty-ui/style.css` ships the base reset and component styles. Import it once.
+- `twenty-ui/theme-light.css` and `twenty-ui/theme-dark.css` define the design-token CSS variables for each color scheme.
+- `ThemeProvider` exposes the active theme through `useTheme()` and applies the `light` / `dark` class. Pass `applyToRoot={false}` with `overrides` to scope a theme to a subtree instead of the document root.
-Decisions taken during the port where reality diverged from the map above (public API parity won every time):
+# Development
-- **`MenuItem` family and `TabButton` did NOT move to Base UI** Menu/Tabs — those primitives require a
- `Root` context the deprecated standalone APIs don't have. They are pure presentation with `data-*` state.
- The Base UI `Menu` mapping applies to the Phase-4 `modules/ui` dropdown instead.
-- **`AnimatedExpandableContainer` kept framer-motion** (sanctioned fallback): its exported utils are framer
- variant factories whose signatures are public API, and Collapsible/grid-rows could not match scrollHeight
- mid-animation retargeting or initial-mount animation.
-- **`Avatar`'s `invalidAvatarUrlsAtomV2` and the icon system's `iconsState` Jotai atoms were kept** — both are
- public `display` exports, overriding this doc's earlier "Jotai → local state" idea.
-- **`CardContent` kept framer-motion**: its motion props are part of the public prop type and twenty-front's
- `CalendarDayCardContent` passes them.
-- **`ProgressBar` is pure SCSS** (Base UI Progress was optional and not needed for parity); `useProgressAnimation`
- keeps framer motion-values verbatim (public hook).
-- **Known behavior deltas to watch in QA:** `AppTooltip` and `Modal` (without an explicit `container`) now portal
- to `document.body` (Base UI), so overflow-clipping ancestors no longer clip them and `AppTooltip`'s default
- `maxWidth: '40%'` resolves against the body; `Checkbox`/`Radio` test ids moved from the hidden input to the
- visible Base UI control.
-- **The Storybook axe gate was inert until this migration** — `.storybook/vitest.setup.ts` did not register the
- a11y addon annotations, so `a11y.test: 'error'` never ran. It is now live; 119 ported stories carry
- story-level `a11y: { test: 'todo' }` overrides (`// TODO(a11y)` comments) pending a dedicated fix pass.
-- The canonical styling pattern is established in `src/input/button/components/Button/Button.tsx` +
- `Button.module.scss`: `data-variant/accent/position/inverted` attributes, Sass maps + `@each` assigning
- `--btn-*` custom properties, all declarations on a flat `(0,1,0)` class so `styled(Component)` consumer
- overrides keep working.
+```bash
+npx nx build twenty-ui # Build the library (dual ESM/CJS + types)
+npx nx storybook:serve:dev twenty-ui # Run Storybook
+npx nx test twenty-ui # Run unit tests
+```
-## Application-level UI migration (`twenty-front/src/modules/ui`)
+# License
-`twenty-front/src/modules/ui` holds ~250 application-level UI building blocks that consume `twenty-ui-deprecated`
-today: `display`, `feedback` (snackbar/dialog managers), `field` (input + display), `input`
-(incl. relation picker), `layout` (dropdown, modal, tab-list, side-panel, page, table, resizable-panel,
-expandable-list, selectable-list, top-bar, …), `navigation` (drawer, breadcrumb, step-bar, menu-item),
-`drag-and-drop`, `suggestion`, `theme`, and `utilities` (hotkey, scroll, focus, responsive, drag-select, …).
-
-These are a **different kind of migration** than the `twenty-ui-deprecated` swap: they are stateful and
-app-coupled — Jotai atoms, hooks, contexts, and (in places) GraphQL/router/Recoil-style state — rather
-than pure presentation. The goal is to extract the **generic, reusable** parts into `twenty-ui`
-while leaving genuinely app-specific wiring in `twenty-front`.
-
-**Approach**
-
-- **Triage, don't lift-and-shift.** Per component, classify as: (a) **generic** → migrate to `twenty-ui`; (b) **app-specific** → keep in `twenty-front`; (c) **hybrid** → split a presentational/headless core (library) from an app-wired wrapper (front).
-- **Decouple state.** Replace internal Jotai/global state with controlled props (`props down, events up`); where a component needs local state, keep it self-contained. The library must not import app stores, GraphQL, or routing.
-- **Prefer Base UI primitives** for behavior already covered there — Dropdown→`Menu`/`Popover`, modal/side-panel→`Dialog`, tab-list→`Tabs`, expandable/selectable lists→`Collapsible`/list patterns, drag-and-drop stays on the existing dnd lib but exposed generically.
-- **Same parity bar** as the rest of the package: stories (all states, light/dark), interaction + a11y tests, visual-parity diff, within-budget size entry.
-
-**Out of scope (stays in `twenty-front`):** components bound to domain entities, record/table data fetching,
-workspace/router/permission logic, and anything whose only consumer is a single feature screen.
-
-A component-by-component triage of `modules/ui` (generic / app-specific / hybrid, with target subpath
-and state-decoupling notes) is the remaining **Phase 4 prerequisite** (the `twenty-ui-deprecated` inventory itself is complete — every component is migrated).
-
-## Hardest components to migrate (risk hotspots)
-
-A predicted ranking of where the effort and risk concentrate, to inform sequencing and staffing. This
-is a hypothesis to validate during the Phase 0 inventory/triage, not a final list.
-
-### In `twenty-ui-deprecated` *(all migrated — predictions held; see Migration outcomes)*
-
-| Component | Why it's hard | Migration shape |
-| --- | --- | --- |
-| `CodeEditor` (`input/code-editor`) | Hard dependency on Monaco; Linaria theme defined via `defineTheme()` bound to Monaco lifecycle | Port Monaco integration ~verbatim; only re-skin via CSS vars — Base UI doesn't apply |
-| Button family — `Button` (~560 LOC), `IconButton` (~330), `AnimatedButton` (~520) | Huge Linaria style matrix (variant × accent × inverted × disabled × position, 140+ branches each); router `Link`; framer-motion on the animated one | Establish the canonical "computed class / `cva` + `data-*`" pattern here first; this trio is the project's key inflection point (~30–40% of library effort) |
-| `Modal` + `ModalBackdrop` (`layout/modal`) | framer-motion `AnimatePresence`, portal + z-index layering, responsive Linaria sizing | Base UI `Dialog` + CSS transitions; backdrop animation has no direct Base UI equivalent |
-| `AnimatedExpandableContainer` | scroll-height measurement + framer-motion height/opacity animation | Base UI `Collapsible` + CSS grid-rows / JS height fallback |
-| `AppTooltip`, `OverflowingTextWithTooltip` | `react-tooltip` dependency + overflow detection; Linaria `css` template | Swap to Base UI `Tooltip` (+ Floating UI); behavioral divergence is likely and needs parity tests |
-| `JsonNestedNode` (`json-visualizer`) | recursive tree with per-node framer-motion expand/collapse | Recursion is fine; replace animation, keep structure |
-| `MenuItem`, `ProgressBar`/`CircularProgressBar`, `Avatar`/`AvatarGroup` | framer-motion micro-animations; `Avatar` uses a Jotai atom for broken-image fallback | CSS transitions; `Avatar` → Base UI `Avatar`, Jotai → local state/props |
-| `IconsProvider`, `ThemeProvider` | Jotai-backed icon registry; runtime CSS-var parsing — **every** component depends on them | Low per-unit effort but high blast radius; freeze the public API, swap internals carefully |
-
-Cross-cutting: **~120 files use Linaria prop interpolation** and **~26 use framer-motion** — the two
-systemic conversions (→ SCSS Modules, → CSS/Base UI transitions) dominate, not any single component.
-
-### In `twenty-front/src/modules/ui`
-
-Here difficulty is **decoupling from app state**, not visuals. Ranked hardest:
-
-| Area | Why it's hard | Decoupling needed |
-| --- | --- | --- |
-| `layout/dropdown` | Floating UI positioning + open-state atoms + hotkey scoping; foundational to many features | Generic positioning wrapper; controlled open state; injectable keyboard handling |
-| `utilities/hotkey` + `utilities/focus` | Hand-rolled global hotkey **scope stack** and focus stack as shared runtime state | Extract as an injectable system; the rest of the library must not assume the global stack |
-| `navigation/navigation-drawer` (~40 files) | Deeply bound to `currentWorkspaceState`, auth, Apollo error handling, multi-workspace switching | Mostly **app-specific** — migrate only the generic drawer shell, leave workspace logic in `twenty-front` |
-| `layout/selectable-list` | 2D arrow-key navigation state machine over atom families | Pure grid-position functions + a controlled selection API |
-| `layout/expandable-list` | Floating UI + DOM overflow measurement | Layout-agnostic overflow API, drop Floating UI coupling |
-| `layout/table` | Generic types but heavy sorting/metadata atoms | Make field-agnostic; lift state out |
-| `layout/modal` | `ModalComponentInstanceContext`, click-outside + escape via hotkeys, stacking indices | Injectable container; remove context coupling |
-| `layout/resizable-panel`, `utilities/drag-select`, `utilities/scroll` | Direct DOM/pointer manipulation, set CSS vars on `documentElement`, scroll-wrapper atom coupling | Callback/controlled APIs; pure geometry utils; optional scroll coupling |
-| `feedback` (snackbar + dialog managers) | Snackbar formats **Apollo** errors; dialog uses framer-motion | Generic error objects; CSS animations |
-| `layout/tab-list` | Router `useNavigate`, measurement system, dropdown coupling | Callback-based navigation; extract measurement |
-| `input` date pickers (`internal/date`, ~47 files) | `temporal-polyfill`, reads `currentWorkspaceMemberState` for tz/locale | Parameterize locale/timezone via props |
-
-**Probably should NOT migrate (too app-coupled, keep in `twenty-front`):** `field/input` & `field/display`
-(bound to `FieldMetadata` / `object-record`), the full navigation-drawer workspace/auth UI, snackbar
-Apollo error formatting, and the icon/theme-color pickers tied to Twenty's icon set and theme system.
-
-## Test, benchmark & parity strategy
-
-- **Workbench** — Storybook (`@storybook/react-vite`). Every component has stories covering variants, sizes, and states (via `storybook-addon-pseudo-states`), in light and dark, with `autodocs`.
-- **Functional** — component/interaction tests via `@storybook/addon-vitest` (real browser); unit tests (Jest) for hooks/utilities; coverage gate via `@storybook/addon-coverage`.
-- **Accessibility** — Storybook a11y addon (axe-core) with `parameters.a11y.test = 'error'` so violations fail CI.
-- **Visual parity** — visual regression via Argos (self-hosted) plus a cross-package comparison project that diffs `twenty-ui` stories against `twenty-ui-deprecated` stories with identical names; a pixel-diff threshold is the per-component acceptance gate. See [Visual regression](#visual-regression) below.
-- **Performance & size** — `size-limit` per entry point with budgets; tree-shaking fixtures (importing one component must not pull the library); build-time tracking; render benchmarks via React Profiler; load-time via Lighthouse/Playwright on the built Storybook. As one concrete benchmark, a dedicated **stress story** renders a very large number of a single component (e.g. 10,000 buttons) and measures total render time — compared against the `twenty-ui-deprecated` equivalent and gated against a budget to catch per-instance overhead regressions. *(Stress story not yet built.)*
-
-CI surfaces a per-PR diff table (`twenty-ui-deprecated` vs `twenty-ui`) for size, a11y, and visual changes. *(Not yet built.)*
-
-## Visual regression
-
-Two Argos projects (on argos.twenty-internal.com) provide visual regression in CI:
-
-1. **`twenty-ui`** — pixel diff of `twenty-ui` stories against the `main` branch baseline. Catches regressions introduced by a PR.
-2. **`twenty-ui-vs-new-ui`** — cross-package comparison. The baseline is always `twenty-ui-deprecated` screenshots from `main`; PR builds upload `twenty-ui` screenshots and diff them against that baseline. This shows exactly which components still differ between the two implementations.
-
-For the cross-package comparison to produce meaningful diffs, stories in `twenty-ui` must use the **same title hierarchy** as `twenty-ui-deprecated` (e.g. `UI/Input/Toggle/Toggle`). *(Done: all 70 story titles are byte-identical.)*
-
-### Local visual diff
-
-Run a pixel diff of `twenty-ui` components against `twenty-ui-deprecated` using the self-hosted Argos instance.
-
-**Prerequisites:**
-- AWS SSO configured and logged in (`aws sso login --profile twenty-dev`)
-- `twenty-infra/super-cli` cloned (sibling of this repo)
-
-**1. Start the Argos tunnel**
-
-In the `twenty-infra/super-cli` directory:
-
- yarn cli argos-tunnel
-
-This port-forwards the Argos service to `http://127.0.0.1:4002`.
-Wait until the CLI shows "Argos tunnel is running".
-
-**2. Set your Argos token**
-
-Create a `.env` file in `packages/twenty-ui/` (gitignored):
-
- ARGOS_TOKEN=
-
-**3. Run the visual diff**
-
-From the repo root:
-
- npx nx storybook:visual-diff twenty-ui
-
-This builds Storybook, captures screenshots of every story, and uploads
-them to Argos with build name `/twenty-ui`. The diff
-compares against the latest approved baseline.
-
-To run `twenty-ui-deprecated`'s visual diff in the same Argos instance (to build the
-cross-package comparison baseline):
-
- npx nx storybook:visual-diff twenty-ui-deprecated
-
-**4. View results**
-
-Open `http://127.0.0.1:4002` in your browser (while the tunnel is running)
-to review diffs.
-
-## Build & publishing
-
-- Vite library mode, dual ESM/CJS, `vite-plugin-dts`, `vite-plugin-svgr`; SCSS via Vite's built-in `sass`; no Babel.
-- `sideEffects: ["**/*.css", "**/*.scss"]`; emit per-entry CSS plus `style.css` / `theme-light.css` / `theme-dark.css`.
-- Public package (remove `private`); ships as `twenty-ui` (the old package already moved to the `twenty-ui-deprecated` name and is removed after cut-over).
-- **Changesets** for semver + changelog; GitHub Actions release with `npm publish --provenance`.
-- Declare `react` / `react-dom` as peer dependencies; validate the `exports`/types map with `publint` + `@arethetypeswrong/cli`.
-- Publish the Storybook as living documentation.
-
-## Migration & rollout
-
-1. ~~Build `twenty-ui` to parity with the same API surface and design~~ **Done** — validated by the export-parity diff, a11y, and size suites; visual-parity triage via Argos still pending.
-2. Dogfood on a few non-critical `twenty-front` screens behind a temporary alias.
-3. Codemod imports `twenty-ui-deprecated` → `twenty-ui` (subpaths preserved) across `twenty-front` (~1,730 files), `twenty-front-component-renderer`, and `twenty-sdk`; handle any changed APIs explicitly.
-4. Swap the dependency, run the full test suite + visual diffs, ship.
-5. Remove `twenty-ui-deprecated` after a soak period.
-
-## Roadmap
-
-- ~~**Phase 0 — Foundations**~~ ✅ scaffolding, tooling, theme parity, harnesses. Still open from Phase 0: the CI diff-table workflow and the `modules/ui` triage (moved under Phase 4).
-- ~~**Phase 1 — Primitives**~~ ✅ done June 2026 (canonical pattern: `Button.tsx` + data-attribute Sass matrix).
-- ~~**Phase 2 — Behavioral**~~ ✅ done June 2026 (Base UI where mapped; see Migration outcomes for exceptions).
-- ~~**Phase 3 — Long tail**~~ ✅ done June 2026. Follow-up debt: the a11y fix pass for the 119 `a11y: 'todo'` stories, and the Argos visual-parity triage.
-- **Phase 4 — Application-level UI:** migrate the generic/hybrid components from `twenty-front/src/modules/ui` per the triage — decouple state, split headless cores, swap each behind its existing `@/ui/...` import path.
-- **Phase 5 — Hardening & publish:** close gaps; finalize release pipeline; cut `1.0.0`; publish docs.
-- ~~**Phase 6 — Cut-over**~~ ✅ done June 2026: codemod imports → swap dependency → remove `twenty-ui-deprecated`.
-
-A component is done only with: stories (all states, light/dark), passing interaction + a11y tests,
-a passing visual-parity diff, and a within-budget size entry.
-
-## Risks
-
-| Risk | Mitigation |
-| --- | --- |
-| Base UI pre-1.0 API churn | Pin exact version; gate GA on stable release; isolate behind component APIs |
-| Visual drift | Reuse exact tokens; visual-parity snapshots as the per-component gate |
-| Theme API mismatch (~943 consumers) | Freeze `theme-constants` contract; generated-CSS diff test |
-| 1,721 import sites | Preserve subpaths/names; automate with a codemod |
-| No Base UI primitive for some components | Build in-house; use Base UI utilities where helpful |
-| Bundle regressions | `size-limit` budgets + PR diff; prefer CSS transitions over `framer-motion` |
-| `modules/ui` components entangled with app state (Jotai/GraphQL/router) | Triage first; split headless core from app wrapper; controlled props only — no app imports in the library |
-
-## Open questions
-
-1. ~~Published package name.~~ **Resolved:** the rename already happened — this package owns `twenty-ui`; the old one is `twenty-ui-deprecated`.
-2. ~~Styling: SCSS Modules vs vanilla-extract vs plain CSS Modules.~~ **Resolved:** SCSS Modules, proven across all 192 components.
-3. ~~Variants helper: `clsx` + `data-*` vs `cva`.~~ **Resolved:** `clsx` + `data-*` attributes with Sass maps/`@each` (canonical pattern in `Button.module.scss`); `cva` not needed.
-4. ~~Visual regression tooling: Chromatic vs self-hosted image snapshots.~~ **Resolved:** Argos (self-hosted at argos.twenty-internal.com). See [Visual regression](#visual-regression).
-5. ~~How aggressively to drop `framer-motion`.~~ **Resolved:** keep it where animation is the public contract (`utilities/animation`, `AnimatedButton`, `AnimatedCheckmark`, `AnimatedExpandableContainer`, `useProgressAnimation`, `CardContent`); converted to CSS/Base UI transitions everywhere it was an internal micro-transition.
-6. ~~Scope of `assets` / `testing` / `json-visualizer`.~~ **Resolved:** ported — assets byte-identical, testing decorators converted to SCSS, json-visualizer recursion verbatim with CSS/Collapsible animations.
-7. Where to draw the generic-vs-app-specific line for `modules/ui`, and whether hybrid components live as a headless core in `twenty-ui` with a thin app wrapper in `twenty-front`. **(Still open — Phase 4.)**
+twenty-ui is released under the [AGPL-3.0](https://github.com/twentyhq/twenty/blob/main/packages/twenty-ui/LICENSE) license.