@exxatdesignux/ui 0.3.0 → 0.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (214) hide show
  1. package/CHANGELOG.md +701 -6
  2. package/README.md +138 -0
  3. package/bin/init.mjs +134 -31
  4. package/consumer-extras/cursor-rules/exxat-board-cards.mdc +1 -1
  5. package/consumer-extras/cursor-rules/exxat-centralized-list-dataset.mdc +2 -2
  6. package/consumer-extras/cursor-rules/exxat-collaboration-access.mdc +1 -1
  7. package/consumer-extras/cursor-rules/exxat-data-tables.mdc +2 -0
  8. package/consumer-extras/cursor-rules/exxat-dedicated-search-surfaces.mdc +1 -1
  9. package/consumer-extras/cursor-rules/exxat-ds-agents.mdc +3 -3
  10. package/consumer-extras/cursor-rules/exxat-library-hub-header.mdc +28 -0
  11. package/consumer-extras/cursor-rules/exxat-mono-ids.mdc +1 -1
  12. package/consumer-extras/cursor-rules/exxat-person-identity-display.mdc +1 -1
  13. package/consumer-extras/cursor-rules/exxat-primary-nav-secondary-panel.mdc +6 -6
  14. package/consumer-extras/cursor-rules/exxat-reuse-before-custom.mdc +1 -1
  15. package/consumer-extras/cursor-skills/exxat-board-cards/SKILL.md +2 -2
  16. package/consumer-extras/cursor-skills/exxat-centralized-list-dataset/SKILL.md +1 -1
  17. package/consumer-extras/cursor-skills/exxat-collaboration-access/SKILL.md +3 -3
  18. package/consumer-extras/cursor-skills/exxat-dedicated-search-surfaces/SKILL.md +2 -2
  19. package/consumer-extras/cursor-skills/exxat-ds-skill/SKILL.md +7 -7
  20. package/consumer-extras/cursor-skills/exxat-kpi-flat-band/SKILL.md +1 -1
  21. package/consumer-extras/cursor-skills/exxat-list-page-view-shells/SKILL.md +1 -1
  22. package/consumer-extras/cursor-skills/exxat-mono-ids/SKILL.md +4 -4
  23. package/consumer-extras/cursor-skills/exxat-primary-nav-secondary-panel/SKILL.md +8 -8
  24. package/consumer-extras/cursor-skills/exxat-token-economy/SKILL.md +277 -0
  25. package/consumer-extras/handbook/HANDBOOK.md +2 -0
  26. package/consumer-extras/handbook/glossary.md +2 -1
  27. package/consumer-extras/handbook/reference-implementations.md +31 -4
  28. package/consumer-extras/patterns/collaboration-access-pattern.md +7 -7
  29. package/consumer-extras/patterns/data-views-pattern.md +18 -16
  30. package/consumer-extras/patterns/kpi-flat-band-pattern.md +2 -2
  31. package/dist/components/data-table/index.js +2 -2
  32. package/dist/components/data-table/index.js.map +1 -1
  33. package/dist/components/data-table/pagination.js +3 -3
  34. package/dist/components/data-table/pagination.js.map +1 -1
  35. package/dist/components/data-table/use-table-state.d.ts +1 -1
  36. package/dist/components/data-table/use-table-state.js.map +1 -1
  37. package/dist/components/data-views/data-row-list.js.map +1 -1
  38. package/dist/components/data-views/finder-panel-view.d.ts +1 -1
  39. package/dist/components/data-views/finder-panel-view.js.map +1 -1
  40. package/dist/components/data-views/hub-table.d.ts +9 -3
  41. package/dist/components/data-views/hub-table.js +262 -40
  42. package/dist/components/data-views/hub-table.js.map +1 -1
  43. package/dist/components/data-views/index.js +262 -40
  44. package/dist/components/data-views/index.js.map +1 -1
  45. package/dist/components/data-views/list-page-split-hub-tokens.d.ts +2 -2
  46. package/dist/components/data-views/list-page-split-hub-tokens.js.map +1 -1
  47. package/dist/components/data-views/list-page-tree-column-header.d.ts +1 -1
  48. package/dist/components/data-views/list-page-tree-column-header.js.map +1 -1
  49. package/dist/components/data-views/list-page-tree-panel-shell.js.map +1 -1
  50. package/dist/components/data-views/os-folder-glyph.d.ts +1 -1
  51. package/dist/components/data-views/os-folder-glyph.js.map +1 -1
  52. package/dist/components/ui/avatar.d.ts +1 -1
  53. package/dist/components/ui/key-metrics.js.map +1 -1
  54. package/dist/index.js +136 -39
  55. package/dist/index.js.map +1 -1
  56. package/package.json +3 -2
  57. package/src/components/data-table/index.tsx +2 -2
  58. package/src/components/data-table/pagination.tsx +5 -1
  59. package/src/components/data-table/use-table-state.ts +1 -1
  60. package/src/components/data-views/data-row-list.tsx +1 -1
  61. package/src/components/data-views/finder-panel-view.tsx +2 -2
  62. package/src/components/data-views/hub-table.tsx +149 -41
  63. package/src/components/data-views/list-page-split-hub-tokens.ts +2 -2
  64. package/src/components/data-views/list-page-tree-column-header.tsx +1 -1
  65. package/src/components/data-views/os-folder-glyph.tsx +1 -1
  66. package/src/components/ui/key-metrics.tsx +1 -1
  67. package/template/.claude/skills/exxat-ds-skill/SKILL.md +8 -7
  68. package/template/.cursor/rules/exxat-accessibility.mdc +1 -1
  69. package/template/.cursor/rules/exxat-command-menu.mdc +1 -1
  70. package/template/.cursor/rules/exxat-dashboard-view-charts.mdc +6 -6
  71. package/template/.cursor/rules/exxat-data-tables.mdc +3 -3
  72. package/template/.cursor/rules/exxat-kbd-shortcuts.mdc +5 -5
  73. package/template/.cursor/rules/exxat-mono-ids.mdc +1 -1
  74. package/template/.cursor/rules/exxat-page-vs-drawer.mdc +1 -1
  75. package/template/.cursor/rules/exxat-table-properties-drawer.mdc +1 -1
  76. package/template/AGENTS.md +43 -37
  77. package/template/app/(app)/columns/page.tsx +11 -0
  78. package/template/app/(app)/library/all/page.tsx +11 -0
  79. package/template/app/(app)/library/find/page.tsx +12 -0
  80. package/template/app/(app)/{question-bank → library}/layout.tsx +16 -16
  81. package/template/app/(app)/library/list/page.tsx +12 -0
  82. package/template/app/(app)/{question-bank → library}/new/page.tsx +10 -10
  83. package/template/app/(app)/library/page.tsx +11 -0
  84. package/template/app/(app)/tokens-themes/page.tsx +11 -0
  85. package/template/components/ask-leo-composer.tsx +2 -2
  86. package/template/components/columns-client.tsx +158 -0
  87. package/template/components/columns-showcase.tsx +541 -0
  88. package/template/components/data-views/index.ts +32 -6
  89. package/template/components/data-views/{question-bank-folder-tree-branch.tsx → library-folder-tree-branch.tsx} +19 -19
  90. package/template/components/data-views/table-cells.tsx +673 -0
  91. package/template/components/folder-details-shell.tsx +11 -11
  92. package/template/components/hub-tree-panel-view.tsx +24 -24
  93. package/template/components/{question-bank-board-view.tsx → library-board-view.tsx} +44 -44
  94. package/template/components/{question-bank-client.tsx → library-client.tsx} +82 -82
  95. package/template/components/{question-bank-dashboard-charts.tsx → library-dashboard-charts.tsx} +14 -14
  96. package/template/components/{question-bank-favorite-button.tsx → library-favorite-button.tsx} +7 -7
  97. package/template/components/{question-bank-hub-client.tsx → library-hub-client.tsx} +43 -43
  98. package/template/components/{question-bank-new-folder-sheet.tsx → library-new-folder-sheet.tsx} +14 -14
  99. package/template/components/{question-bank-os-folder-view.tsx → library-os-folder-view.tsx} +31 -31
  100. package/template/components/{question-bank-page-header.tsx → library-page-header.tsx} +6 -6
  101. package/template/components/library-panel-activator.tsx +8 -0
  102. package/template/components/{question-bank-secondary-nav.tsx → library-secondary-nav.tsx} +60 -60
  103. package/template/components/{question-bank-table.tsx → library-table.tsx} +97 -97
  104. package/template/components/list-hub-status-badge.tsx +2 -2
  105. package/template/components/{new-question-composer.tsx → new-library-item-form.tsx} +37 -37
  106. package/template/components/sidebar/app-sidebar.tsx +61 -5
  107. package/template/components/sidebar/secondary-panel.tsx +109 -56
  108. package/template/components/sidebar/sidebar-auto-collapse.tsx +2 -2
  109. package/template/components/sidebar/sidebar-auto-open.tsx +2 -1
  110. package/template/components/table-properties/types.ts +1 -1
  111. package/template/components/templates/discovery-hub-template.tsx +1 -1
  112. package/template/components/templates/new-focus-template.tsx +2 -2
  113. package/template/components/templates/secondary-panel-hub-template.tsx +1 -1
  114. package/template/components/tokens-secondary-nav.tsx +192 -0
  115. package/template/components/tokens-themes-client.tsx +476 -0
  116. package/template/components/tokens-themes-section.tsx +386 -0
  117. package/template/docs/HANDBOOK.md +187 -0
  118. package/template/docs/blueprints/README.md +1 -1
  119. package/template/docs/blueprints/board-card.md +1 -1
  120. package/template/docs/blueprints/data-table.md +2 -2
  121. package/template/docs/blueprints/list-page-template.md +3 -3
  122. package/template/docs/blueprints/page-header.md +4 -4
  123. package/template/docs/collaboration-access-pattern.md +7 -7
  124. package/template/docs/component-selection-guide.md +1 -1
  125. package/template/docs/data-views-pattern.md +18 -16
  126. package/template/docs/glossary.md +58 -0
  127. package/template/docs/kpi-flat-band-pattern.md +3 -3
  128. package/template/docs/kpi-trend-pattern.md +18 -3
  129. package/template/docs/large-dataset-strategy.md +155 -0
  130. package/template/docs/library-hub-header-pattern.md +25 -0
  131. package/template/docs/migrations/_template.md +1 -1
  132. package/template/docs/reference-implementations.md +151 -0
  133. package/template/docs/token-taxonomy.md +1 -1
  134. package/template/docs/voice-and-tone.md +262 -0
  135. package/template/eslint.config.mjs +9 -39
  136. package/template/hooks/use-secondary-panel-hub-nav.ts +10 -10
  137. package/template/lib/ask-leo-route-context.ts +6 -18
  138. package/template/lib/coach-mark-registry.ts +0 -16
  139. package/template/lib/command-menu-config.ts +5 -12
  140. package/template/lib/command-menu-search-data.ts +8 -39
  141. package/template/lib/{question-bank-authoring.ts → library-authoring.ts} +89 -88
  142. package/template/lib/library-dedicated-search.ts +19 -0
  143. package/template/lib/library-hub-search.ts +90 -0
  144. package/template/lib/library-nav.ts +477 -0
  145. package/template/lib/library-recent-searches.ts +22 -0
  146. package/template/lib/{placements-supported-views.ts → library-supported-views.ts} +2 -2
  147. package/template/lib/list-status-badges.ts +16 -104
  148. package/template/lib/mock/dashboard.ts +1 -1
  149. package/template/lib/mock/{question-bank-folders.ts → library-folders.ts} +30 -30
  150. package/template/lib/mock/library-header-collaborators.ts +54 -0
  151. package/template/lib/mock/{question-bank-inspector.ts → library-inspector.ts} +29 -29
  152. package/template/lib/mock/{question-bank-kpi.ts → library-kpi.ts} +20 -20
  153. package/template/lib/mock/library.ts +249 -0
  154. package/template/lib/mock/navigation.tsx +32 -26
  155. package/template/lib/table-state-lifecycle.ts +1 -1
  156. package/template/next.config.mjs +7 -4
  157. package/template/package.json +0 -1
  158. package/tokens/hooks-index.json +2874 -0
  159. package/consumer-extras/cursor-rules/exxat-question-bank-hub-header.mdc +0 -28
  160. package/template/app/(app)/examples/page.tsx +0 -41
  161. package/template/app/(app)/question-bank/find/page.tsx +0 -12
  162. package/template/app/(app)/question-bank/library/page.tsx +0 -11
  163. package/template/app/(app)/question-bank/list/page.tsx +0 -12
  164. package/template/app/(app)/question-bank/page.tsx +0 -11
  165. package/template/components/compliance-board-view.tsx +0 -142
  166. package/template/components/compliance-client.tsx +0 -92
  167. package/template/components/compliance-page-header.tsx +0 -89
  168. package/template/components/compliance-table.tsx +0 -468
  169. package/template/components/data-view-dashboard-charts-compliance.tsx +0 -963
  170. package/template/components/data-view-dashboard-charts-team.tsx +0 -971
  171. package/template/components/data-view-dashboard-charts.tsx +0 -1503
  172. package/template/components/new-placement-back-btn.tsx +0 -28
  173. package/template/components/new-placement-form.tsx +0 -942
  174. package/template/components/placement-board-card.tsx +0 -250
  175. package/template/components/placement-detail.tsx +0 -438
  176. package/template/components/placements-board-view.tsx +0 -397
  177. package/template/components/placements-client.tsx +0 -220
  178. package/template/components/placements-list-view.tsx +0 -124
  179. package/template/components/placements-page-header.tsx +0 -166
  180. package/template/components/placements-table-cells.test.tsx +0 -22
  181. package/template/components/placements-table-cells.tsx +0 -173
  182. package/template/components/placements-table-columns.tsx +0 -210
  183. package/template/components/placements-table.tsx +0 -934
  184. package/template/components/question-bank-panel-activator.tsx +0 -8
  185. package/template/components/rotations-empty-state.tsx +0 -50
  186. package/template/components/rotations-panel-activator.tsx +0 -8
  187. package/template/components/sites-board-view.tsx +0 -67
  188. package/template/components/sites-client.tsx +0 -154
  189. package/template/components/sites-table.tsx +0 -249
  190. package/template/components/team-board-view.tsx +0 -122
  191. package/template/components/team-client.tsx +0 -100
  192. package/template/components/team-page-header.tsx +0 -92
  193. package/template/components/team-table.tsx +0 -553
  194. package/template/docs/question-bank-hub-header-pattern.md +0 -25
  195. package/template/lib/compliance-supported-views.ts +0 -10
  196. package/template/lib/data-view-dashboard-placements-layout.ts +0 -215
  197. package/template/lib/mock/compliance-kpi.ts +0 -61
  198. package/template/lib/mock/compliance.ts +0 -146
  199. package/template/lib/mock/placements-kpi.ts +0 -134
  200. package/template/lib/mock/placements.ts +0 -176
  201. package/template/lib/mock/question-bank-header-collaborators.ts +0 -54
  202. package/template/lib/mock/question-bank.ts +0 -249
  203. package/template/lib/mock/sites-directory.ts +0 -16
  204. package/template/lib/mock/sites-kpi.ts +0 -25
  205. package/template/lib/mock/team-kpi.ts +0 -60
  206. package/template/lib/mock/team.ts +0 -118
  207. package/template/lib/placement-board-card-layout.ts +0 -79
  208. package/template/lib/question-bank-dedicated-search.ts +0 -19
  209. package/template/lib/question-bank-hub-search.ts +0 -90
  210. package/template/lib/question-bank-nav.ts +0 -477
  211. package/template/lib/question-bank-recent-searches.ts +0 -22
  212. package/template/lib/question-bank-supported-views.ts +0 -12
  213. package/template/lib/sites-supported-views.ts +0 -10
  214. package/template/lib/team-supported-views.ts +0 -10
