@exxatdesignux/ui 0.5.10 → 0.5.12
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.
- package/CHANGELOG.md +37 -0
- package/bin/cli.mjs +70 -1
- package/bin/init.mjs +18 -4
- package/bin/sync-extras.mjs +28 -4
- package/consumer-extras/README.md +41 -5
- package/consumer-extras/cursor-rules/exxat-accessibility.mdc +2 -1
- package/consumer-extras/cursor-rules/exxat-board-cards.mdc +5 -3
- package/consumer-extras/cursor-rules/exxat-breadcrumbs-no-back.mdc +1 -0
- package/consumer-extras/cursor-rules/exxat-card-vs-list-rows.mdc +1 -0
- package/consumer-extras/cursor-rules/exxat-centralized-list-dataset.mdc +4 -2
- package/consumer-extras/cursor-rules/exxat-collaboration-access.mdc +1 -0
- package/consumer-extras/cursor-rules/exxat-command-menu.mdc +3 -2
- package/consumer-extras/cursor-rules/exxat-data-tables.mdc +5 -3
- package/consumer-extras/cursor-rules/exxat-dedicated-search-surfaces.mdc +7 -0
- package/consumer-extras/cursor-rules/exxat-drawer-vs-dialog.mdc +2 -1
- package/consumer-extras/cursor-rules/exxat-ds-agents.mdc +13 -2
- package/consumer-extras/cursor-rules/exxat-fontawesome-icons.mdc +1 -0
- package/consumer-extras/cursor-rules/exxat-hub-supported-views.mdc +6 -4
- package/consumer-extras/cursor-rules/exxat-kbd-shortcuts.mdc +6 -5
- package/consumer-extras/cursor-rules/exxat-kpi-flat-band.mdc +1 -0
- package/consumer-extras/cursor-rules/exxat-kpi-max-four.mdc +1 -0
- package/consumer-extras/cursor-rules/exxat-kpi-trends.mdc +1 -0
- package/consumer-extras/cursor-rules/exxat-library-hub-header.mdc +2 -1
- package/consumer-extras/cursor-rules/exxat-list-page-connected-views.mdc +6 -2
- package/consumer-extras/cursor-rules/exxat-list-page-view-shells.mdc +2 -1
- package/consumer-extras/cursor-rules/exxat-mono-ids.mdc +2 -1
- package/consumer-extras/cursor-rules/exxat-nav-single-active.mdc +4 -3
- package/consumer-extras/cursor-rules/exxat-no-image-pixel-copy.mdc +25 -14
- package/consumer-extras/cursor-rules/exxat-no-slds-leakage.mdc +8 -2
- package/consumer-extras/cursor-rules/exxat-no-toast.mdc +1 -0
- package/consumer-extras/cursor-rules/exxat-no-vaul.mdc +2 -1
- package/consumer-extras/cursor-rules/exxat-page-header-actions.mdc +6 -4
- package/consumer-extras/cursor-rules/exxat-page-vs-drawer.mdc +2 -1
- package/consumer-extras/cursor-rules/exxat-person-identity-display.mdc +1 -0
- package/consumer-extras/cursor-rules/exxat-primary-nav-secondary-panel.mdc +2 -1
- package/consumer-extras/cursor-rules/exxat-reuse-before-custom.mdc +1 -0
- package/consumer-extras/cursor-rules/exxat-sidebar-shell.mdc +13 -7
- package/consumer-extras/cursor-rules/exxat-table-properties-drawer.mdc +5 -3
- package/consumer-extras/cursor-rules/exxat-table-row-preview.mdc +1 -0
- package/consumer-extras/cursor-rules/exxat-tabs-chrome.mdc +6 -4
- package/consumer-extras/cursor-rules/exxat-token-discipline.mdc +6 -0
- package/consumer-extras/cursor-rules/exxat-ux-discovery-protocol.mdc +92 -12
- package/consumer-extras/cursor-rules/exxat-ux-principles.mdc +1 -0
- package/consumer-extras/cursor-skills/exxat-ds-skill/SKILL.md +1 -1
- package/consumer-extras/cursor-skills/exxat-kpi-trends/SKILL.md +5 -3
- package/consumer-extras/cursor-skills/exxat-senior-ux/SKILL.md +70 -17
- package/consumer-extras/patterns/command-menu-pattern.md +2 -2
- package/consumer-extras/patterns/consumer-upgrade-checklist.md +1 -1
- package/consumer-extras/patterns/jobs/README.md +1 -1
- package/consumer-extras/patterns/perf-memory-pattern.md +115 -150
- package/consumer-extras/scripts/dev-guard.mjs +156 -0
- package/consumer-extras/templates/README.md +23 -0
- package/consumer-extras/templates/handoff.md +190 -0
- package/dist/hooks/use-app-theme.d.ts +1 -1
- package/package.json +2 -2
- package/{template → template-vite}/.claude/skills/exxat-ds-skill/SKILL.md +184 -23
- package/template-vite/.cursor/rules/exxat-accessibility.mdc +40 -0
- package/template-vite/.cursor/rules/exxat-board-cards.mdc +28 -0
- package/template-vite/.cursor/rules/exxat-breadcrumbs-no-back.mdc +22 -0
- package/template-vite/.cursor/rules/exxat-card-vs-list-rows.mdc +22 -0
- package/template-vite/.cursor/rules/exxat-centralized-list-dataset.mdc +46 -0
- package/template-vite/.cursor/rules/exxat-collaboration-access.mdc +33 -0
- package/{template → template-vite}/.cursor/rules/exxat-command-menu.mdc +5 -5
- package/template-vite/.cursor/rules/exxat-data-tables.mdc +47 -0
- package/template-vite/.cursor/rules/exxat-dedicated-search-surfaces.mdc +32 -0
- package/template-vite/.cursor/rules/exxat-drawer-vs-dialog.mdc +23 -0
- package/template-vite/.cursor/rules/exxat-ds-agents.mdc +87 -0
- package/template-vite/.cursor/rules/exxat-fontawesome-icons.mdc +32 -0
- package/template-vite/.cursor/rules/exxat-hub-supported-views.mdc +56 -0
- package/{template → template-vite}/.cursor/rules/exxat-kbd-shortcuts.mdc +1 -0
- package/template-vite/.cursor/rules/exxat-kpi-flat-band.mdc +29 -0
- package/template-vite/.cursor/rules/exxat-kpi-max-four.mdc +22 -0
- package/template-vite/.cursor/rules/exxat-kpi-trends.mdc +32 -0
- package/template-vite/.cursor/rules/exxat-library-hub-header.mdc +29 -0
- package/template-vite/.cursor/rules/exxat-list-page-connected-views.mdc +28 -0
- package/template-vite/.cursor/rules/exxat-list-page-view-shells.mdc +32 -0
- package/{template → template-vite}/.cursor/rules/exxat-mono-ids.mdc +1 -0
- package/template-vite/.cursor/rules/exxat-nav-single-active.mdc +32 -0
- package/template-vite/.cursor/rules/exxat-no-image-pixel-copy.mdc +46 -0
- package/template-vite/.cursor/rules/exxat-no-slds-leakage.mdc +84 -0
- package/{template → template-vite}/.cursor/rules/exxat-no-toast.mdc +2 -2
- package/template-vite/.cursor/rules/exxat-no-vaul.mdc +26 -0
- package/template-vite/.cursor/rules/exxat-page-header-actions.mdc +33 -0
- package/{template → template-vite}/.cursor/rules/exxat-page-vs-drawer.mdc +5 -3
- package/template-vite/.cursor/rules/exxat-person-identity-display.mdc +48 -0
- package/template-vite/.cursor/rules/exxat-primary-nav-secondary-panel.mdc +53 -0
- package/template-vite/.cursor/rules/exxat-reuse-before-custom.mdc +37 -0
- package/template-vite/.cursor/rules/exxat-sidebar-shell.mdc +41 -0
- package/template-vite/.cursor/rules/exxat-table-properties-drawer.mdc +79 -0
- package/template-vite/.cursor/rules/exxat-table-row-preview.mdc +25 -0
- package/template-vite/.cursor/rules/exxat-tabs-chrome.mdc +33 -0
- package/template-vite/.cursor/rules/exxat-token-discipline.mdc +109 -0
- package/template-vite/.cursor/rules/exxat-ux-discovery-protocol.mdc +202 -0
- package/template-vite/.cursor/rules/exxat-ux-principles.mdc +187 -0
- package/template-vite/.cursor/skills/exxat-accessibility/SKILL.md +282 -0
- package/template-vite/.cursor/skills/exxat-board-cards/SKILL.md +68 -0
- package/template-vite/.cursor/skills/exxat-card-vs-list-rows/SKILL.md +20 -0
- package/template-vite/.cursor/skills/exxat-centralized-list-dataset/SKILL.md +99 -0
- package/template-vite/.cursor/skills/exxat-collaboration-access/SKILL.md +35 -0
- package/template-vite/.cursor/skills/exxat-dedicated-search-surfaces/SKILL.md +45 -0
- package/template-vite/.cursor/skills/exxat-drawer-vs-dialog/SKILL.md +20 -0
- package/template-vite/.cursor/skills/exxat-ds-skill/SKILL.md +893 -0
- package/template-vite/.cursor/skills/exxat-ds-skill/references/accessibility.md +142 -0
- package/template-vite/.cursor/skills/exxat-ds-skill/references/coach-marks.md +169 -0
- package/template-vite/.cursor/skills/exxat-ds-skill/references/data-table-pattern.md +392 -0
- package/template-vite/.cursor/skills/exxat-fontawesome-icons/SKILL.md +31 -0
- package/template-vite/.cursor/skills/exxat-kpi-flat-band/SKILL.md +38 -0
- package/template-vite/.cursor/skills/exxat-kpi-max-four/SKILL.md +19 -0
- package/template-vite/.cursor/skills/exxat-kpi-trends/SKILL.md +29 -0
- package/template-vite/.cursor/skills/exxat-list-page-view-shells/SKILL.md +36 -0
- package/template-vite/.cursor/skills/exxat-mono-ids/SKILL.md +56 -0
- package/template-vite/.cursor/skills/exxat-primary-nav-secondary-panel/SKILL.md +49 -0
- package/template-vite/.cursor/skills/exxat-senior-ux/SKILL.md +198 -0
- package/template-vite/.cursor/skills/exxat-token-economy/SKILL.md +287 -0
- package/template-vite/.cursor/skills/exxat-ux-audit/SKILL.md +303 -0
- package/{template → template-vite}/components/ask-leo-sidebar.tsx +10 -8
- package/{template → template-vite}/components/command-menu.tsx +1 -1
- package/{template → template-vite}/components/data-views/library-folder-tree-branch.tsx +1 -1
- package/{template → template-vite}/components/dedicated-search-recents.tsx +1 -1
- package/{template → template-vite}/components/dedicated-search-url-composer.tsx +1 -1
- package/{template → template-vite}/components/library-client.tsx +1 -1
- package/{template → template-vite}/components/library-hub-client.tsx +2 -2
- package/{template → template-vite}/components/library-secondary-nav.tsx +2 -2
- package/{template → template-vite}/components/library-table.tsx +35 -27
- package/{template → template-vite}/components/new-library-item-form.tsx +1 -1
- package/{template → template-vite}/components/page-breadcrumb-trail.tsx +1 -1
- package/{template → template-vite}/components/settings-client.tsx +1 -1
- package/{template → template-vite}/components/sidebar/app-sidebar.tsx +2 -2
- package/{template → template-vite}/components/sidebar/nav-main.tsx +1 -1
- package/{template → template-vite}/components/sidebar/nav-user.tsx +1 -1
- package/{template → template-vite}/components/sidebar/secondary-nav.tsx +1 -1
- package/{template → template-vite}/components/system-banner-slot.tsx +1 -1
- package/{template → template-vite}/components/templates/discovery-hub-template.tsx +2 -2
- package/{template → template-vite}/components/templates/new-focus-template.tsx +1 -1
- package/{template → template-vite}/components/tokens-secondary-nav.tsx +2 -2
- package/{template → template-vite}/components/tokens-themes-client.tsx +1 -1
- package/{template → template-vite}/hooks/use-secondary-panel-hub-nav.ts +1 -1
- package/template-vite/index.html +49 -0
- package/template-vite/lib/next-compat.tsx +98 -0
- package/{template → template-vite}/package.json +15 -27
- package/template-vite/scripts/port-next-imports.mjs +70 -0
- package/template-vite/src/App.tsx +103 -0
- package/template-vite/src/main.tsx +50 -0
- package/{template/app/(app)/error.tsx → template-vite/src/pages/_error.tsx} +12 -24
- package/{template/app/(app)/loading.tsx → template-vite/src/pages/_loading.tsx} +4 -2
- package/template-vite/src/pages/_not-found.tsx +17 -0
- package/template-vite/src/pages/dashboard.tsx +48 -0
- package/{template/app/(app)/help/page.tsx → template-vite/src/pages/help.tsx} +3 -2
- package/{template/app/(app)/library/layout.tsx → template-vite/src/pages/library/_layout.tsx} +18 -16
- package/{template/app/(app)/library/all/page.tsx → template-vite/src/pages/library/all.tsx} +1 -1
- package/{template/app/(app)/library/new/page.tsx → template-vite/src/pages/library/new.tsx} +12 -18
- package/template-vite/src/routes.tsx +72 -0
- package/{template/app → template-vite/src/styles}/globals.css +6 -2
- package/{template → template-vite}/tsconfig.json +5 -14
- package/template-vite/vite.config.ts +52 -0
- package/consumer-extras/cursor-rules/exxat-dashboard-view-charts.mdc +0 -53
- package/template/.agents/skills/shadcn/SKILL.md +0 -242
- package/template/.agents/skills/shadcn/agents/openai.yml +0 -5
- package/template/.agents/skills/shadcn/assets/shadcn-small.png +0 -0
- package/template/.agents/skills/shadcn/assets/shadcn.png +0 -0
- package/template/.agents/skills/shadcn/cli.md +0 -257
- package/template/.agents/skills/shadcn/customization.md +0 -202
- package/template/.agents/skills/shadcn/evals/evals.json +0 -47
- package/template/.agents/skills/shadcn/mcp.md +0 -94
- package/template/.agents/skills/shadcn/rules/base-vs-radix.md +0 -306
- package/template/.agents/skills/shadcn/rules/composition.md +0 -195
- package/template/.agents/skills/shadcn/rules/forms.md +0 -192
- package/template/.agents/skills/shadcn/rules/icons.md +0 -101
- package/template/.agents/skills/shadcn/rules/styling.md +0 -162
- package/template/.cursor/rules/exxat-accessibility.mdc +0 -33
- package/template/.cursor/rules/exxat-data-tables.mdc +0 -32
- package/template/.cursor/rules/exxat-ds-agents.mdc +0 -26
- package/template/.cursor/rules/exxat-list-page-connected-views.mdc +0 -16
- package/template/.cursor/rules/exxat-table-properties-drawer.mdc +0 -40
- package/template/.nvmrc +0 -1
- package/template/.prettierignore +0 -7
- package/template/Logo/Exxat_Prism.svg +0 -39
- package/template/Logo/Exxat_one.svg +0 -36
- package/template/app/(app)/dashboard/loading.tsx +0 -18
- package/template/app/(app)/dashboard/page.tsx +0 -36
- package/template/app/(app)/layout.tsx +0 -77
- package/template/app/global-error.tsx +0 -63
- package/template/app/layout.tsx +0 -133
- package/template/app/page.tsx +0 -9
- package/template/docs/HANDBOOK.md +0 -187
- package/template/docs/blueprints/README.md +0 -86
- package/template/docs/blueprints/_template.md +0 -91
- package/template/docs/blueprints/board-card.md +0 -123
- package/template/docs/blueprints/data-table.md +0 -139
- package/template/docs/blueprints/key-metrics.md +0 -128
- package/template/docs/blueprints/list-page-template.md +0 -123
- package/template/docs/blueprints/page-header.md +0 -130
- package/template/docs/card-vs-rows-pattern.md +0 -36
- package/template/docs/collaboration-access-pattern.md +0 -116
- package/template/docs/command-menu-pattern.md +0 -45
- package/template/docs/component-selection-guide.md +0 -224
- package/template/docs/components-audit-2026-05.md +0 -158
- package/template/docs/consumer-upgrade-checklist.md +0 -52
- package/template/docs/data-views-pattern.md +0 -185
- package/template/docs/drawer-vs-dialog-pattern.md +0 -50
- package/template/docs/glossary.md +0 -59
- package/template/docs/hub-supported-views-pattern.md +0 -53
- package/template/docs/jobs/README.md +0 -59
- package/template/docs/jobs/record-detail.md +0 -177
- package/template/docs/kpi-flat-band-pattern.md +0 -57
- package/template/docs/kpi-strip-max-four-pattern.md +0 -30
- package/template/docs/kpi-trend-pattern.md +0 -58
- package/template/docs/large-dataset-strategy.md +0 -155
- package/template/docs/library-hub-header-pattern.md +0 -25
- package/template/docs/migrations/0001-brand-deep-alias-stabilization.md +0 -95
- package/template/docs/migrations/0002-exxat-token-namespace.md +0 -154
- package/template/docs/migrations/0003-globals-css-canonical.md +0 -110
- package/template/docs/migrations/README.md +0 -100
- package/template/docs/migrations/_template.md +0 -64
- package/template/docs/modern-saas-patterns.md +0 -165
- package/template/docs/perf-memory-pattern.md +0 -206
- package/template/docs/reference-implementations.md +0 -153
- package/template/docs/shell-surface-elevation-pattern.md +0 -52
- package/template/docs/token-taxonomy.md +0 -416
- package/template/docs/voice-and-tone.md +0 -262
- package/template/ecosystem.config.cjs +0 -32
- package/template/next.config.mjs +0 -216
- package/template/postcss.config.mjs +0 -8
- package/template/public/favicon/favicon.ico +0 -0
- package/template/tests/setup.ts +0 -26
- package/template/vitest.config.ts +0 -18
- /package/{template → template-vite}/.cursor/rules/exxat-dashboard-view-charts.mdc +0 -0
- /package/{template → template-vite}/.prettierrc +0 -0
- /package/{template → template-vite}/AGENTS.md +0 -0
- /package/{template → template-vite}/README.md +0 -0
- /package/{template → template-vite}/components/.gitkeep +0 -0
- /package/{template → template-vite}/components/ask-leo-composer.tsx +0 -0
- /package/{template → template-vite}/components/brand-color-picker.tsx +0 -0
- /package/{template → template-vite}/components/chart-area-interactive.tsx +0 -0
- /package/{template → template-vite}/components/charts-overview.tsx +0 -0
- /package/{template → template-vite}/components/collaboration-access-flow.tsx +0 -0
- /package/{template → template-vite}/components/columns-client.tsx +0 -0
- /package/{template → template-vite}/components/columns-showcase.tsx +0 -0
- /package/{template → template-vite}/components/dashboard-promo-banner.tsx +0 -0
- /package/{template → template-vite}/components/dashboard-quota-progress-card.tsx +0 -0
- /package/{template → template-vite}/components/dashboard-report-charts.tsx +0 -0
- /package/{template → template-vite}/components/dashboard-section-heading.tsx +0 -0
- /package/{template → template-vite}/components/dashboard-tabs.tsx +0 -0
- /package/{template → template-vite}/components/data-table/filter-date-calendar.tsx +0 -0
- /package/{template → template-vite}/components/data-table/filter-text-value-input.tsx +0 -0
- /package/{template → template-vite}/components/data-table/index.tsx +0 -0
- /package/{template → template-vite}/components/data-table/pagination.tsx +0 -0
- /package/{template → template-vite}/components/data-table/types.ts +0 -0
- /package/{template → template-vite}/components/data-table/use-table-state.test.ts +0 -0
- /package/{template → template-vite}/components/data-table/use-table-state.ts +0 -0
- /package/{template → template-vite}/components/data-views/board-card-primitives.tsx +0 -0
- /package/{template → template-vite}/components/data-views/data-row-list.tsx +0 -0
- /package/{template → template-vite}/components/data-views/finder-panel-view.tsx +0 -0
- /package/{template → template-vite}/components/data-views/folder-grid-view.tsx +0 -0
- /package/{template → template-vite}/components/data-views/hub-table.tsx +0 -0
- /package/{template → template-vite}/components/data-views/index.ts +0 -0
- /package/{template → template-vite}/components/data-views/list-page-board-card.tsx +0 -0
- /package/{template → template-vite}/components/data-views/list-page-board-template.tsx +0 -0
- /package/{template → template-vite}/components/data-views/list-page-connected-view-body.tsx +0 -0
- /package/{template → template-vite}/components/data-views/list-page-split-details-placeholder.tsx +0 -0
- /package/{template → template-vite}/components/data-views/list-page-split-hub-chrome.tsx +0 -0
- /package/{template → template-vite}/components/data-views/list-page-split-hub-tokens.ts +0 -0
- /package/{template → template-vite}/components/data-views/list-page-tree-column-header.tsx +0 -0
- /package/{template → template-vite}/components/data-views/list-page-tree-panel-shell.tsx +0 -0
- /package/{template → template-vite}/components/data-views/list-page-view-frame.tsx +0 -0
- /package/{template → template-vite}/components/data-views/os-folder-glyph.tsx +0 -0
- /package/{template → template-vite}/components/data-views/outline-tree-menu.tsx +0 -0
- /package/{template → template-vite}/components/data-views/table-cells.tsx +0 -0
- /package/{template → template-vite}/components/dev-chunk-load-recovery.tsx +0 -0
- /package/{template → template-vite}/components/export-drawer.test.tsx +0 -0
- /package/{template → template-vite}/components/export-drawer.tsx +0 -0
- /package/{template → template-vite}/components/exxat-product-logo.tsx +0 -0
- /package/{template → template-vite}/components/folder-details-shell.tsx +0 -0
- /package/{template → template-vite}/components/form-layout-01.tsx +0 -0
- /package/{template → template-vite}/components/hub-tree-panel-view.tsx +0 -0
- /package/{template → template-vite}/components/invite-collaborators-drawer.tsx +0 -0
- /package/{template → template-vite}/components/key-metrics-ask-leo-bridge.tsx +0 -0
- /package/{template → template-vite}/components/key-metrics.tsx +0 -0
- /package/{template → template-vite}/components/leo-insight-indicator.tsx +0 -0
- /package/{template → template-vite}/components/leo-typing-dots.tsx +0 -0
- /package/{template → template-vite}/components/library-board-view.tsx +0 -0
- /package/{template → template-vite}/components/library-dashboard-charts.tsx +0 -0
- /package/{template → template-vite}/components/library-favorite-button.tsx +0 -0
- /package/{template → template-vite}/components/library-new-folder-sheet.tsx +0 -0
- /package/{template → template-vite}/components/library-os-folder-view.tsx +0 -0
- /package/{template → template-vite}/components/library-page-header.tsx +0 -0
- /package/{template → template-vite}/components/library-panel-activator.tsx +0 -0
- /package/{template → template-vite}/components/list-hub-status-badge.tsx +0 -0
- /package/{template → template-vite}/components/list-page-dashboard-charts.tsx +0 -0
- /package/{template → template-vite}/components/onboarding/getting-started.tsx +0 -0
- /package/{template → template-vite}/components/onboarding/index.ts +0 -0
- /package/{template → template-vite}/components/onboarding/onboarding-01.tsx +0 -0
- /package/{template → template-vite}/components/onboarding/onboarding-02.tsx +0 -0
- /package/{template → template-vite}/components/onboarding/onboarding-03.tsx +0 -0
- /package/{template → template-vite}/components/onboarding/onboarding-04.tsx +0 -0
- /package/{template → template-vite}/components/page-header.tsx +0 -0
- /package/{template → template-vite}/components/product-switcher.tsx +0 -0
- /package/{template → template-vite}/components/product-wordmark.tsx +0 -0
- /package/{template → template-vite}/components/settings-appearance-card.tsx +0 -0
- /package/{template → template-vite}/components/settings-form-row.tsx +0 -0
- /package/{template → template-vite}/components/sidebar/app-sidebar-dynamic.tsx +0 -0
- /package/{template → template-vite}/components/sidebar/index.ts +0 -0
- /package/{template → template-vite}/components/sidebar/nav-documents.tsx +0 -0
- /package/{template → template-vite}/components/sidebar/nav-secondary.tsx +0 -0
- /package/{template → template-vite}/components/sidebar/secondary-panel.tsx +0 -0
- /package/{template → template-vite}/components/sidebar/sidebar-auto-collapse.tsx +0 -0
- /package/{template → template-vite}/components/sidebar/sidebar-auto-open.tsx +0 -0
- /package/{template → template-vite}/components/sidebar/sidebar-shell.tsx +0 -0
- /package/{template → template-vite}/components/site-header.tsx +0 -0
- /package/{template → template-vite}/components/table-properties/column-row.tsx +0 -0
- /package/{template → template-vite}/components/table-properties/draggable-list.ts +0 -0
- /package/{template → template-vite}/components/table-properties/drawer-button.tsx +0 -0
- /package/{template → template-vite}/components/table-properties/drawer.tsx +0 -0
- /package/{template → template-vite}/components/table-properties/filter-card.tsx +0 -0
- /package/{template → template-vite}/components/table-properties/index.ts +0 -0
- /package/{template → template-vite}/components/table-properties/sort-card.tsx +0 -0
- /package/{template → template-vite}/components/table-properties/types.ts +0 -0
- /package/{template → template-vite}/components/task-list-panel.tsx +0 -0
- /package/{template → template-vite}/components/task-priority-badge.tsx +0 -0
- /package/{template → template-vite}/components/templates/dedicated-search-landing-template.tsx +0 -0
- /package/{template → template-vite}/components/templates/dedicated-search-results-template.tsx +0 -0
- /package/{template → template-vite}/components/templates/list-page.tsx +0 -0
- /package/{template → template-vite}/components/templates/nested-secondary-panel-shell.tsx +0 -0
- /package/{template → template-vite}/components/templates/primary-page-template.tsx +0 -0
- /package/{template → template-vite}/components/templates/secondary-panel-hub-template.tsx +0 -0
- /package/{template → template-vite}/components/theme-color-sync.tsx +0 -0
- /package/{template → template-vite}/components/theme-provider.tsx +0 -0
- /package/{template → template-vite}/components/tinted-icon-disc.tsx +0 -0
- /package/{template → template-vite}/components/tokens-hub-auxiliary-views.tsx +0 -0
- /package/{template → template-vite}/components/tokens-themes-section.tsx +0 -0
- /package/{template → template-vite}/components/ui/accordion.tsx +0 -0
- /package/{template → template-vite}/components/ui/ai-thinking-surface.tsx +0 -0
- /package/{template → template-vite}/components/ui/alert-dialog.tsx +0 -0
- /package/{template → template-vite}/components/ui/avatar.tsx +0 -0
- /package/{template → template-vite}/components/ui/badge.tsx +0 -0
- /package/{template → template-vite}/components/ui/banner.tsx +0 -0
- /package/{template → template-vite}/components/ui/breadcrumb.tsx +0 -0
- /package/{template → template-vite}/components/ui/button.tsx +0 -0
- /package/{template → template-vite}/components/ui/calendar.tsx +0 -0
- /package/{template → template-vite}/components/ui/card.tsx +0 -0
- /package/{template → template-vite}/components/ui/chart.tsx +0 -0
- /package/{template → template-vite}/components/ui/checkbox.tsx +0 -0
- /package/{template → template-vite}/components/ui/coach-mark.tsx +0 -0
- /package/{template → template-vite}/components/ui/collapsible.tsx +0 -0
- /package/{template → template-vite}/components/ui/command.tsx +0 -0
- /package/{template → template-vite}/components/ui/context-menu.tsx +0 -0
- /package/{template → template-vite}/components/ui/date-picker-field.tsx +0 -0
- /package/{template → template-vite}/components/ui/dialog.tsx +0 -0
- /package/{template → template-vite}/components/ui/dot-pattern.tsx +0 -0
- /package/{template → template-vite}/components/ui/drag-handle-grip.tsx +0 -0
- /package/{template → template-vite}/components/ui/dropdown-menu.tsx +0 -0
- /package/{template → template-vite}/components/ui/field.tsx +0 -0
- /package/{template → template-vite}/components/ui/form.tsx +0 -0
- /package/{template → template-vite}/components/ui/hover-card.tsx +0 -0
- /package/{template → template-vite}/components/ui/input-group.tsx +0 -0
- /package/{template → template-vite}/components/ui/input-mask.tsx +0 -0
- /package/{template → template-vite}/components/ui/input.tsx +0 -0
- /package/{template → template-vite}/components/ui/kbd.tsx +0 -0
- /package/{template → template-vite}/components/ui/label.tsx +0 -0
- /package/{template → template-vite}/components/ui/leo-icon.tsx +0 -0
- /package/{template → template-vite}/components/ui/payment-card-fields.tsx +0 -0
- /package/{template → template-vite}/components/ui/popover.tsx +0 -0
- /package/{template → template-vite}/components/ui/radio-group.tsx +0 -0
- /package/{template → template-vite}/components/ui/resizable.tsx +0 -0
- /package/{template → template-vite}/components/ui/scroll-area.tsx +0 -0
- /package/{template → template-vite}/components/ui/select.tsx +0 -0
- /package/{template → template-vite}/components/ui/selection-tile-grid.tsx +0 -0
- /package/{template → template-vite}/components/ui/separator.tsx +0 -0
- /package/{template → template-vite}/components/ui/sheet.tsx +0 -0
- /package/{template → template-vite}/components/ui/sidebar.tsx +0 -0
- /package/{template → template-vite}/components/ui/skeleton.tsx +0 -0
- /package/{template → template-vite}/components/ui/slider.tsx +0 -0
- /package/{template → template-vite}/components/ui/sonner.tsx +0 -0
- /package/{template → template-vite}/components/ui/status-badge.tsx +0 -0
- /package/{template → template-vite}/components/ui/table.tsx +0 -0
- /package/{template → template-vite}/components/ui/tabs.tsx +0 -0
- /package/{template → template-vite}/components/ui/textarea.tsx +0 -0
- /package/{template → template-vite}/components/ui/tip.tsx +0 -0
- /package/{template → template-vite}/components/ui/toggle-group.tsx +0 -0
- /package/{template → template-vite}/components/ui/toggle-switch.tsx +0 -0
- /package/{template → template-vite}/components/ui/toggle.tsx +0 -0
- /package/{template → template-vite}/components/ui/tooltip.tsx +0 -0
- /package/{template → template-vite}/components/ui/view-segmented-control.tsx +0 -0
- /package/{template → template-vite}/components.json +0 -0
- /package/{template → template-vite}/contexts/chart-variant-context.tsx +0 -0
- /package/{template → template-vite}/contexts/command-menu-context.tsx +0 -0
- /package/{template → template-vite}/contexts/dashboard-view-context.tsx +0 -0
- /package/{template → template-vite}/contexts/product-context.tsx +0 -0
- /package/{template → template-vite}/contexts/system-banner-context.tsx +0 -0
- /package/{template → template-vite}/eslint.config.mjs +0 -0
- /package/{template → template-vite}/fontawesome-subset.manifest.json +0 -0
- /package/{template → template-vite}/hooks/.gitkeep +0 -0
- /package/{template → template-vite}/hooks/use-app-theme.ts +0 -0
- /package/{template → template-vite}/hooks/use-coach-mark.ts +0 -0
- /package/{template → template-vite}/hooks/use-location-hash.ts +0 -0
- /package/{template → template-vite}/hooks/use-mobile.ts +0 -0
- /package/{template → template-vite}/hooks/use-mod-key-label.ts +0 -0
- /package/{template → template-vite}/hooks/use-sidebar-reflow-zoom.ts +0 -0
- /package/{template → template-vite}/lib/.gitkeep +0 -0
- /package/{template → template-vite}/lib/ask-leo-route-context.ts +0 -0
- /package/{template → template-vite}/lib/chart-keyboard-selection.test.ts +0 -0
- /package/{template → template-vite}/lib/chart-keyboard-selection.ts +0 -0
- /package/{template → template-vite}/lib/chart-line-dash.ts +0 -0
- /package/{template → template-vite}/lib/chunk-load-error.ts +0 -0
- /package/{template → template-vite}/lib/coach-mark-registry.ts +0 -0
- /package/{template → template-vite}/lib/collaborator-access.ts +0 -0
- /package/{template → template-vite}/lib/command-menu-config.ts +0 -0
- /package/{template → template-vite}/lib/command-menu-search-data.ts +0 -0
- /package/{template → template-vite}/lib/conditional-rule-match.ts +0 -0
- /package/{template → template-vite}/lib/dashboard-customize-coach-mark.ts +0 -0
- /package/{template → template-vite}/lib/dashboard-layout-merge.ts +0 -0
- /package/{template → template-vite}/lib/data-list-display-options.ts +0 -0
- /package/{template → template-vite}/lib/data-list-persistence.ts +0 -0
- /package/{template → template-vite}/lib/data-list-view-registry.ts +0 -0
- /package/{template → template-vite}/lib/data-list-view-surface.ts +0 -0
- /package/{template → template-vite}/lib/data-list-view.ts +0 -0
- /package/{template → template-vite}/lib/data-view-dashboard-storage.ts +0 -0
- /package/{template → template-vite}/lib/date-filter.ts +0 -0
- /package/{template → template-vite}/lib/dedicated-search-recents.ts +0 -0
- /package/{template → template-vite}/lib/dedicated-search-url.ts +0 -0
- /package/{template → template-vite}/lib/dev-log.test.ts +0 -0
- /package/{template → template-vite}/lib/dev-log.ts +0 -0
- /package/{template → template-vite}/lib/discovery-hub.ts +0 -0
- /package/{template → template-vite}/lib/editable-target.ts +0 -0
- /package/{template → template-vite}/lib/exxat-palette.json +0 -0
- /package/{template → template-vite}/lib/exxat-palette.ts +0 -0
- /package/{template → template-vite}/lib/floating-sheet-panel.ts +0 -0
- /package/{template → template-vite}/lib/full-hub-supported-views.ts +0 -0
- /package/{template → template-vite}/lib/hub-connected-view-renderers.ts +0 -0
- /package/{template → template-vite}/lib/initials-from-name.ts +0 -0
- /package/{template → template-vite}/lib/library-authoring.ts +0 -0
- /package/{template → template-vite}/lib/library-dedicated-search.ts +0 -0
- /package/{template → template-vite}/lib/library-hub-search.ts +0 -0
- /package/{template → template-vite}/lib/library-nav.ts +0 -0
- /package/{template → template-vite}/lib/library-recent-searches.ts +0 -0
- /package/{template → template-vite}/lib/library-supported-views.ts +0 -0
- /package/{template → template-vite}/lib/list-hub-supported-views.ts +0 -0
- /package/{template → template-vite}/lib/list-page-table-properties.ts +0 -0
- /package/{template → template-vite}/lib/list-status-badges.ts +0 -0
- /package/{template → template-vite}/lib/logo-dev.ts +0 -0
- /package/{template → template-vite}/lib/mailto.ts +0 -0
- /package/{template → template-vite}/lib/mock/dashboard.ts +0 -0
- /package/{template → template-vite}/lib/mock/library-folders.ts +0 -0
- /package/{template → template-vite}/lib/mock/library-header-collaborators.ts +0 -0
- /package/{template → template-vite}/lib/mock/library-inspector.ts +0 -0
- /package/{template → template-vite}/lib/mock/library-kpi.ts +0 -0
- /package/{template → template-vite}/lib/mock/library.ts +0 -0
- /package/{template → template-vite}/lib/mock/navigation.tsx +0 -0
- /package/{template → template-vite}/lib/motion-ui.ts +0 -0
- /package/{template → template-vite}/lib/product-brand.ts +0 -0
- /package/{template → template-vite}/lib/raf-throttle.ts +0 -0
- /package/{template → template-vite}/lib/row-height.ts +0 -0
- /package/{template → template-vite}/lib/sidebar-state-cookie.ts +0 -0
- /package/{template → template-vite}/lib/stock-portrait.ts +0 -0
- /package/{template → template-vite}/lib/table-state-lifecycle.ts +0 -0
- /package/{template → template-vite}/lib/utils.test.ts +0 -0
- /package/{template → template-vite}/lib/utils.ts +0 -0
- /package/{template → template-vite}/public/.gitkeep +0 -0
- /package/{template → template-vite}/public/Illustration/Rotation.svg +0 -0
- /package/{template → template-vite}/public/avatars/user.svg +0 -0
- /package/{template/public → template-vite/public/favicon}/favicon.ico +0 -0
- /package/{template/app → template-vite/public}/favicon.ico +0 -0
- /package/{template → template-vite}/public/folders/icons8-folder-windows-11.svg +0 -0
- /package/{template → template-vite}/public/logos/exxat-one.svg +0 -0
- /package/{template → template-vite}/public/logos/exxat-prism.svg +0 -0
- /package/{template → template-vite}/public/mock-schools/emory.svg +0 -0
- /package/{template → template-vite}/public/mock-schools/rush.svg +0 -0
- /package/{template → template-vite}/scripts/fontawesome-subset-audit.mjs +0 -0
- /package/{template → template-vite}/scripts/pm2-startup-macos.sh +0 -0
- /package/{template → template-vite}/skills-lock.json +0 -0
- /package/{template/app/(app)/columns/page.tsx → template-vite/src/pages/columns.tsx} +0 -0
- /package/{template/app/(app)/library/find/page.tsx → template-vite/src/pages/library/find.tsx} +0 -0
- /package/{template/app/(app)/library/page.tsx → template-vite/src/pages/library/index.tsx} +0 -0
- /package/{template/app/(app)/library/list/page.tsx → template-vite/src/pages/library/list.tsx} +0 -0
- /package/{template/app/(app)/settings/page.tsx → template-vite/src/pages/settings.tsx} +0 -0
- /package/{template/app/(app)/tokens-themes/page.tsx → template-vite/src/pages/tokens-themes.tsx} +0 -0
- /package/{template → template-vite}/stores/app-store.ts +0 -0
- /package/{template → template-vite}/types/react-payment-inputs.d.ts +0 -0
|
@@ -1,101 +0,0 @@
|
|
|
1
|
-
# Icons
|
|
2
|
-
|
|
3
|
-
**Always use the project's configured `iconLibrary` for imports.** Check the `iconLibrary` field from project context: `lucide` → `lucide-react`, `tabler` → `@tabler/icons-react`, etc. Never assume `lucide-react`.
|
|
4
|
-
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
## Icons in Button use data-icon attribute
|
|
8
|
-
|
|
9
|
-
Add `data-icon="inline-start"` (prefix) or `data-icon="inline-end"` (suffix) to the icon. No sizing classes on the icon.
|
|
10
|
-
|
|
11
|
-
**Incorrect:**
|
|
12
|
-
|
|
13
|
-
```tsx
|
|
14
|
-
<Button>
|
|
15
|
-
<SearchIcon className="mr-2 size-4" />
|
|
16
|
-
Search
|
|
17
|
-
</Button>
|
|
18
|
-
```
|
|
19
|
-
|
|
20
|
-
**Correct:**
|
|
21
|
-
|
|
22
|
-
```tsx
|
|
23
|
-
<Button>
|
|
24
|
-
<SearchIcon data-icon="inline-start"/>
|
|
25
|
-
Search
|
|
26
|
-
</Button>
|
|
27
|
-
|
|
28
|
-
<Button>
|
|
29
|
-
Next
|
|
30
|
-
<ArrowRightIcon data-icon="inline-end"/>
|
|
31
|
-
</Button>
|
|
32
|
-
```
|
|
33
|
-
|
|
34
|
-
---
|
|
35
|
-
|
|
36
|
-
## No sizing classes on icons inside components
|
|
37
|
-
|
|
38
|
-
Components handle icon sizing via CSS. Don't add `size-4`, `w-4 h-4`, or other sizing classes to icons inside `Button`, `DropdownMenuItem`, `Alert`, `Sidebar*`, or other shadcn components. Unless the user explicitly asks for custom icon sizes.
|
|
39
|
-
|
|
40
|
-
**Incorrect:**
|
|
41
|
-
|
|
42
|
-
```tsx
|
|
43
|
-
<Button>
|
|
44
|
-
<SearchIcon className="size-4" data-icon="inline-start" />
|
|
45
|
-
Search
|
|
46
|
-
</Button>
|
|
47
|
-
|
|
48
|
-
<DropdownMenuItem>
|
|
49
|
-
<SettingsIcon className="mr-2 size-4" />
|
|
50
|
-
Settings
|
|
51
|
-
</DropdownMenuItem>
|
|
52
|
-
```
|
|
53
|
-
|
|
54
|
-
**Correct:**
|
|
55
|
-
|
|
56
|
-
```tsx
|
|
57
|
-
<Button>
|
|
58
|
-
<SearchIcon data-icon="inline-start" />
|
|
59
|
-
Search
|
|
60
|
-
</Button>
|
|
61
|
-
|
|
62
|
-
<DropdownMenuItem>
|
|
63
|
-
<SettingsIcon />
|
|
64
|
-
Settings
|
|
65
|
-
</DropdownMenuItem>
|
|
66
|
-
```
|
|
67
|
-
|
|
68
|
-
---
|
|
69
|
-
|
|
70
|
-
## Pass icons as component objects, not string keys
|
|
71
|
-
|
|
72
|
-
Use `icon={CheckIcon}`, not a string key to a lookup map.
|
|
73
|
-
|
|
74
|
-
**Incorrect:**
|
|
75
|
-
|
|
76
|
-
```tsx
|
|
77
|
-
const iconMap = {
|
|
78
|
-
check: CheckIcon,
|
|
79
|
-
alert: AlertIcon,
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
function StatusBadge({ icon }: { icon: string }) {
|
|
83
|
-
const Icon = iconMap[icon]
|
|
84
|
-
return <Icon />
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
<StatusBadge icon="check" />
|
|
88
|
-
```
|
|
89
|
-
|
|
90
|
-
**Correct:**
|
|
91
|
-
|
|
92
|
-
```tsx
|
|
93
|
-
// Import from the project's configured iconLibrary (e.g. lucide-react, @tabler/icons-react).
|
|
94
|
-
import { CheckIcon } from "lucide-react"
|
|
95
|
-
|
|
96
|
-
function StatusBadge({ icon: Icon }: { icon: React.ComponentType }) {
|
|
97
|
-
return <Icon />
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
<StatusBadge icon={CheckIcon} />
|
|
101
|
-
```
|
|
@@ -1,162 +0,0 @@
|
|
|
1
|
-
# Styling & Customization
|
|
2
|
-
|
|
3
|
-
See [customization.md](../customization.md) for theming, CSS variables, and adding custom colors.
|
|
4
|
-
|
|
5
|
-
## Contents
|
|
6
|
-
|
|
7
|
-
- Semantic colors
|
|
8
|
-
- Built-in variants first
|
|
9
|
-
- className for layout only
|
|
10
|
-
- No space-x-* / space-y-*
|
|
11
|
-
- Prefer size-* over w-* h-* when equal
|
|
12
|
-
- Prefer truncate shorthand
|
|
13
|
-
- No manual dark: color overrides
|
|
14
|
-
- Use cn() for conditional classes
|
|
15
|
-
- No manual z-index on overlay components
|
|
16
|
-
|
|
17
|
-
---
|
|
18
|
-
|
|
19
|
-
## Semantic colors
|
|
20
|
-
|
|
21
|
-
**Incorrect:**
|
|
22
|
-
|
|
23
|
-
```tsx
|
|
24
|
-
<div className="bg-blue-500 text-white">
|
|
25
|
-
<p className="text-gray-600">Secondary text</p>
|
|
26
|
-
</div>
|
|
27
|
-
```
|
|
28
|
-
|
|
29
|
-
**Correct:**
|
|
30
|
-
|
|
31
|
-
```tsx
|
|
32
|
-
<div className="bg-primary text-primary-foreground">
|
|
33
|
-
<p className="text-muted-foreground">Secondary text</p>
|
|
34
|
-
</div>
|
|
35
|
-
```
|
|
36
|
-
|
|
37
|
-
---
|
|
38
|
-
|
|
39
|
-
## No raw color values for status/state indicators
|
|
40
|
-
|
|
41
|
-
For positive, negative, or status indicators, use Badge variants, semantic tokens like `text-destructive`, or define custom CSS variables — don't reach for raw Tailwind colors.
|
|
42
|
-
|
|
43
|
-
**Incorrect:**
|
|
44
|
-
|
|
45
|
-
```tsx
|
|
46
|
-
<span className="text-emerald-600">+20.1%</span>
|
|
47
|
-
<span className="text-green-500">Active</span>
|
|
48
|
-
<span className="text-red-600">-3.2%</span>
|
|
49
|
-
```
|
|
50
|
-
|
|
51
|
-
**Correct:**
|
|
52
|
-
|
|
53
|
-
```tsx
|
|
54
|
-
<Badge variant="secondary">+20.1%</Badge>
|
|
55
|
-
<Badge>Active</Badge>
|
|
56
|
-
<span className="text-destructive">-3.2%</span>
|
|
57
|
-
```
|
|
58
|
-
|
|
59
|
-
If you need a success/positive color that doesn't exist as a semantic token, use a Badge variant or ask the user about adding a custom CSS variable to the theme (see [customization.md](../customization.md)).
|
|
60
|
-
|
|
61
|
-
---
|
|
62
|
-
|
|
63
|
-
## Built-in variants first
|
|
64
|
-
|
|
65
|
-
**Incorrect:**
|
|
66
|
-
|
|
67
|
-
```tsx
|
|
68
|
-
<Button className="border border-input bg-transparent hover:bg-accent">
|
|
69
|
-
Click me
|
|
70
|
-
</Button>
|
|
71
|
-
```
|
|
72
|
-
|
|
73
|
-
**Correct:**
|
|
74
|
-
|
|
75
|
-
```tsx
|
|
76
|
-
<Button variant="outline">Click me</Button>
|
|
77
|
-
```
|
|
78
|
-
|
|
79
|
-
---
|
|
80
|
-
|
|
81
|
-
## className for layout only
|
|
82
|
-
|
|
83
|
-
Use `className` for layout (e.g. `max-w-md`, `mx-auto`, `mt-4`), **not** for overriding component colors or typography. To change colors, use semantic tokens, built-in variants, or CSS variables.
|
|
84
|
-
|
|
85
|
-
**Incorrect:**
|
|
86
|
-
|
|
87
|
-
```tsx
|
|
88
|
-
<Card className="bg-blue-100 text-blue-900 font-bold">
|
|
89
|
-
<CardContent>Dashboard</CardContent>
|
|
90
|
-
</Card>
|
|
91
|
-
```
|
|
92
|
-
|
|
93
|
-
**Correct:**
|
|
94
|
-
|
|
95
|
-
```tsx
|
|
96
|
-
<Card className="max-w-md mx-auto">
|
|
97
|
-
<CardContent>Dashboard</CardContent>
|
|
98
|
-
</Card>
|
|
99
|
-
```
|
|
100
|
-
|
|
101
|
-
To customize a component's appearance, prefer these approaches in order:
|
|
102
|
-
1. **Built-in variants** — `variant="outline"`, `variant="destructive"`, etc.
|
|
103
|
-
2. **Semantic color tokens** — `bg-primary`, `text-muted-foreground`.
|
|
104
|
-
3. **CSS variables** — define custom colors in the global CSS file (see [customization.md](../customization.md)).
|
|
105
|
-
|
|
106
|
-
---
|
|
107
|
-
|
|
108
|
-
## No space-x-* / space-y-*
|
|
109
|
-
|
|
110
|
-
Use `gap-*` instead. `space-y-4` → `flex flex-col gap-4`. `space-x-2` → `flex gap-2`.
|
|
111
|
-
|
|
112
|
-
```tsx
|
|
113
|
-
<div className="flex flex-col gap-4">
|
|
114
|
-
<Input />
|
|
115
|
-
<Input />
|
|
116
|
-
<Button>Submit</Button>
|
|
117
|
-
</div>
|
|
118
|
-
```
|
|
119
|
-
|
|
120
|
-
---
|
|
121
|
-
|
|
122
|
-
## Prefer size-* over w-* h-* when equal
|
|
123
|
-
|
|
124
|
-
`size-10` not `w-10 h-10`. Applies to icons, avatars, skeletons, etc.
|
|
125
|
-
|
|
126
|
-
---
|
|
127
|
-
|
|
128
|
-
## Prefer truncate shorthand
|
|
129
|
-
|
|
130
|
-
`truncate` not `overflow-hidden text-ellipsis whitespace-nowrap`.
|
|
131
|
-
|
|
132
|
-
---
|
|
133
|
-
|
|
134
|
-
## No manual dark: color overrides
|
|
135
|
-
|
|
136
|
-
Use semantic tokens — they handle light/dark via CSS variables. `bg-background text-foreground` not `bg-white dark:bg-gray-950`.
|
|
137
|
-
|
|
138
|
-
---
|
|
139
|
-
|
|
140
|
-
## Use cn() for conditional classes
|
|
141
|
-
|
|
142
|
-
Use the `cn()` utility from the project for conditional or merged class names. Don't write manual ternaries in className strings.
|
|
143
|
-
|
|
144
|
-
**Incorrect:**
|
|
145
|
-
|
|
146
|
-
```tsx
|
|
147
|
-
<div className={`flex items-center ${isActive ? "bg-primary text-primary-foreground" : "bg-muted"}`}>
|
|
148
|
-
```
|
|
149
|
-
|
|
150
|
-
**Correct:**
|
|
151
|
-
|
|
152
|
-
```tsx
|
|
153
|
-
import { cn } from "@/lib/utils"
|
|
154
|
-
|
|
155
|
-
<div className={cn("flex items-center", isActive ? "bg-primary text-primary-foreground" : "bg-muted")}>
|
|
156
|
-
```
|
|
157
|
-
|
|
158
|
-
---
|
|
159
|
-
|
|
160
|
-
## No manual z-index on overlay components
|
|
161
|
-
|
|
162
|
-
`Dialog`, `Sheet`, `Drawer`, `AlertDialog`, `DropdownMenu`, `Popover`, `Tooltip`, `HoverCard` handle their own stacking. Never add `z-50` or `z-[999]`.
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
description: Exxat DS — WCAG 2.1 AA, ARIA tablists, 24px targets, contrast; see AGENTS.md §8
|
|
3
|
-
alwaysApply: true
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# Exxat DS — accessibility (binding summary)
|
|
7
|
-
|
|
8
|
-
**Full checklist:** monorepo **`.cursor/skills/exxat-accessibility/SKILL.md`** when the parent repo is open.
|
|
9
|
-
|
|
10
|
-
**Product rules:** **`./AGENTS.md` §8**.
|
|
11
|
-
|
|
12
|
-
## Non‑negotiables
|
|
13
|
-
|
|
14
|
-
1. **Target:** **WCAG 2.1 Level AA** (2.2 where noted — e.g. target size).
|
|
15
|
-
2. **`role="tablist"`** — only **`role="tab"`** as tab semantics. **MUST NOT** put `role="button"`, menus (`aria-haspopup`), or other controls **inside** the same **`tablist`** container.
|
|
16
|
-
3. **Composite view switchers** (tabs + per-tab menu + remove): **`role="toolbar"`** + **`aria-label`**; **`aria-pressed`** on toggles — **MUST NOT** misuse `tab`/`tablist`.
|
|
17
|
-
4. **Touch targets (2.5.8):** **≥ 24×24 CSS px** or **24px** spacing — **`min-h-6 min-w-6` / `size-6`** for icon-only; avoid **`size-4`** as sole target.
|
|
18
|
-
5. **Contrast:** normal text **≥ 4.5:1**; UI / focus **≥ 3:1** where required; muted on tinted surfaces use correct surface tokens.
|
|
19
|
-
6. **Minimum text size:** visible product copy **≥ 11px** — **`text-xs`** or larger (**`AGENTS.md` §8.3**, **`app/globals.css`** `--text-xs`).
|
|
20
|
-
7. **Dialogs / sheets:** must have a **Title** (`DialogTitle` / `SheetTitle`); **`sr-only`** if hidden.
|
|
21
|
-
8. **Format hints persistent, not placeholders (SC 3.3.2, 1.3.1).** Fields with required formats — **date, time, phone, currency, GPA, IDs, URLs, unit-bearing numbers** — MUST render the format via **`FormDescription`** (or equivalent `aria-describedby` helper text). Placeholders disappear on focus and **MUST NOT** be the sole carrier. Prefer picker primitives (e.g. `DatePickerField`) over free-text where available.
|
|
22
|
-
9. **Every icon that communicates information MUST have a text alternative** — not just icon-only buttons. Three cases (SC 1.1.1, 3.3.2, 2.4.6):
|
|
23
|
-
|
|
24
|
-
- **A. Decorative icon next to text that already names it** (`<i class="fa-light fa-calendar-days" aria-hidden /> 12/14/2025`) → icon is `aria-hidden`, no `aria-label`, no tooltip. The text is the alt.
|
|
25
|
-
- **B. Informational icon standing alone** (calendar = "date range", clock = "updated at", pin = "site", cap = "student", trend arrow, status dot, icon-only chart legend) → MUST pair **`role="img"` + `aria-label`** with a visible **`Tooltip`**. Wrapper MUST be keyboard-focusable (`tabIndex={0}`) so the tooltip opens on focus too.
|
|
26
|
-
- **C. Interactive icon-only button/link** (close `×`, chevron, overflow `⋯`, sort, filter-dismiss, copy, Ask Leo toggle, row actions) → MUST pair **`aria-label`** on the `<button>` with a wrapping **`Tooltip`**. `aria-label` alone is not enough — sighted users rely on the tooltip too.
|
|
27
|
-
|
|
28
|
-
In all cases the inner `<i>` / `<svg>` is `aria-hidden`; tooltip text matches the accessible name. Narrow exception: chevron inside a labelled composite (`Select`, `Combobox`). See **`AGENTS.md` §8.6 (Case A/B/C)**.
|
|
29
|
-
10. **Keyboard shortcut hints inside buttons** MUST use **`<Kbd variant="bare">`** (no background/border, inherits `currentColor` at 70%). The default `tile` variant is for **tooltips** and **menu `shortcut=` slots** only. Glue multi-key chords into one bare kbd (e.g. `<Kbd variant="bare">⌘⌥K</Kbd>`). Reference: Next/Back in `new-library-item-form.tsx`; see **`.cursor/rules/exxat-kbd-shortcuts.mdc`**.
|
|
30
|
-
|
|
31
|
-
Re-run **axe** on **Placements** (or affected page) after changing **views toolbar** or **tabs**.
|
|
32
|
-
|
|
33
|
-
**Charts:** Keyboard exploration uses **`ChartFigure`**; selected points use **`chart-keyboard-selection`** (ring/stroke parity with gallery) — see **`AGENTS.md` §4.3** and **`.cursor/rules/exxat-dashboard-view-charts.mdc`**.
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
description: Exxat DS — product data tables must use DataTable with search, filters, and table properties; no alternate table stacks.
|
|
3
|
-
alwaysApply: true
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# Exxat DS — data tables (mandatory pattern)
|
|
7
|
-
|
|
8
|
-
## Use one stack for product data lists
|
|
9
|
-
|
|
10
|
-
For **any app screen that shows a browsable, filterable grid of records** (directories, tokens, columns showcase, question banks, etc.):
|
|
11
|
-
|
|
12
|
-
1. **Base table:** `DataTable` from `@/components/data-table` (optionally wrapped with `DataTablePaginated` when pagination is required).
|
|
13
|
-
2. **Search:** Wire the table’s search/query UX (toolbar search or equivalent) — do not ship a “bare” table without find-in-list behavior when the page is a data list.
|
|
14
|
-
3. **Filters:** Use the shared filter model (filter chips / `FilterFieldDef` and operators) consistent with existing list pages — not one-off filter UIs that bypass the table stack.
|
|
15
|
-
4. **Table properties:** Include **Table properties** via `TablePropertiesDrawer` from `@/components/table-properties/drawer` (or the same toolbar + drawer pattern used on the reference pages — `library-table.tsx`, `columns-showcase.tsx`, `tokens-themes-client.tsx`). Users must be able to adjust columns, density, and related table settings from one place.
|
|
16
|
-
5. **Active view:** On **`ListPageTemplate`** pages with **table / list / board / dashboard** tabs, **`TablePropertiesDrawer`** **MUST** receive **`currentView`** and **`onViewChange`** (see **`./AGENTS.md` §4.2** and **`.cursor/rules/exxat-table-properties-drawer.mdc`**) so Properties matches the selected view (not table-only copy on Board).
|
|
17
|
-
6. **Dropdown menus:** **`DropdownMenuContent`** uses the shared **`@exxatdesignux/ui`** default (**intrinsic `w-max`**, **`min-w-52`**, capped **`max-w`**) for view settings, row ⋯, column menus, and filter pickers — **pure CSS**, no **`ResizeObserver`**. Override only for deliberate narrow/wide rails (e.g. pagination **`w-20`**, account trigger-width, school switcher **`!w-max min-w-72 …`**). See **`docs/data-views-pattern.md`** (“Dropdown menus”).
|
|
18
|
-
|
|
19
|
-
**Reference implementations:** `components/library-table.tsx` (full hub: table / board / dashboard, conditional rules, bulk actions), `components/columns-showcase.tsx` (catalog hub composing every `table-cells.tsx` primitive — built-in pagination via `HubTable`), and `components/tokens-themes-client.tsx` (table + secondary-panel category rail). Each shows how `HubTable`, filters, and `TablePropertiesDrawer` compose together.
|
|
20
|
-
|
|
21
|
-
## Do not
|
|
22
|
-
|
|
23
|
-
- Do **not** build product list pages with `@/components/ui/table` alone, raw `<table>` markup, or third-party data grids.
|
|
24
|
-
- Do **not** introduce a second “table component” pattern for the same product surfaces (splitting search/filters/properties across incompatible implementations).
|
|
25
|
-
|
|
26
|
-
## Exceptions
|
|
27
|
-
|
|
28
|
-
- **Tiny, read-only tables inside charts or analytics cards** (e.g. chart figure captions / summary matrices) may use minimal markup when they are not primary data-list experiences — still prefer tokens and accessibility, but the full DataTable stack is not required there.
|
|
29
|
-
|
|
30
|
-
## See also
|
|
31
|
-
|
|
32
|
-
- **`./AGENTS.md`** — full MUST/MUST NOT, list-page template, primary hubs, checklist.
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
description: Exxat DS — follow AGENTS.md; DataTable, ListPageTemplate, primary hubs, export, Kbd
|
|
3
|
-
alwaysApply: true
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# Exxat DS — AI handbook (binding)
|
|
7
|
-
|
|
8
|
-
**Read `./AGENTS.md` at this repo root** before implementing or reviewing list/table/board or data-heavy pages (rule precedence, MUST/MUST NOT, §4.1–§4.3, **§6.4** page vs drawer, **§6.5** no toast, §7.1 command palette, §13 checklist).
|
|
9
|
-
|
|
10
|
-
## Non‑negotiables (if anything conflicts, open AGENTS.md §12–§13)
|
|
11
|
-
|
|
12
|
-
1. **Product data lists** → `DataTable` + search + shared filters + `TablePropertiesDrawer` — not raw `<table>` / ui `Table` alone / ad-hoc grids. With **`ListPageTemplate`** view tabs, pass **`currentView`** + **`onViewChange`** into **`TablePropertiesDrawer`** (**`AGENTS.md` §4.2**, **`.cursor/rules/exxat-table-properties-drawer.mdc`**).
|
|
13
|
-
2. **Main `DataTable` surface** → wrapped in **`ListPageTemplate`** (view tabs). All tab view types share **`useTableState`**; list/board/dashboard read **`tableState.rows`**. Reference: `PlacementsClient`, `TeamClient`, `TeamTable`.
|
|
14
|
-
3. **Do not double-indent** the toolbar/table — avoid extra `px`/`mx` wrappers around `DataTable` when it already applies horizontal inset.
|
|
15
|
-
4. **Primary hub + large/complex data** → same composition as Placements/Team: `ListPageTemplate` + metrics/export pattern as in `PlacementsClient` / `TeamClient`, not `PageHeader`-only.
|
|
16
|
-
5. **Exportable pages** → filled primary CTA; **⋯** menu with Export → `ExportDrawer` pattern (see `PlacementsPageHeader`).
|
|
17
|
-
6. **Keyboard hints** → `.cursor/rules/exxat-kbd-shortcuts.mdc`; pair hints with behavior.
|
|
18
|
-
7. **Accessibility** → `.cursor/rules/exxat-accessibility.mdc` + **`AGENTS.md` §8** + `.cursor/skills/exxat-accessibility/SKILL.md` when present in your workspace.
|
|
19
|
-
8. **Data view dashboard (charts)** → **`AGENTS.md` §4.3** + **`exxat-dashboard-view-charts.mdc`** — `ChartFigure`, centralized **`data-view-dashboard-storage`**, **`chart-keyboard-selection`** parity with the `/dashboard` gallery.
|
|
20
|
-
9. **No toast** → **`AGENTS.md` §6.5** + **`exxat-no-toast.mdc`** — do not use **`toast()`** / Sonner / snackbars for product messaging.
|
|
21
|
-
|
|
22
|
-
## Also read
|
|
23
|
-
|
|
24
|
-
- `docs/data-views-pattern.md` — architecture narrative (keep aligned with `AGENTS.md`); **Page vs drawer** with **`AGENTS.md` §6.4**.
|
|
25
|
-
- `docs/command-menu-pattern.md` — global ⌘K palette (search + quick AI vs Ask Leo).
|
|
26
|
-
- `.cursor/rules/exxat-data-tables.mdc`, `exxat-list-page-connected-views.mdc`, `exxat-table-properties-drawer.mdc`, **`exxat-page-vs-drawer.mdc`** (this folder; repo root copy when parent repo open), **`exxat-no-toast.mdc`**, **`exxat-dashboard-view-charts.mdc`** (this folder), **`exxat-command-menu.mdc`**, `exxat-kbd-shortcuts.mdc`, and `exxat-accessibility.mdc`.
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
description: ListPageTemplate — shared table state across views, mock + KPI helpers, dashboard tab
|
|
3
|
-
alwaysApply: true
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# Exxat DS — list page connected views
|
|
7
|
-
|
|
8
|
-
**Authoritative detail:** **`./AGENTS.md` §4.1** and **`docs/data-views-pattern.md`** (mock data, connected views, dashboard view).
|
|
9
|
-
|
|
10
|
-
## When building `ListPageTemplate` + data client
|
|
11
|
-
|
|
12
|
-
1. **One `useTableState` per tab’s table** — Pass full mock/API rows into a single table component; **`list` / `board` / `dashboard`** surfaces consume **`tableState.rows`** (same filters/search/sort as the grid).
|
|
13
|
-
2. **`renderContent`** — Always pass **`view={tab.viewType}`**; use **`key={tab.id}`** (not `viewType`) so switching views does not reset table state. Pass **`onViewChange`** into the table component so **`TablePropertiesDrawer`** stays aligned (**`currentView`** + **`updateTab({ viewType, icon: dataListViewIcon(viewType) })`** — see **`./AGENTS.md` §4.2** and **`.cursor/rules/exxat-table-properties-drawer.mdc`**).
|
|
14
|
-
3. **Mock data** — Typed arrays in **`lib/mock/<entity>.ts`**; KPI builders in **`lib/mock/<entity>-kpi.ts`** returning **`MetricItem[]`** / **`MetricInsight`** from **`@/components/key-metrics`**.
|
|
15
|
-
4. **Dashboard view tab** — Use **`KeyMetrics`** (`variant="flat"` or `"card"`) and the **same** KPI functions with **`tableState.rows`**. Do **not** add standalone `Card` metric grids that duplicate those numbers. For chart-heavy dashboards reuse **`ChartsOverview`** / **`DashboardTabs`** patterns from the main dashboard route when appropriate.
|
|
16
|
-
5. **MUST NOT** ship “not wired” / “switch to table” placeholders for list/board/dashboard when the stack supports those views.
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
description: TablePropertiesDrawer must receive currentView and onViewChange when used with ListPageTemplate view tabs
|
|
3
|
-
alwaysApply: true
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# Exxat DS — Table properties + active view
|
|
7
|
-
|
|
8
|
-
**Authoritative detail:** **`AGENTS.md` §4.2** (at repo root).
|
|
9
|
-
|
|
10
|
-
## Why this exists
|
|
11
|
-
|
|
12
|
-
`TablePropertiesDrawer` uses **`currentView`** (`DataListViewType`) for the first summary row (“Board display” vs “Table display”, matching icons/descriptions) and to show **table-only** vs **board-only** sub-panels. If **`currentView`** is omitted, the drawer assumes **table** — wrong when the tab is **Board**, **List**, or **Dashboard**.
|
|
13
|
-
|
|
14
|
-
## MUST
|
|
15
|
-
|
|
16
|
-
When **`ListPageTemplate`** drives **`tab.viewType`** and the page renders **`TablePropertiesDrawer`** (directly or via a toolbar slot):
|
|
17
|
-
|
|
18
|
-
1. Pass **`currentView={view}`** (same value as **`tab.viewType`** passed into your table component).
|
|
19
|
-
2. Pass **`onViewChange`** from **`renderContent={(tab, updateTab) => ...}`** so the drawer’s view-type tiles stay in sync with the tab:
|
|
20
|
-
|
|
21
|
-
```tsx
|
|
22
|
-
import { dataListViewIcon, type DataListViewType } from "@/lib/data-list-view"
|
|
23
|
-
|
|
24
|
-
onViewChange={(v: DataListViewType) =>
|
|
25
|
-
updateTab({ viewType: v, icon: dataListViewIcon(v) })
|
|
26
|
-
}
|
|
27
|
-
```
|
|
28
|
-
|
|
29
|
-
3. Thread **`view`** and **`onViewChange`** through: **client → table component → drawer toolbar → `TablePropertiesDrawer`**.
|
|
30
|
-
|
|
31
|
-
**Reference implementations:** `components/library-hub-client.tsx` + `library-table.tsx` (full hub: table / board / dashboard, conditional rules, bulk actions), `components/columns-showcase.tsx` (single-table catalog + built-in pagination via `HubTable`), `components/tokens-themes-client.tsx` (table + `SecondaryPanel` category rail).
|
|
32
|
-
|
|
33
|
-
## MUST NOT
|
|
34
|
-
|
|
35
|
-
- Mount **`TablePropertiesDrawer`** on a multi-view list page **without** **`currentView`** when the active view is known from the tab.
|
|
36
|
-
- Omit **`onViewChange`** if the product shows the **view type** control inside Properties (otherwise tiles cannot update the tab).
|
|
37
|
-
|
|
38
|
-
## See also
|
|
39
|
-
|
|
40
|
-
- **`./AGENTS.md` §4.2**, **§13** checklist
|
package/template/.nvmrc
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
24
|
package/template/.prettierignore
DELETED
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
<svg width="845" height="164" viewBox="0 0 845 164" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
2
|
-
<g clip-path="url(#clip0_73_1049)">
|
|
3
|
-
<path d="M60.56 142.305C94.0064 142.305 121.12 115.191 121.12 81.7451C121.12 48.2987 94.0064 21.1851 60.56 21.1851C27.1136 21.1851 0 48.2987 0 81.7451C0 115.191 27.1136 142.305 60.56 142.305Z" fill="url(#paint0_linear_73_1049)"/>
|
|
4
|
-
<path d="M0.490234 89.3652C3.79023 115.675 23.9702 136.725 49.8502 141.355L84.4302 110.265V98.6852H71.5502L84.4302 87.1052V75.5252H71.5502L84.4302 63.9452V52.3652H41.6602L0.490234 89.3652Z" fill="#BE1E6D"/>
|
|
5
|
-
<path d="M84.4397 110.265H41.6597L48.3497 98.6851H84.4397V110.265Z" fill="white"/>
|
|
6
|
-
<path d="M84.4397 63.935H48.3497L41.6597 52.355H84.4397V63.935Z" fill="white"/>
|
|
7
|
-
<path d="M84.44 87.0951H55.04L58.38 81.3051L55.04 75.5151H84.44V87.0951Z" fill="white"/>
|
|
8
|
-
<path d="M32.3198 75.5151H55.0398L48.3498 63.9351H32.3198V75.5151Z" fill="white"/>
|
|
9
|
-
<path d="M32.3198 98.6852H48.3498L55.0398 87.0952H32.3198V98.6852Z" fill="white"/>
|
|
10
|
-
</g>
|
|
11
|
-
<g clip-path="url(#clip1_73_1049)">
|
|
12
|
-
<path d="M516.224 35.7236L539.045 35.6448C548.902 35.625 559.716 34.8998 569.171 37.7297C585.061 42.4847 589.938 57.0863 585.808 72.1784C580.934 89.9788 559.598 94.2839 544.16 89.3496C544.351 93.6141 544.239 98.6862 544.245 103.011C544.219 108.886 543.484 116.871 546.468 122.242C548.536 125.968 552.34 124.047 553.976 126.463C553.706 127.638 552.504 127.799 551.372 127.789C542.691 127.708 534 127.796 525.316 127.765C522.622 127.756 518.799 127.94 516.227 127.341L516.102 126.775C519.23 122.746 524.611 126.79 524.921 115.051C525.418 96.2037 525.079 77.3564 525.181 58.4995C525.194 55.9626 525.161 53.3199 525.02 50.8087C524.542 42.2774 524.714 40.2086 516.276 37.7666C515.835 36.8568 516.026 36.8479 516.224 35.7236ZM561.758 81.7577C566.075 76.0378 567.208 72.0182 567.607 64.7877C568.193 54.1196 565.344 41.9079 552.274 41.5163C550.509 41.4632 548.73 41.5288 546.919 41.6016C546.122 41.9652 544.775 42.8401 544.588 43.8455C543.978 47.2131 544.117 51.0942 544.219 54.5488C544.456 62.5893 544.077 70.5968 544.127 78.6252C544.176 86.7181 553.374 86.2803 558.649 83.5938C559.72 83.0443 560.757 82.4312 561.758 81.7577Z" fill="#E31B79"/>
|
|
13
|
-
<path d="M402.818 55.8327C405.052 55.5377 410.074 55.66 412.311 55.837C423.661 56.7359 434.899 61.6492 437.377 73.8645C438.215 77.9916 437.996 82.5469 437.985 86.8025C437.977 92.7617 437.929 98.7208 437.839 104.68C437.771 110.573 437.002 112.867 443.417 113.143L443.425 127.935C435.329 127.94 423.442 129.682 420.634 119.91C413.623 128.59 403.51 130.322 392.744 128.652C386.398 127.668 380.94 124.729 377.251 119.341C374.341 114.429 373.846 108.153 375.083 102.656C377.954 90.5343 391.037 87.8972 401.558 86.4666C405.949 85.8693 419.888 84.6536 420.496 78.9129C421.531 69.1633 405.427 66.9952 399.222 71.6421C395.538 74.4015 395.056 77.1527 394.214 81.4294C388.59 81.2 382.169 81.3447 376.488 81.3849C377.656 64.6911 386.55 57.7136 402.818 55.8327ZM394.722 112.842C402.622 116.994 414.879 113.956 419.195 105.867C420.898 102.675 420.786 100.037 420.753 96.5686C420.676 96.4397 420.464 96.0521 420.367 95.9825C417.57 96.9217 415.105 97.5589 412.227 98.1463C405.998 99.4177 386.104 100.755 393.813 111.851C394.008 112.132 394.46 112.588 394.722 112.842Z" fill="#273441"/>
|
|
14
|
-
<path d="M285.842 57.092C288.383 57.0821 302.013 56.8534 303.49 57.3801C303.921 59.8946 296.385 70.3368 294.519 73.0942C290.393 79.1912 286.383 85.8209 282.086 91.7382L296.149 114.075C297.839 116.764 303.016 124.546 303.836 127.148C302.355 128.098 287.357 127.674 284.53 127.661C283.197 125.148 280.545 121.155 278.947 118.593C275.663 113.239 272.302 107.934 268.867 102.676C267.615 105.328 264.978 109.267 263.356 111.861L253.472 127.619C250.818 127.679 236.379 128.223 234.929 127.307C234.802 127.226 234.833 127.271 234.805 127.121C234.334 124.593 253.23 96.0195 256.079 91.7346C254.614 89.9792 253.162 87.6385 251.899 85.6936C246.461 77.3195 240.713 69.1346 235.418 60.6715C234.529 59.2505 234.261 58.7567 234.685 57.1032L252.113 57.0953C257.638 65.5363 263.657 74.0278 269.026 82.5146C273.446 74.8182 280.898 65.1741 285.842 57.092Z" fill="#273441"/>
|
|
15
|
-
<path d="M305.863 57.0737L323.379 57.1011C329.02 65.2052 335.012 74.2679 340.362 82.5632C345.285 74.7113 352.033 64.6471 357.386 57.0948C361.996 57.0674 369.815 56.7925 374.173 57.1818C376.244 58.9665 368.54 69.0402 367.023 71.3256L353.506 91.742C356.918 98.694 374.121 122.433 374.944 127.689C368.802 127.534 362.114 127.674 355.93 127.682C351.193 119.662 345.363 110.633 340.337 102.74C335.343 110.592 329.601 119.589 324.992 127.585C318.896 127.832 311.626 127.673 305.417 127.677C306.982 123.265 310.578 118.366 313.063 114.31C317.652 106.819 322.836 99.2867 327.267 91.7074C321.78 83.8363 316.645 75.6089 311.249 67.6613C309.415 64.9596 305.794 60.2636 305.863 57.0737Z" fill="#273441"/>
|
|
16
|
-
<path d="M454.026 36.0116C459.731 36.0271 465.436 36.0096 471.14 35.9585L471.16 57.0945L488.243 57.052L488.254 72.2463C482.683 72.1227 476.754 72.2229 471.155 72.2212L471.138 93.4004C471.135 97.6102 471.294 101.493 471.405 105.692C471.614 113.586 482.181 112.858 488.24 111.97L488.243 121.691L488.265 127.416C484.779 127.724 481.282 127.899 477.783 127.94C452.823 127.992 454.009 116.222 454.008 96.2313L454.009 72.2176C450.214 72.1859 446.419 72.2047 442.624 72.274C442.557 67.2104 442.563 62.1465 442.64 57.0833C443.23 57.0955 443.82 57.1018 444.409 57.1021C456.599 57.0942 454.076 44.6883 454.026 36.0116Z" fill="#273441"/>
|
|
17
|
-
<path d="M709.341 59.4712C716.161 59.8473 722.388 60.0978 728.658 62.9393C728.596 67.6956 729.116 72.4767 728.948 77.2304C728.915 78.25 728.625 78.2575 727.805 78.5895C726.149 78.3568 725.164 76.1287 724.331 74.7855C720.494 68.5946 713.855 63.7545 706.235 65.229C703.018 65.852 701.173 67.4402 699.448 70.0608C699.27 72.2558 698.99 76.0269 700.63 77.7446C708.168 85.6309 720.708 87.2873 728.365 95.1211C735.62 102.545 734.454 115.729 726.821 122.426C719.902 128.588 710.773 129.464 701.895 129.132C698.341 128.594 689.667 127.399 686.796 125.738C685.518 124.267 684.932 110.419 684.816 107.618L685.324 107.085C686.041 107.047 686.789 107.004 687.286 107.65C693.165 115.302 696.79 123.714 708.043 123.502C713.075 123.407 720.214 119.506 719.134 114.29C717.023 104.1 698.266 101.216 691.511 94.1994C687.54 90.077 685.36 87.1363 684.928 81.2675C684.793 65.2695 695.615 60.3273 709.341 59.4712Z" fill="#E31B79"/>
|
|
18
|
-
<path d="M618.055 70.3023C622.942 64.803 628.655 59.6719 636.542 60.0331C638.09 60.104 640.181 60.1933 641.587 60.8365C642.259 61.9866 638.782 76.3723 637.902 78.2548C635.943 78.7173 631.319 73.5997 628.408 73.0406C624.032 72.2007 621.786 73.8225 618.229 76.0014C618.437 79.0644 618.295 83.7093 618.288 86.8732L618.259 106.8C618.252 111.321 617.926 118.732 619.257 122.874C620.791 125.951 623.31 124.084 624.272 127.062L623.946 127.616C621.934 127.967 595.543 127.866 594.604 127.405C594.357 124.494 599.386 125.153 599.606 121.179C600.476 105.594 600.377 89.6685 599.732 74.0856C599.596 70.8189 593.995 67.4322 593.794 65.223C594.693 64.2789 614.389 60.52 617.165 60.0681L617.926 60.1713C618.796 61.2686 618.203 68.5635 618.055 70.3023Z" fill="#E31B79"/>
|
|
19
|
-
<path d="M671.456 60.0659L671.852 60.1147C673.07 61.728 670.436 114.857 673.459 123.901C674.924 124.763 678.053 125.34 677.648 127.371C676.251 128.137 652.159 127.715 648.348 127.662C648.045 127.023 648.138 126.807 648.292 126.107C648.954 125.397 650.802 124.955 651.813 124.637C652.261 123.884 652.718 123.058 652.975 122.219C654.365 117.667 654.21 81.5708 653.492 75.5704C653.209 73.2049 652.633 71.4493 651.53 69.3564C649.652 68.3464 646.85 67.491 647.746 65.0283C649.745 64.1607 668.736 60.3504 671.456 60.0659Z" fill="#E31B79"/>
|
|
20
|
-
<path d="M660.464 29.0874C666.085 27.8926 671.627 31.4201 672.932 37.0223C674.236 42.6241 670.821 48.2405 665.252 49.6553C661.55 50.5958 657.632 49.4605 655 46.6872C652.372 43.914 651.447 39.9353 652.58 36.2846C653.713 32.6341 656.729 29.8814 660.464 29.0874Z" fill="#E31B79"/>
|
|
21
|
-
<path d="M761.916 68.9873C765.581 65.9846 769.029 63.5459 773.531 61.9241C782.963 58.5285 794.742 58.5338 798.918 69.5262C799.61 69.5908 800.947 68.4074 801.605 67.8757C808.511 62.3085 818.884 58.2474 827.862 60.5298C841.12 63.901 839.358 80.4903 839.325 91.0205L839.262 111.901C839.256 115.431 838.9 120.475 840.685 123.589C841.396 124.831 843.267 125.24 844.568 125.534V127.647C839.022 127.927 832.702 127.69 827.097 127.775C824.693 127.811 817.643 127.894 815.585 127.5C815.189 126.534 815.216 126.934 815.555 125.874C816.879 124.858 819.632 125.262 819.978 122.643C821.746 109.29 821.101 93.9062 820.705 80.4959C820.297 66.6729 808.834 70.1054 800.397 74.8545C800.785 87.0695 800.242 99.8169 800.453 112.114C800.495 114.734 800.341 121.388 802.119 123.764C803.239 125.265 805.804 125.298 806.723 126.439L806.347 127.002C805.531 127.396 803.762 127.897 802.906 127.828C795.131 127.208 784.899 128.621 777.394 127.525C776.613 125.13 781.445 124.649 781.929 121.478C783.045 114.488 782.548 107.249 782.597 100.194C782.702 85.2196 785.768 60.2954 762.104 74.6161C762.308 78.0539 762.163 83.0849 762.163 86.6324L762.143 109.455C762.137 112.774 761.923 117.623 762.4 120.955C762.835 124.001 767.399 125.604 767.926 127.128L767.692 127.463C765.249 127.893 741.759 127.94 738.703 127.531C738.044 126.817 738.143 127.132 738.166 126.259C738.864 125.368 740.204 125.442 741.136 124.866C742.368 124.103 742.892 122.707 743.237 121.366C744.347 117.035 744.443 79.9484 743.652 74.8749C743.316 72.7155 742.266 70.9361 741.176 69.0881C739.793 68.3511 738.248 67.8405 737.435 66.6122C737.244 65.4908 737.168 65.9094 737.718 64.9278C740.27 64.0206 759.538 60.1982 762.209 60.0646C762.193 62.9836 762.242 66.1026 761.916 68.9873Z" fill="#E31B79"/>
|
|
22
|
-
<path d="M170.13 35.5752C189.392 35.5686 209.114 35.7911 228.335 35.5347C228.339 40.4077 228.22 45.8813 228.386 50.7056L187.397 50.7283C187.445 58.5473 187.443 66.3666 187.393 74.1856C199.283 74.1872 211.506 74.3409 223.368 74.1655L223.38 89.3357C211.424 89.2981 199.329 89.2147 187.376 89.3499C187.435 97.1307 187.447 104.912 187.41 112.692L230.17 112.697C230.192 117.588 230.294 122.754 230.163 127.622L170.13 127.589V35.5752Z" fill="#273441"/>
|
|
23
|
-
</g>
|
|
24
|
-
<defs>
|
|
25
|
-
<linearGradient id="paint0_linear_73_1049" x1="23.38" y1="125.015" x2="96.57" y2="39.8551" gradientUnits="userSpaceOnUse">
|
|
26
|
-
<stop offset="0.04" stop-color="#E21C79"/>
|
|
27
|
-
<stop offset="0.65" stop-color="#E21E7B"/>
|
|
28
|
-
<stop offset="0.73" stop-color="#E42880"/>
|
|
29
|
-
<stop offset="0.88" stop-color="#E9448E"/>
|
|
30
|
-
<stop offset="1" stop-color="#EF609D"/>
|
|
31
|
-
</linearGradient>
|
|
32
|
-
<clipPath id="clip0_73_1049">
|
|
33
|
-
<rect width="121.13" height="121.13" fill="white" transform="translate(0 21.1851)"/>
|
|
34
|
-
</clipPath>
|
|
35
|
-
<clipPath id="clip1_73_1049">
|
|
36
|
-
<rect width="674.438" height="163.5" fill="white" transform="translate(170.13)"/>
|
|
37
|
-
</clipPath>
|
|
38
|
-
</defs>
|
|
39
|
-
</svg>
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
<svg width="766" height="164" viewBox="0 0 766 164" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
2
|
-
<g clip-path="url(#clip0_73_1036)">
|
|
3
|
-
<path d="M73.4939 155.238C114.084 155.238 146.988 122.334 146.988 81.7439C146.988 41.1544 114.084 8.25 73.4939 8.25C32.9044 8.25 0 41.1544 0 81.7439C0 122.334 32.9044 155.238 73.4939 155.238Z" fill="url(#paint0_linear_73_1036)"/>
|
|
4
|
-
<path d="M0.594727 90.9915C4.59951 122.921 29.0894 148.466 60.4966 154.085L102.462 116.355V102.302H86.8312L102.462 88.2489V74.1957H86.8312L102.462 60.1425V46.0894H50.5575L0.594727 90.9915Z" fill="#BE1E6D"/>
|
|
5
|
-
<path d="M102.474 116.355H50.5576L58.6764 102.302H102.474V116.355Z" fill="white"/>
|
|
6
|
-
<path d="M102.474 60.1303H58.6764L50.5576 46.0771H102.474V60.1303Z" fill="white"/>
|
|
7
|
-
<path d="M102.474 88.2368H66.7949L70.8483 81.2102L66.7949 74.1836H102.474V88.2368Z" fill="white"/>
|
|
8
|
-
<path d="M39.2227 74.1835H66.795L58.6762 60.1304H39.2227V74.1835Z" fill="white"/>
|
|
9
|
-
<path d="M39.2227 102.302H58.6762L66.795 88.2368H39.2227V102.302Z" fill="white"/>
|
|
10
|
-
</g>
|
|
11
|
-
<g clip-path="url(#clip1_73_1036)">
|
|
12
|
-
<path d="M579.64 32.6512C592.027 32.3136 602.339 34.2511 611.886 42.8549C621.616 51.9225 625.419 64.8345 626.05 77.6623C627.31 103.322 613.505 127.896 585.51 129.148C585.162 129.199 584.811 129.234 584.461 129.252C574.085 129.753 562.004 126.318 554.126 119.188C536.921 103.616 535.647 72.9436 546.054 53.3303C552.613 40.9652 565.665 33.3388 579.64 32.6512ZM584.116 123.144C589.474 122.455 593.908 120.383 597.184 115.86C606.219 102.471 605.632 82.6132 604.178 67.1363C603.351 58.3677 600.264 47.6909 593.184 42.0268C590.322 39.7365 585.27 38.2385 581.604 38.7657C572.591 39.5696 567.54 44.6598 564.488 52.8846C558.062 70.2058 555.754 124.532 584.116 123.144Z" fill="#E31B79"/>
|
|
13
|
-
<path d="M430.755 55.7344C443.603 55.2553 459.709 58.3988 463.175 73.143C464.166 77.3587 463.884 82.6952 463.877 87.0408L463.845 105.91C463.857 112.149 463.051 112.645 469.328 113.205C469.057 117.66 469.234 123.628 469.242 128.194C461.169 128.149 448.96 129.818 446.764 119.668C444.471 122.422 443.567 123.605 440.357 125.604C433.884 129.636 423.423 129.934 416.178 128.172C410.382 126.762 405.62 123.519 402.512 118.29C400.527 114.233 400.122 109.477 400.649 105.072C402.505 89.5606 418.762 87.5983 431.172 85.928C435.522 85.237 440.828 84.6483 444.472 82.0073C447.548 79.7708 447.168 76.525 444.97 73.7922C440.68 68.4582 429.516 68.0981 424.356 72.2079C421.359 74.5939 420.834 77.8667 420.5 81.4362C414.437 81.3803 408.373 81.3842 402.31 81.4478C402.503 79.5217 402.653 77.3957 403.031 75.5059C405.774 61.7822 418.095 56.4115 430.755 55.7344ZM420.852 112.903C428.033 116.948 440.992 113.872 444.937 106.311C445.852 104.557 447.932 97.6766 446.702 95.9674L446.344 95.9145C442.708 97.4881 435.913 98.8678 431.795 99.3372C425.343 100.072 411.452 104.687 420.852 112.903Z" fill="#273441"/>
|
|
14
|
-
<path d="M677.935 59.0477C699.855 57.8913 696.583 76.9682 696.748 92.0377C696.845 100.807 696.517 109.637 697.098 118.395C697.259 120.816 697.771 123.787 700.211 124.947C701.104 125.374 701.849 125.466 702.614 126.131C702.778 127.168 702.853 126.832 702.5 127.735C699.251 128.44 678.411 127.93 673.804 127.775C673.206 127.755 672.953 127.462 672.68 127.015C673.231 125.409 675.671 125.143 677.582 123.199C679.398 114.08 678.719 105.254 678.844 95.9909C678.858 90.3513 678.931 84.9044 678.377 79.2797C677.042 65.7365 665.601 69.2473 656.927 73.9796C657.192 76.486 657.033 81.4311 657.025 84.1135L657 106.393C656.994 112.303 656.332 118.583 658.741 124.027C660.446 125.154 662.221 124.835 663.019 126.793C662.85 127.589 663.003 127.49 662.488 127.922C658.98 128.008 635.083 128.474 633.558 127.735C632.96 127.446 632.882 127.238 632.676 126.643C633.394 124.87 634.977 125.133 636.384 124.383C637.23 123.934 637.658 122.7 637.906 121.828C639.341 116.75 639.266 75.7628 637.889 71.6175C636.952 68.8035 633.614 67.9918 632.445 65.6353C632.095 64.9279 632.198 64.6117 632.418 63.913C635.133 62.7812 653.765 59.3261 657.053 59.0324L656.98 68.2382C663.158 62.7473 669.782 59.9066 677.935 59.0477Z" fill="#E31B79"/>
|
|
15
|
-
<path d="M331.798 57.0712C337.592 57.1185 343.354 57.0072 349.156 57.1749C351.068 59.3357 353.387 63.1655 355.063 65.6344C358.847 71.2087 362.432 77.014 366.36 82.4907C370.845 75.0665 378.273 64.1367 383.331 57.1032C385.626 57.0945 399.689 56.8398 400.866 57.3117C401.39 58.6028 399.759 61.1078 399.008 62.1658C392.221 71.7261 386.21 82.4699 379.267 91.8592C383.35 97.6717 387.268 104.526 391.166 110.532C393.16 113.606 400.626 124.783 400.949 127.559C399.879 128.243 384.096 127.95 382.001 127.951C377.115 119.684 371.356 110.895 366.217 102.718C364.993 105.113 362.366 109.016 360.85 111.436C357.401 116.922 353.992 122.433 350.622 127.968C348.242 127.897 332.898 128.279 332.168 127.57C332.118 126.754 332.069 125.826 332.449 125.099C334.495 121.173 337.285 117.058 339.661 113.307L353.193 91.8005C352.418 90.7063 351.628 89.4998 350.898 88.362C344.705 78.7208 337.866 69.3865 332.081 59.5087C331.713 58.8803 331.753 57.7841 331.798 57.0712Z" fill="#273441"/>
|
|
16
|
-
<path d="M311.843 57.1062C314.843 57.097 327.108 56.8601 329.377 57.2135L329.606 57.8503C329.333 60.3776 324.215 67.3436 322.511 69.9223C317.651 77.1875 312.847 84.4905 308.101 91.8305C309.118 93.8473 311.981 98.1472 313.27 100.2L323.962 117.113C325.904 120.182 329.179 124.459 329.551 127.99C323.658 127.748 316.574 127.94 310.593 127.946C307.782 122.799 304.084 117.694 301.099 112.597C299.196 109.347 296.932 105.769 294.706 102.746C293.772 104.889 290.7 109.57 289.357 111.724C285.993 117.165 282.58 122.576 279.12 127.956C276.595 127.908 261.817 128.243 260.671 127.615C260.249 126.007 261.797 123.527 262.702 122.205C269.332 112.519 275.107 101.261 281.979 91.8322C281.555 91.3258 281.153 90.8019 280.774 90.2617C279.987 89.1263 279.24 87.9296 278.486 86.7642C272.548 77.5965 266.263 68.6263 260.479 59.3668C260.192 58.9075 260.442 57.6507 260.539 57.1068C266.332 57.0478 272.125 57.0656 277.917 57.1596C283.454 64.9372 289.73 74.44 294.84 82.5018C296.784 80.011 299.246 76.0686 301.022 73.3917L311.843 57.1062Z" fill="#273441"/>
|
|
17
|
-
<path d="M479.835 35.8541C485.68 35.8897 491.521 35.8895 497.366 35.853C497.152 42.4806 497.332 50.2661 497.324 56.9807L514.284 56.9509L514.292 72.0978C508.643 72.0524 502.993 72.036 497.341 72.0485L497.313 93.563C497.313 97.0693 496.581 108.123 499.41 110.474C502.231 112.82 510.459 112.62 514.295 112.135L514.279 123.529L514.292 127.437C511.116 127.895 507.911 128.146 504.704 128.188C479.71 128.491 479.891 117.266 479.916 96.9484C479.949 88.6621 479.938 80.3759 479.88 72.09C476.431 72.026 471.882 71.9331 468.516 72.1906C468.292 67.7063 468.488 61.552 468.523 56.9865C469.391 56.999 470.258 56.9979 471.126 56.9829C482.417 56.741 480.091 43.7789 479.835 35.8541Z" fill="#273441"/>
|
|
18
|
-
<path d="M196 35.7646L235.626 35.811C239.705 35.8108 250.804 36.0941 254.421 35.6509L254.407 50.8756C240.766 50.8038 227.125 50.8041 213.485 50.877L213.495 74.3467C224.554 74.3448 238.413 74.7338 249.193 74.2652L249.203 89.7182C245.211 89.4232 239.525 89.5845 235.431 89.5872L213.496 89.6342L213.484 113.004L256.078 112.926L256.072 128.097C251.917 127.617 239.134 127.901 234.375 127.929C221.693 128.004 208.639 127.754 196 127.94V35.7646Z" fill="#273441"/>
|
|
19
|
-
<path d="M765.695 111.581C764.975 112.808 764.201 114.145 763.431 115.334C759.103 122.071 752.257 126.795 744.421 128.451C738.137 129.794 731.661 129.518 725.655 127.155C704.375 118.784 701.479 90.2098 712.245 72.5278C724.1 53.0555 757.792 53.4083 764.26 77.0772C764.933 79.5425 765.164 82.3339 765.695 84.8904V88.317C761.667 88.6393 755.214 88.441 751.038 88.436L724.401 88.4051C725.018 94.4891 725.082 99.3499 727.666 104.929C735.589 122.017 750.591 119.084 762.151 108.735C763.172 109.32 764.655 110.224 765.695 110.669V111.581ZM737.739 82.3573C741.742 82.3648 745.848 82.325 749.842 82.3896C749.575 74.8096 748.304 62.8235 737.466 64.6145C727.219 65.6478 726.515 74.7732 724.812 82.424C729.121 82.3579 733.43 82.3356 737.739 82.3573Z" fill="#E31B79"/>
|
|
20
|
-
</g>
|
|
21
|
-
<defs>
|
|
22
|
-
<linearGradient id="paint0_linear_73_1036" x1="28.3733" y1="134.255" x2="117.195" y2="30.9074" gradientUnits="userSpaceOnUse">
|
|
23
|
-
<stop offset="0.04" stop-color="#E21C79"/>
|
|
24
|
-
<stop offset="0.65" stop-color="#E21E7B"/>
|
|
25
|
-
<stop offset="0.73" stop-color="#E42880"/>
|
|
26
|
-
<stop offset="0.88" stop-color="#E9448E"/>
|
|
27
|
-
<stop offset="1" stop-color="#EF609D"/>
|
|
28
|
-
</linearGradient>
|
|
29
|
-
<clipPath id="clip0_73_1036">
|
|
30
|
-
<rect width="147" height="147" fill="white" transform="translate(0 8.25)"/>
|
|
31
|
-
</clipPath>
|
|
32
|
-
<clipPath id="clip1_73_1036">
|
|
33
|
-
<rect width="569.695" height="163.5" fill="white" transform="translate(196)"/>
|
|
34
|
-
</clipPath>
|
|
35
|
-
</defs>
|
|
36
|
-
</svg>
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import { Skeleton } from "@/components/ui/skeleton"
|
|
2
|
-
|
|
3
|
-
/** Route-level fallback while the dashboard shell + tabs chunk load. */
|
|
4
|
-
export default function DashboardLoading() {
|
|
5
|
-
return (
|
|
6
|
-
<div className="flex flex-col gap-4 p-4 md:p-6" aria-busy="true" aria-label="Loading dashboard">
|
|
7
|
-
<Skeleton className="h-9 w-56 max-w-full" />
|
|
8
|
-
<Skeleton className="h-11 w-full max-w-xl" />
|
|
9
|
-
<div className="grid gap-3 sm:grid-cols-2 lg:grid-cols-4">
|
|
10
|
-
<Skeleton className="h-24 rounded-xl" />
|
|
11
|
-
<Skeleton className="h-24 rounded-xl" />
|
|
12
|
-
<Skeleton className="h-24 rounded-xl" />
|
|
13
|
-
<Skeleton className="h-24 rounded-xl" />
|
|
14
|
-
</div>
|
|
15
|
-
<Skeleton className="min-h-[320px] w-full rounded-xl" />
|
|
16
|
-
</div>
|
|
17
|
-
)
|
|
18
|
-
}
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
import dynamic from "next/dynamic"
|
|
2
|
-
import { PrimaryPageTemplate } from "@/components/templates/primary-page-template"
|
|
3
|
-
import { Skeleton } from "@/components/ui/skeleton"
|
|
4
|
-
import { DASHBOARD_METRICS, DASHBOARD_INSIGHT } from "@/lib/mock/dashboard"
|
|
5
|
-
|
|
6
|
-
const DashboardTabs = dynamic(
|
|
7
|
-
() => import("@/components/dashboard-tabs").then(m => ({ default: m.DashboardTabs })),
|
|
8
|
-
{
|
|
9
|
-
loading: () => (
|
|
10
|
-
<div className="flex flex-col gap-4 p-4 md:p-6" aria-busy="true" aria-label="Loading dashboard">
|
|
11
|
-
<Skeleton className="h-9 w-56 max-w-full" />
|
|
12
|
-
<Skeleton className="h-11 w-full max-w-xl" />
|
|
13
|
-
<div className="grid gap-3 sm:grid-cols-2 lg:grid-cols-4">
|
|
14
|
-
<Skeleton className="h-24 rounded-xl" />
|
|
15
|
-
<Skeleton className="h-24 rounded-xl" />
|
|
16
|
-
<Skeleton className="h-24 rounded-xl" />
|
|
17
|
-
<Skeleton className="h-24 rounded-xl" />
|
|
18
|
-
</div>
|
|
19
|
-
<Skeleton className="min-h-[320px] w-full rounded-xl" />
|
|
20
|
-
</div>
|
|
21
|
-
),
|
|
22
|
-
},
|
|
23
|
-
)
|
|
24
|
-
|
|
25
|
-
export default function Page() {
|
|
26
|
-
return (
|
|
27
|
-
<PrimaryPageTemplate siteHeader={{ title: "Dashboard" }}>
|
|
28
|
-
<DashboardTabs
|
|
29
|
-
title="Dashboard"
|
|
30
|
-
subtitle="Design system shell · sample metrics and charts"
|
|
31
|
-
metrics={DASHBOARD_METRICS}
|
|
32
|
-
insight={DASHBOARD_INSIGHT}
|
|
33
|
-
/>
|
|
34
|
-
</PrimaryPageTemplate>
|
|
35
|
-
)
|
|
36
|
-
}
|