@@ -2,6 +2,8 @@
2
2
 
3
3
  > **Canonical rules for agents (MUST/MUST NOT, checklists):** [`AGENTS.md`](../AGENTS.md) in this package (including **§8 Accessibility**). This file is the long-form narrative; keep both aligned when patterns change.
4
4
 
5
+ > **Scaling past ~2K rows:** see [`large-dataset-strategy.md`](./large-dataset-strategy.md) for pagination, server-mode upgrade path, and the virtualization follow-up.
6
+
5
7
  This document describes how list pages combine **views**, **toolbar** behavior, **filters**, **properties**, and **persistence** in this codebase.
6
8
 
7
9
  ## Reuse existing components (required)
@@ -10,18 +12,18 @@ This document describes how list pages combine **views**, **toolbar** behavior,
10
12
 
11
13
  | Need | Reuse | Where Placements uses it |
12
14
  | --- | --- | --- |
13
- | **View tabs** (table / list / board, lifecycle filters) | `ListPageTemplate` (`ViewTab`, `renderContent`, optional metrics + export) | `components/placements-client.tsx` + `components/templates/list-page.tsx` |
14
- | **Table shell** (search, filter bar, sort, grouping, columns, pagination) | `DataTable`, `DataTableToolbar`, `useTableState` | `components/data-table/`, `components/placements-table.tsx` |
15
- | **Properties drawer** (display, columns, filters, sort, view type tiles) | `TablePropertiesDrawer` from `@/components/table-properties` | `DrawerToolbar` / list–board shells in `placements-table.tsx` |
15
+ | **View tabs** (table / list / board, lifecycle filters) | `ListPageTemplate` (`ViewTab`, `renderContent`, optional metrics + export) | `components/library-hub-client.tsx` + `components/templates/list-page.tsx` |
16
+ | **Table shell** (search, filter bar, sort, grouping, columns, pagination) | `HubTable` → `DataTable`, `DataTableToolbar`, `useTableState` | `components/data-table/`, `components/data-views/hub-table.tsx`, `components/columns-showcase.tsx` |
17
+ | **Properties drawer** (display, columns, filters, sort, view type tiles) | `TablePropertiesDrawer` from `@/components/table-properties` (auto-wired by `HubTable`) | `DrawerToolbar` / list–board shells in `library-table.tsx` |
16
18
  | **Board / list** | `PlacementsBoardView`, `PlacementListRowContent` (wrapped by `HubTable.renderListRow` → `DataRowList`) + same `useTableState` | `PlacementsTable` |
17
- | **Page header** (primary CTA + More ⋯ + export) | `PlacementsPageHeader` or `TeamPageHeader` | `components/placements-page-header.tsx`, `components/team-page-header.tsx` |
18
- | **Team page (primary template)** | `TeamClient` = `ListPageTemplate` + `KeyMetrics` + `TeamPageHeader` + `TeamTable` (same composition as `PlacementsClient`) | `components/team-client.tsx`, `lib/mock/team-kpi.ts` |
19
- | **Team roster** | `TeamTable` — `DataTable` + `useTableState` + `TablePropertiesDrawer`; list/board/dashboard read **`tableState.rows`** | `components/team-table.tsx` |
20
- | **Dashboard view (list tab)** | **`KeyMetrics`** (`variant="flat"` or `"card"`) — same KPI system as the template metrics strip; **do not** add ad-hoc `Card` grids for entity summaries | `TeamTable` dashboard branch, `lib/mock/team-kpi.ts` |
21
- | **List hub metrics strip** | **`KeyMetrics variant="flat"`** — transparent cells, OKLCH brand glow only, border hairlines (**no** grey panel) | **`docs/kpi-flat-band-pattern.md`**, Placements / Team / Question bank clients |
22
- | **Secondary panel chrome** | **`--secondary-panel-bg`** on **`NestedSecondaryPanelShell`** (lighter than sidebar, follows active product) | **`docs/shell-surface-elevation-pattern.md`**, Question bank |
19
+ | **Page header** (primary CTA + More ⋯ + export) | Per-hub page header composing `PageHeader` + `ExportDrawer` button | `components/library-page-header.tsx` |
20
+ | **Primary hub composition** | `*Client` = `ListPageTemplate` + `KeyMetrics` + `*PageHeader` + `*Table`. Reference: `LibraryHubClient`. | `components/library-hub-client.tsx`, `components/columns-client.tsx`, `components/tokens-themes-client.tsx` |
21
+ | **Hub table body** | `HubTable` — wraps `DataTable` + `useTableState` + `TablePropertiesDrawer`; list / board / dashboard read **`tableState.rows`**. Pagination chrome is auto-mounted when the hub passes `pagination` + `onPaginationChange`. | `components/data-views/hub-table.tsx`, `components/library-table.tsx`, `components/columns-showcase.tsx` |
22
+ | **Dashboard view (list tab)** | **`KeyMetrics`** (`variant="flat"` or `"card"`) — same KPI system as the template metrics strip; **do not** add ad-hoc `Card` grids for entity summaries. | `LibraryTable` dashboard branch, `components/library-dashboard-charts.tsx` |
23
+ | **List hub metrics strip** | **`KeyMetrics variant="flat"`** — transparent cells, OKLCH brand glow only, border hairlines (**no** grey panel) | **`docs/kpi-flat-band-pattern.md`**, Placements / Team / Library clients |
24
+ | **Secondary panel chrome** | **`--secondary-panel-bg`** on **`NestedSecondaryPanelShell`** (lighter than sidebar, follows active product) | **`docs/shell-surface-elevation-pattern.md`**, Library |
23
25
  | **Export** | `ExportDrawer` | `ListPageTemplate` export props; `PlacementsClient` |
24
- | **View body layout** (gutter + centered max-width for folder / icon / panel-style content) | **`ListPageViewFrame`** (`components/data-views/list-page-view-frame.tsx`, re-exported from `components/data-views`) | **`FolderGridView`** (uses the frame); **`QuestionBankOsFolderView`** — see **`AGENTS.md` §4.5** |
26
+ | **View body layout** (gutter + centered max-width for folder / icon / panel-style content) | **`ListPageViewFrame`** (`components/data-views/list-page-view-frame.tsx`, re-exported from `components/data-views`) | **`FolderGridView`** (uses the frame); **`LibraryOsFolderView`** — see **`AGENTS.md` §4.5** |
25
27
 
26
28
  **Rules:** (1) Import and compose these components; pass **props** and **column defs** for your entity. (2) If something is missing, **extend the shared component** under `components/` (e.g. a new optional slot on `DataTableToolbar`) rather than copying markup into a single page. (3) Card-only or lightweight pages may use a smaller **Properties** sheet only when there is **no** table—otherwise use `TablePropertiesDrawer` with `DataTable` (see Team).
27
29
 
@@ -89,13 +91,13 @@ Non-table view branches (e.g. **folder** icon grid, **panel** finder, OS-style f
89
91
  - **Status (Team & Compliance)** — `lib/list-status-badges.ts` — single source for label strings + badge `className` tails for **table, list, and board**. Do **not** pair with `uppercase` on the Badge (labels are sentence case, aligned with Placements `BoardStatusBadge`).
90
92
  - **Owner initials** — `lib/initials-from-name.ts` when mock rows have a display name but no `initials` field.
91
93
  - **Shared column shell** — `components/data-views/list-page-board-template.tsx` — `ListPageBoardTemplate` + `ListPageBoardColumnDef<T>`: define columns with `filter` predicates, `renderCard`, `getRowKey`. Used by **Team** and **Compliance** boards; new hubs should start here before custom chrome.
92
- - **Placement card** — `components/data-views/placement-board-card.tsx` — `BoardPlacementCard` composes **`ListPageBoardCard`** parts with `ColumnDef<Placement>` and lifecycle layout helpers from `lib/placement-board-card-layout.ts`. Placements keeps richer column headers (search, menus); still uses the same primitives.
94
+ - **Library board** — `components/library-board-view.tsx` — composes **`ListPageBoardCard`** parts with `BoardCardTwoLineBlock` for the body and `ListHubStatusBadge` for the status row. Use this as the reference for any new domain board card.
93
95
  - New entities should add their own card component that composes **`ListPageBoardCard`** + primitives rather than duplicating column scroll/layout or ad-hoc card chrome.
94
96
 
95
97
  ## Dashboard view (list pages)
96
98
 
97
- - **Reuse the dashboard chart bundle** — `components/dashboard-report-charts.tsx` — `DashboardReportCharts`: flat `KeyMetrics` + middle chart section + period comparison `KeyMetrics` card. **`ChartsOverview`** (placement-themed demo gallery) is the default middle section for `/dashboard` and **Placements**. **Team** passes **`chartsSection={<TeamDashboardChartsSection members={tableState.rows} />}`** so charts reflect roster data, not placements. List hubs use `ListPageDashboardCharts` (`metricsSingleRow`). Chart **style** can follow `ChartVariantProvider` when using `ChartsOverview`.
98
- - **Data tab canvas charts** (`data-view-dashboard-charts*.tsx`) share **`ChartFigure`**, **`ChartCard`**, and **`ChartDataTable`** with `charts-overview.tsx`. **Layout** for Placements / Team / Compliance is stored in one place: **`lib/data-view-dashboard-storage.ts`** (see `AGENTS.md` §4.3). **Keyboard-selected bars/slices** must use **`lib/chart-keyboard-selection.ts`** (`activeBar` / `activeShape`) so behavior matches the gallery — not opacity-only `Cell` dimming.
99
+ - **Reuse the dashboard chart bundle** — `components/dashboard-report-charts.tsx` — `DashboardReportCharts`: flat `KeyMetrics` + middle chart section + period comparison `KeyMetrics` card. **`ChartsOverview`** is the default middle section for `/dashboard`. Hubs pass **`chartsSection={<MyDashboardChartsSection rows={tableState.rows} />}`** so charts reflect the hub's own row set. Reference: **`LibraryDashboardChartsSection`** in `components/library-dashboard-charts.tsx`. Chart **style** can follow `ChartVariantProvider` when using `ChartsOverview`.
100
+ - **Data tab canvas charts** share **`ChartFigure`**, **`ChartCard`**, and **`ChartDataTable`** with `charts-overview.tsx`. **Layout** is stored in one place: **`lib/data-view-dashboard-storage.ts`** under a per-hub scope (see `AGENTS.md` §4.3). **Keyboard-selected bars/slices** must use **`lib/chart-keyboard-selection.ts`** (`activeBar` / `activeShape`) so behavior matches the gallery — not opacity-only `Cell` dimming.
99
101
 
100
102
  ## Persistence
101
103
 
@@ -130,13 +132,13 @@ Below the threshold, these may be omitted unless the page is a primary data hub
130
132
 
131
133
  ## Data pages: primary CTA + More + Export
132
134
 
133
- If the page **has exportable data** (rows, members, placements, etc.), follow the **Placements** header pattern:
135
+ If the page **has exportable data** (rows, members, library items, etc.), follow the **Library** header pattern:
134
136
 
135
- 1. **Primary action** — One default (filled) button for the main task (e.g. **New placement**, **Invite member**). Do **not** use `variant="outline"` for that primary action.
137
+ 1. **Primary action** — One default (filled) button for the main task (e.g. **New question**, **Invite collaborator**, **Add token**). Do **not** use `variant="outline"` for that primary action.
136
138
  2. **More (⋯)** — An outline **icon** button opening a menu that includes **Export** (and other overflow actions). Wire **Export** to `ExportDrawer` (or equivalent).
137
139
  3. **Subtitle** — Prefer a short line with **count + freshness** (e.g. `24 records · Last updated now`), matching `PlacementsPageHeader`.
138
140
 
139
- Reference: `components/placements-page-header.tsx`, `components/team-page-header.tsx`, `components/team-client.tsx`.
141
+ Reference: `components/library-page-header.tsx`, `components/library-hub-client.tsx`.
140
142
 
141
143
  ---
142
144
 
@@ -24,7 +24,7 @@ List hubs and the main dashboard mix view use **`KeyMetrics variant="flat"`** as
24
24
 
25
25
  ## MUST NOT
26
26
 
27
- - Add **`--key-metrics-flat-band-linear`** back into `flatBandStyle` or hub inline styles (e.g. question-bank hub hero).
27
+ - Add **`--key-metrics-flat-band-linear`** back into `flatBandStyle` or hub inline styles (e.g. library hub hero).
28
28
  - Use **`variant="card"`** on **`ListPageTemplate`** metrics when the design calls for a **flat strip** on the page background.
29
29
  - Duplicate KPI numbers in ad-hoc **`Card`** grids on the same hub.
30
30
  - Set **`variant="mutedSuffix"`** on product wordmarks to grey out the **suffix** in dark mode — suffix stays **Exxat pink** (`wordmarkColor`); see **`lib/product-brand.ts`**.
@@ -42,7 +42,7 @@ Dark mode (`.dark`): same rules — transparent cells, radial glow only, no line
42
42
 
43
43
  ## Reference implementations
44
44
 
45
- - `components/question-bank-client.tsx` — `KeyMetrics variant="flat" metricsSingleRow`
45
+ - `components/library-client.tsx` — `KeyMetrics variant="flat" metricsSingleRow`
46
46
  - `components/dashboard-tabs.tsx` — mix view flat band + insight
47
47
  - `components/placements-client.tsx`, `team-client.tsx`, `compliance-client.tsx` — list hub metrics slot
48
48
 
@@ -2579,8 +2579,8 @@ function DataTableInner({
2579
2579
  setHeaderScrollLeft(e.currentTarget.scrollLeft);
2580
2580
  },
2581
2581
  className: cn(
2582
- "mx-4 lg:mx-6 overflow-x-auto border border-border",
2583
- hasFooter ? "rounded-t-lg" : "rounded-lg"
2582
+ "mx-4 lg:mx-6 overflow-x-auto border-t border-x border-border",
2583
+ hasFooter ? "rounded-t-lg" : "border-b rounded-lg"
2584
2584
  ),
2585
2585
  children: /* @__PURE__ */ jsxs(
2586
2586
  "table",