@exxatdesignux/ui 0.2.19 → 0.3.0
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 +60 -7
- package/bin/sync-extras.mjs +116 -29
- package/consumer-extras/README.md +42 -7
- package/consumer-extras/cursor-rules/exxat-accessibility.mdc +39 -0
- package/consumer-extras/cursor-rules/exxat-board-cards.mdc +26 -0
- package/consumer-extras/cursor-rules/exxat-breadcrumbs-no-back.mdc +21 -0
- package/consumer-extras/cursor-rules/exxat-card-vs-list-rows.mdc +21 -0
- package/consumer-extras/cursor-rules/exxat-centralized-list-dataset.mdc +44 -0
- package/consumer-extras/cursor-rules/exxat-collaboration-access.mdc +32 -0
- package/consumer-extras/cursor-rules/exxat-command-menu.mdc +22 -0
- package/consumer-extras/cursor-rules/exxat-dashboard-view-charts.mdc +53 -0
- package/consumer-extras/cursor-rules/exxat-data-tables.mdc +41 -0
- package/consumer-extras/cursor-rules/exxat-dedicated-search-surfaces.mdc +25 -0
- package/consumer-extras/cursor-rules/exxat-drawer-vs-dialog.mdc +22 -0
- package/consumer-extras/cursor-rules/exxat-ds-agents.mdc +56 -0
- package/consumer-extras/cursor-rules/exxat-fontawesome-icons.mdc +31 -0
- package/consumer-extras/cursor-rules/exxat-kbd-shortcuts.mdc +100 -0
- package/consumer-extras/cursor-rules/exxat-kpi-flat-band.mdc +28 -0
- package/consumer-extras/cursor-rules/exxat-kpi-max-four.mdc +21 -0
- package/consumer-extras/cursor-rules/exxat-kpi-trends.mdc +31 -0
- package/consumer-extras/cursor-rules/exxat-list-page-connected-views.mdc +24 -0
- package/consumer-extras/cursor-rules/exxat-list-page-view-shells.mdc +31 -0
- package/consumer-extras/cursor-rules/exxat-mono-ids.mdc +30 -0
- package/consumer-extras/cursor-rules/exxat-no-slds-leakage.mdc +78 -0
- package/consumer-extras/cursor-rules/exxat-no-toast.mdc +25 -0
- package/consumer-extras/cursor-rules/exxat-page-vs-drawer.mdc +23 -0
- package/consumer-extras/cursor-rules/exxat-person-identity-display.mdc +47 -0
- package/consumer-extras/cursor-rules/exxat-primary-nav-secondary-panel.mdc +52 -0
- package/consumer-extras/cursor-rules/exxat-question-bank-hub-header.mdc +28 -0
- package/consumer-extras/cursor-rules/exxat-reuse-before-custom.mdc +34 -0
- package/consumer-extras/cursor-rules/exxat-table-properties-drawer.mdc +77 -0
- package/consumer-extras/cursor-rules/exxat-token-discipline.mdc +103 -0
- package/consumer-extras/cursor-skills/exxat-accessibility/SKILL.md +1 -1
- package/consumer-extras/cursor-skills/exxat-board-cards/SKILL.md +2 -2
- package/consumer-extras/cursor-skills/exxat-centralized-list-dataset/SKILL.md +4 -15
- package/consumer-extras/cursor-skills/exxat-ds-skill/SKILL.md +13 -28
- package/consumer-extras/cursor-skills/exxat-ds-skill/references/data-table-pattern.md +1 -1
- package/consumer-extras/cursor-skills/exxat-primary-nav-secondary-panel/SKILL.md +2 -4
- package/consumer-extras/handbook/HANDBOOK.md +185 -0
- package/consumer-extras/handbook/glossary.md +57 -0
- package/consumer-extras/handbook/reference-implementations.md +126 -0
- package/consumer-extras/handbook/voice-and-tone.md +262 -0
- package/consumer-extras/patterns/command-menu-pattern.md +1 -1
- package/consumer-extras/patterns/consumer-upgrade-checklist.md +0 -20
- package/consumer-extras/patterns/data-views-pattern.md +17 -54
- package/consumer-extras/patterns/shell-surface-elevation-pattern.md +3 -5
- package/dist/components/data-table/filter-date-calendar.d.ts +10 -0
- package/dist/components/data-table/filter-date-calendar.js +280 -0
- package/dist/components/data-table/filter-date-calendar.js.map +1 -0
- package/dist/components/data-table/filter-text-value-input.d.ts +15 -0
- package/dist/components/data-table/filter-text-value-input.js +561 -0
- package/dist/components/data-table/filter-text-value-input.js.map +1 -0
- package/dist/components/data-table/index.d.ts +45 -0
- package/dist/components/data-table/index.js +3085 -0
- package/dist/components/data-table/index.js.map +1 -0
- package/dist/components/data-table/pagination.d.ts +28 -0
- package/dist/components/data-table/pagination.js +3264 -0
- package/dist/components/data-table/pagination.js.map +1 -0
- package/dist/components/data-table/types.d.ts +84 -0
- package/dist/components/data-table/types.js +3 -0
- package/dist/components/data-table/types.js.map +1 -0
- package/dist/components/data-table/use-table-state.d.ts +116 -0
- package/dist/components/data-table/use-table-state.js +670 -0
- package/dist/components/data-table/use-table-state.js.map +1 -0
- package/dist/components/data-views/board-card-primitives.d.ts +22 -0
- package/dist/components/data-views/board-card-primitives.js +84 -0
- package/dist/components/data-views/board-card-primitives.js.map +1 -0
- package/dist/components/data-views/data-row-list.d.ts +33 -0
- package/dist/components/data-views/data-row-list.js +106 -0
- package/dist/components/data-views/data-row-list.js.map +1 -0
- package/dist/components/data-views/finder-panel-view.d.ts +54 -0
- package/dist/components/data-views/finder-panel-view.js +388 -0
- package/dist/components/data-views/finder-panel-view.js.map +1 -0
- package/dist/components/data-views/folder-grid-view.d.ts +22 -0
- package/dist/components/data-views/folder-grid-view.js +58 -0
- package/dist/components/data-views/folder-grid-view.js.map +1 -0
- package/dist/components/data-views/hub-table.d.ts +167 -0
- package/dist/components/data-views/hub-table.js +5561 -0
- package/dist/components/data-views/hub-table.js.map +1 -0
- package/dist/components/data-views/index.d.ts +27 -0
- package/dist/components/data-views/index.js +6575 -0
- package/dist/components/data-views/index.js.map +1 -0
- package/dist/components/data-views/list-page-board-card.d.ts +72 -0
- package/dist/components/data-views/list-page-board-card.js +264 -0
- package/dist/components/data-views/list-page-board-card.js.map +1 -0
- package/dist/components/data-views/list-page-board-template.d.ts +24 -0
- package/dist/components/data-views/list-page-board-template.js +137 -0
- package/dist/components/data-views/list-page-board-template.js.map +1 -0
- package/dist/components/data-views/list-page-connected-view-body.d.ts +19 -0
- package/dist/components/data-views/list-page-connected-view-body.js +116 -0
- package/dist/components/data-views/list-page-connected-view-body.js.map +1 -0
- package/dist/components/data-views/list-page-split-details-placeholder.d.ts +14 -0
- package/dist/components/data-views/list-page-split-details-placeholder.js +38 -0
- package/dist/components/data-views/list-page-split-details-placeholder.js.map +1 -0
- package/dist/components/data-views/list-page-split-hub-chrome.d.ts +17 -0
- package/dist/components/data-views/list-page-split-hub-chrome.js +54 -0
- package/dist/components/data-views/list-page-split-hub-chrome.js.map +1 -0
- package/dist/components/data-views/list-page-split-hub-tokens.d.ts +12 -0
- package/dist/components/data-views/list-page-split-hub-tokens.js +8 -0
- package/dist/components/data-views/list-page-split-hub-tokens.js.map +1 -0
- package/dist/components/data-views/list-page-tree-column-header.d.ts +15 -0
- package/dist/components/data-views/list-page-tree-column-header.js +22 -0
- package/dist/components/data-views/list-page-tree-column-header.js.map +1 -0
- package/dist/components/data-views/list-page-tree-panel-shell.d.ts +25 -0
- package/dist/components/data-views/list-page-tree-panel-shell.js +146 -0
- package/dist/components/data-views/list-page-tree-panel-shell.js.map +1 -0
- package/dist/components/data-views/os-folder-glyph.d.ts +35 -0
- package/dist/components/data-views/os-folder-glyph.js +104 -0
- package/dist/components/data-views/os-folder-glyph.js.map +1 -0
- package/dist/components/data-views/outline-tree-menu.d.ts +36 -0
- package/dist/components/data-views/outline-tree-menu.js +131 -0
- package/dist/components/data-views/outline-tree-menu.js.map +1 -0
- package/dist/components/table-properties/column-row.d.ts +22 -0
- package/dist/components/table-properties/column-row.js +153 -0
- package/dist/components/table-properties/column-row.js.map +1 -0
- package/dist/components/table-properties/draggable-list.d.ts +24 -0
- package/dist/components/table-properties/draggable-list.js +53 -0
- package/dist/components/table-properties/draggable-list.js.map +1 -0
- package/dist/components/table-properties/drawer-button.d.ts +110 -0
- package/dist/components/table-properties/drawer-button.js +2748 -0
- package/dist/components/table-properties/drawer-button.js.map +1 -0
- package/dist/components/table-properties/drawer.d.ts +100 -0
- package/dist/components/table-properties/drawer.js +2595 -0
- package/dist/components/table-properties/drawer.js.map +1 -0
- package/dist/components/table-properties/filter-card.d.ts +24 -0
- package/dist/components/table-properties/filter-card.js +854 -0
- package/dist/components/table-properties/filter-card.js.map +1 -0
- package/dist/components/table-properties/index.d.ts +14 -0
- package/dist/components/table-properties/index.js +2768 -0
- package/dist/components/table-properties/index.js.map +1 -0
- package/dist/components/table-properties/sort-card.d.ts +20 -0
- package/dist/components/table-properties/sort-card.js +102 -0
- package/dist/components/table-properties/sort-card.js.map +1 -0
- package/dist/components/templates/dedicated-search-landing-template.d.ts +21 -0
- package/dist/components/templates/dedicated-search-landing-template.js +254 -0
- package/dist/components/templates/dedicated-search-landing-template.js.map +1 -0
- package/dist/components/templates/dedicated-search-results-template.d.ts +15 -0
- package/dist/components/templates/dedicated-search-results-template.js +16 -0
- package/dist/components/templates/dedicated-search-results-template.js.map +1 -0
- package/dist/components/templates/index.d.ts +9 -0
- package/dist/components/templates/index.js +2720 -0
- package/dist/components/templates/index.js.map +1 -0
- package/dist/components/templates/list-page.d.ts +83 -0
- package/dist/components/templates/list-page.js +2433 -0
- package/dist/components/templates/list-page.js.map +1 -0
- package/dist/components/templates/nested-secondary-panel-shell.d.ts +20 -0
- package/dist/components/templates/nested-secondary-panel-shell.js +54 -0
- package/dist/components/templates/nested-secondary-panel-shell.js.map +1 -0
- package/dist/components/ui/accordion.d.ts +10 -0
- package/dist/components/ui/accordion.js +74 -0
- package/dist/components/ui/accordion.js.map +1 -0
- package/dist/components/ui/alert-dialog.d.ts +37 -0
- package/dist/components/ui/alert-dialog.js +201 -0
- package/dist/components/ui/alert-dialog.js.map +1 -0
- package/dist/components/ui/avatar.d.ts +84 -0
- package/dist/components/ui/avatar.js +328 -0
- package/dist/components/ui/avatar.js.map +1 -0
- package/dist/components/ui/badge.d.ts +13 -0
- package/dist/components/ui/badge.js +49 -0
- package/dist/components/ui/badge.js.map +1 -0
- package/dist/components/ui/banner.d.ts +62 -0
- package/dist/components/ui/banner.js +364 -0
- package/dist/components/ui/banner.js.map +1 -0
- package/dist/components/ui/breadcrumb.d.ts +14 -0
- package/dist/components/ui/breadcrumb.js +114 -0
- package/dist/components/ui/breadcrumb.js.map +1 -0
- package/dist/components/ui/button.d.ts +16 -0
- package/dist/components/ui/button.js +59 -0
- package/dist/components/ui/button.js.map +1 -0
- package/dist/components/ui/calendar.d.ts +13 -0
- package/dist/components/ui/calendar.js +238 -0
- package/dist/components/ui/calendar.js.map +1 -0
- package/dist/components/ui/card.d.ts +14 -0
- package/dist/components/ui/card.js +102 -0
- package/dist/components/ui/card.js.map +1 -0
- package/dist/components/ui/chart.d.ts +58 -0
- package/dist/components/ui/chart.js +292 -0
- package/dist/components/ui/chart.js.map +1 -0
- package/dist/components/ui/checkbox.d.ts +23 -0
- package/dist/components/ui/checkbox.js +155 -0
- package/dist/components/ui/checkbox.js.map +1 -0
- package/dist/components/ui/coach-mark.d.ts +27 -0
- package/dist/components/ui/coach-mark.js +306 -0
- package/dist/components/ui/coach-mark.js.map +1 -0
- package/dist/components/ui/collapsible.d.ts +8 -0
- package/dist/components/ui/collapsible.js +35 -0
- package/dist/components/ui/collapsible.js.map +1 -0
- package/dist/components/ui/command.d.ts +36 -0
- package/dist/components/ui/command.js +274 -0
- package/dist/components/ui/command.js.map +1 -0
- package/dist/components/ui/context-menu.d.ts +32 -0
- package/dist/components/ui/context-menu.js +245 -0
- package/dist/components/ui/context-menu.js.map +1 -0
- package/dist/components/ui/date-picker-field.d.ts +38 -0
- package/dist/components/ui/date-picker-field.js +550 -0
- package/dist/components/ui/date-picker-field.js.map +1 -0
- package/dist/components/ui/dialog.d.ts +22 -0
- package/dist/components/ui/dialog.js +200 -0
- package/dist/components/ui/dialog.js.map +1 -0
- package/dist/components/ui/dot-pattern.d.ts +21 -0
- package/dist/components/ui/dot-pattern.js +139 -0
- package/dist/components/ui/dot-pattern.js.map +1 -0
- package/dist/components/ui/drag-handle-grip.d.ts +10 -0
- package/dist/components/ui/drag-handle-grip.js +15 -0
- package/dist/components/ui/drag-handle-grip.js.map +1 -0
- package/dist/components/ui/drawer.d.ts +16 -0
- package/dist/components/ui/drawer.js +125 -0
- package/dist/components/ui/drawer.js.map +1 -0
- package/dist/components/ui/dropdown-menu.d.ts +45 -0
- package/dist/components/ui/dropdown-menu.js +353 -0
- package/dist/components/ui/dropdown-menu.js.map +1 -0
- package/dist/components/ui/export-drawer.d.ts +11 -0
- package/dist/components/ui/export-drawer.js +1658 -0
- package/dist/components/ui/export-drawer.js.map +1 -0
- package/dist/components/ui/field.d.ts +30 -0
- package/dist/components/ui/field.js +249 -0
- package/dist/components/ui/field.js.map +1 -0
- package/dist/components/ui/form.d.ts +28 -0
- package/dist/components/ui/form.js +110 -0
- package/dist/components/ui/form.js.map +1 -0
- package/dist/components/ui/hover-card.d.ts +9 -0
- package/dist/components/ui/hover-card.js +43 -0
- package/dist/components/ui/hover-card.js.map +1 -0
- package/dist/components/ui/input-group.d.ts +20 -0
- package/dist/components/ui/input-group.js +219 -0
- package/dist/components/ui/input-group.js.map +1 -0
- package/dist/components/ui/input-mask.d.ts +39 -0
- package/dist/components/ui/input-mask.js +118 -0
- package/dist/components/ui/input-mask.js.map +1 -0
- package/dist/components/ui/input.d.ts +5 -0
- package/dist/components/ui/input.js +30 -0
- package/dist/components/ui/input.js.map +1 -0
- package/dist/components/ui/kbd.d.ts +20 -0
- package/dist/components/ui/kbd.js +45 -0
- package/dist/components/ui/kbd.js.map +1 -0
- package/dist/components/ui/key-metrics-context.d.ts +19 -0
- package/dist/components/ui/key-metrics-context.js +26 -0
- package/dist/components/ui/key-metrics-context.js.map +1 -0
- package/dist/components/ui/key-metrics.d.ts +131 -0
- package/dist/components/ui/key-metrics.js +1015 -0
- package/dist/components/ui/key-metrics.js.map +1 -0
- package/dist/components/ui/label.d.ts +6 -0
- package/dist/components/ui/label.js +28 -0
- package/dist/components/ui/label.js.map +1 -0
- package/dist/components/ui/list-page-view-frame.d.ts +22 -0
- package/dist/components/ui/list-page-view-frame.js +24 -0
- package/dist/components/ui/list-page-view-frame.js.map +1 -0
- package/dist/components/ui/page-header.d.ts +51 -0
- package/dist/components/ui/page-header.js +372 -0
- package/dist/components/ui/page-header.js.map +1 -0
- package/dist/components/ui/payment-card-fields.d.ts +10 -0
- package/dist/components/ui/payment-card-fields.js +80 -0
- package/dist/components/ui/payment-card-fields.js.map +1 -0
- package/dist/components/ui/popover.d.ts +10 -0
- package/dist/components/ui/popover.js +47 -0
- package/dist/components/ui/popover.js.map +1 -0
- package/dist/components/ui/radio-group.d.ts +29 -0
- package/dist/components/ui/radio-group.js +190 -0
- package/dist/components/ui/radio-group.js.map +1 -0
- package/dist/components/ui/resizable.d.ts +16 -0
- package/dist/components/ui/resizable.js +51 -0
- package/dist/components/ui/resizable.js.map +1 -0
- package/dist/components/ui/scroll-area.d.ts +8 -0
- package/dist/components/ui/scroll-area.js +66 -0
- package/dist/components/ui/scroll-area.js.map +1 -0
- package/dist/components/ui/select.d.ts +18 -0
- package/dist/components/ui/select.js +186 -0
- package/dist/components/ui/select.js.map +1 -0
- package/dist/components/ui/selection-tile-grid.d.ts +52 -0
- package/dist/components/ui/selection-tile-grid.js +347 -0
- package/dist/components/ui/selection-tile-grid.js.map +1 -0
- package/dist/components/ui/separator.d.ts +7 -0
- package/dist/components/ui/separator.js +33 -0
- package/dist/components/ui/separator.js.map +1 -0
- package/dist/components/ui/sheet.d.ts +18 -0
- package/dist/components/ui/sheet.js +181 -0
- package/dist/components/ui/sheet.js.map +1 -0
- package/dist/components/ui/sidebar.d.ts +94 -0
- package/dist/components/ui/sidebar.js +805 -0
- package/dist/components/ui/sidebar.js.map +1 -0
- package/dist/components/ui/skeleton.d.ts +5 -0
- package/dist/components/ui/skeleton.js +22 -0
- package/dist/components/ui/skeleton.js.map +1 -0
- package/dist/components/ui/slider.d.ts +7 -0
- package/dist/components/ui/slider.js +66 -0
- package/dist/components/ui/slider.js.map +1 -0
- package/dist/components/ui/sonner.d.ts +6 -0
- package/dist/components/ui/sonner.js +38 -0
- package/dist/components/ui/sonner.js.map +1 -0
- package/dist/components/ui/status-badge.d.ts +38 -0
- package/dist/components/ui/status-badge.js +77 -0
- package/dist/components/ui/status-badge.js.map +1 -0
- package/dist/components/ui/table.d.ts +13 -0
- package/dist/components/ui/table.js +115 -0
- package/dist/components/ui/table.js.map +1 -0
- package/dist/components/ui/tabs.d.ts +15 -0
- package/dist/components/ui/tabs.js +93 -0
- package/dist/components/ui/tabs.js.map +1 -0
- package/dist/components/ui/textarea.d.ts +6 -0
- package/dist/components/ui/textarea.js +25 -0
- package/dist/components/ui/textarea.js.map +1 -0
- package/dist/components/ui/tip.d.ts +12 -0
- package/dist/components/ui/tip.js +61 -0
- package/dist/components/ui/tip.js.map +1 -0
- package/dist/components/ui/toggle-group.d.ts +14 -0
- package/dist/components/ui/toggle-group.js +104 -0
- package/dist/components/ui/toggle-group.js.map +1 -0
- package/dist/components/ui/toggle-switch.d.ts +10 -0
- package/dist/components/ui/toggle-switch.js +33 -0
- package/dist/components/ui/toggle-switch.js.map +1 -0
- package/dist/components/ui/toggle.d.ts +13 -0
- package/dist/components/ui/toggle.js +51 -0
- package/dist/components/ui/toggle.js.map +1 -0
- package/dist/components/ui/tooltip.d.ts +10 -0
- package/dist/components/ui/tooltip.js +68 -0
- package/dist/components/ui/tooltip.js.map +1 -0
- package/dist/components/ui/view-segmented-control.d.ts +31 -0
- package/dist/components/ui/view-segmented-control.js +167 -0
- package/dist/components/ui/view-segmented-control.js.map +1 -0
- package/dist/data-list-view-registry-CyBoBML4.d.ts +73 -0
- package/dist/hooks/use-app-theme.d.ts +24 -0
- package/dist/hooks/use-app-theme.js +286 -0
- package/dist/hooks/use-app-theme.js.map +1 -0
- package/dist/hooks/use-coach-mark.d.ts +86 -0
- package/dist/hooks/use-coach-mark.js +218 -0
- package/dist/hooks/use-coach-mark.js.map +1 -0
- package/dist/hooks/use-mobile.d.ts +3 -0
- package/dist/hooks/use-mobile.js +29 -0
- package/dist/hooks/use-mobile.js.map +1 -0
- package/dist/hooks/use-mod-key-label.d.ts +6 -0
- package/dist/hooks/use-mod-key-label.js +25 -0
- package/dist/hooks/use-mod-key-label.js.map +1 -0
- package/dist/index.d.ts +120 -0
- package/dist/index.js +13324 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/compose-refs.d.ts +6 -0
- package/dist/lib/compose-refs.js +17 -0
- package/dist/lib/compose-refs.js.map +1 -0
- package/dist/lib/conditional-rule-match.d.ts +30 -0
- package/dist/lib/conditional-rule-match.js +66 -0
- package/dist/lib/conditional-rule-match.js.map +1 -0
- package/dist/lib/data-list-display-options.d.ts +26 -0
- package/dist/lib/data-list-display-options.js +14 -0
- package/dist/lib/data-list-display-options.js.map +1 -0
- package/dist/lib/data-list-view-registry.d.ts +2 -0
- package/dist/lib/data-list-view-registry.js +102 -0
- package/dist/lib/data-list-view-registry.js.map +1 -0
- package/dist/lib/data-list-view-surface.d.ts +2 -0
- package/dist/lib/data-list-view-surface.js +80 -0
- package/dist/lib/data-list-view-surface.js.map +1 -0
- package/dist/lib/data-list-view.d.ts +21 -0
- package/dist/lib/data-list-view.js +25 -0
- package/dist/lib/data-list-view.js.map +1 -0
- package/dist/lib/date-filter.d.ts +22 -0
- package/dist/lib/date-filter.js +61 -0
- package/dist/lib/date-filter.js.map +1 -0
- package/dist/lib/dev-log.d.ts +8 -0
- package/dist/lib/dev-log.js +10 -0
- package/dist/lib/dev-log.js.map +1 -0
- package/dist/lib/dropdown-menu-surface.d.ts +14 -0
- package/dist/lib/dropdown-menu-surface.js +6 -0
- package/dist/lib/dropdown-menu-surface.js.map +1 -0
- package/dist/lib/editable-target.d.ts +12 -0
- package/dist/lib/editable-target.js +12 -0
- package/dist/lib/editable-target.js.map +1 -0
- package/dist/lib/list-page-table-properties.d.ts +35 -0
- package/dist/lib/list-page-table-properties.js +81 -0
- package/dist/lib/list-page-table-properties.js.map +1 -0
- package/dist/lib/raf-throttle.d.ts +23 -0
- package/dist/lib/raf-throttle.js +27 -0
- package/dist/lib/raf-throttle.js.map +1 -0
- package/dist/lib/row-height.d.ts +16 -0
- package/dist/lib/row-height.js +10 -0
- package/dist/lib/row-height.js.map +1 -0
- package/dist/lib/table-properties-types.d.ts +83 -0
- package/dist/lib/table-properties-types.js +19 -0
- package/dist/lib/table-properties-types.js.map +1 -0
- package/dist/lib/utils.d.ts +5 -0
- package/dist/lib/utils.js +11 -0
- package/dist/lib/utils.js.map +1 -0
- package/package.json +83 -19
- package/src/components/data-table/filter-date-calendar.tsx +38 -0
- package/src/components/data-table/filter-text-value-input.tsx +77 -0
- package/src/components/data-table/index.tsx +1678 -0
- package/src/components/data-table/pagination.tsx +255 -0
- package/src/components/data-table/types.ts +96 -0
- package/src/components/data-table/use-table-state.ts +767 -0
- package/src/components/data-views/board-card-primitives.tsx +93 -0
- package/src/components/data-views/data-row-list.tsx +183 -0
- package/src/components/data-views/finder-panel-view.tsx +405 -0
- package/src/components/data-views/folder-grid-view.tsx +86 -0
- package/src/components/data-views/hub-table.tsx +498 -0
- package/src/components/data-views/index.ts +28 -0
- package/src/components/data-views/list-page-board-card.tsx +192 -0
- package/src/components/data-views/list-page-board-template.tsx +122 -0
- package/src/components/data-views/list-page-connected-view-body.tsx +66 -0
- package/src/components/data-views/list-page-split-details-placeholder.tsx +39 -0
- package/src/components/data-views/list-page-split-hub-chrome.tsx +60 -0
- package/src/components/data-views/list-page-split-hub-tokens.ts +16 -0
- package/src/components/data-views/list-page-tree-column-header.tsx +31 -0
- package/src/components/data-views/list-page-tree-panel-shell.tsx +91 -0
- package/src/components/data-views/os-folder-glyph.tsx +141 -0
- package/src/components/data-views/outline-tree-menu.tsx +157 -0
- package/src/components/table-properties/column-row.tsx +90 -0
- package/src/components/table-properties/draggable-list.ts +54 -0
- package/src/components/table-properties/drawer-button.tsx +300 -0
- package/src/components/table-properties/drawer.tsx +1148 -0
- package/src/components/table-properties/filter-card.tsx +251 -0
- package/src/components/table-properties/index.ts +36 -0
- package/src/components/table-properties/sort-card.tsx +63 -0
- package/src/components/templates/dedicated-search-landing-template.tsx +124 -0
- package/src/components/templates/dedicated-search-results-template.tsx +19 -0
- package/src/components/templates/index.ts +33 -0
- package/src/components/templates/list-page.tsx +602 -0
- package/src/components/templates/nested-secondary-panel-shell.tsx +70 -0
- package/src/components/ui/accordion.tsx +92 -0
- package/src/components/ui/alert-dialog.tsx +221 -0
- package/src/components/ui/avatar.tsx +13 -2
- package/src/components/ui/banner.tsx +2 -2
- package/src/components/ui/button.tsx +4 -4
- package/src/components/ui/calendar.tsx +1 -1
- package/src/components/ui/coach-mark.tsx +1 -1
- package/src/components/ui/context-menu.tsx +291 -0
- package/src/components/ui/date-picker-field.tsx +2 -2
- package/src/components/ui/dot-pattern.tsx +183 -0
- package/src/components/ui/export-drawer.tsx +375 -0
- package/src/components/ui/hover-card.tsx +66 -0
- package/src/components/ui/key-metrics-context.tsx +78 -0
- package/src/components/ui/key-metrics.tsx +1133 -0
- package/src/components/ui/list-page-view-frame.tsx +64 -0
- package/src/components/ui/page-header.tsx +244 -0
- package/src/components/ui/payment-card-fields.tsx +2 -2
- package/src/components/ui/resizable.tsx +68 -0
- package/src/components/ui/scroll-area.tsx +72 -0
- package/src/components/ui/selection-tile-grid.tsx +9 -2
- package/src/components/ui/sidebar.tsx +84 -12
- package/src/components/ui/slider.tsx +83 -0
- package/src/globals.css +2201 -7
- package/src/globals.d.ts +20 -0
- package/src/index.ts +68 -1
- package/src/lib/conditional-rule-match.ts +119 -0
- package/src/lib/data-list-display-options.ts +35 -0
- package/src/lib/data-list-view-registry.ts +104 -0
- package/src/lib/data-list-view-surface.ts +83 -0
- package/src/lib/data-list-view.ts +47 -0
- package/src/lib/dev-log.ts +10 -0
- package/src/lib/editable-target.ts +20 -0
- package/src/lib/list-page-table-properties.ts +48 -0
- package/src/lib/raf-throttle.ts +45 -0
- package/src/lib/row-height.ts +19 -0
- package/src/lib/table-properties-types.ts +98 -0
- package/template/.cursor/rules/exxat-command-menu.mdc +1 -1
- package/template/.cursor/rules/exxat-dashboard-view-charts.mdc +3 -3
- package/template/.cursor/rules/exxat-data-tables.mdc +1 -1
- package/template/.cursor/rules/exxat-ds-agents.mdc +2 -2
- package/template/.cursor/rules/exxat-kbd-shortcuts.mdc +2 -2
- package/template/.cursor/rules/exxat-table-properties-drawer.mdc +1 -1
- package/template/AGENTS.md +104 -78
- package/template/app/(app)/dashboard/loading.tsx +15 -3
- package/template/app/(app)/dashboard/page.tsx +14 -2
- package/template/app/(app)/examples/page.tsx +0 -2
- package/template/app/(app)/layout.tsx +17 -4
- package/template/app/(app)/loading.tsx +18 -1
- package/template/app/(app)/question-bank/find/page.tsx +1 -2
- package/template/app/(app)/question-bank/layout.tsx +1 -1
- package/template/app/(app)/question-bank/library/page.tsx +1 -2
- package/template/app/(app)/question-bank/list/page.tsx +1 -2
- package/template/app/(app)/question-bank/new/page.tsx +15 -20
- package/template/app/(app)/question-bank/page.tsx +1 -2
- package/template/app/(app)/settings/page.tsx +5 -4
- package/template/app/globals.css +14 -16
- package/template/components/ask-leo-sidebar.tsx +5 -1
- package/template/components/brand-color-picker.tsx +2 -2
- package/template/components/charts-overview.tsx +1 -1
- package/template/components/compliance-board-view.tsx +142 -0
- package/template/components/compliance-client.tsx +92 -0
- package/template/components/compliance-page-header.tsx +89 -0
- package/template/components/compliance-table.tsx +468 -0
- package/template/components/dashboard-report-charts.tsx +1 -1
- package/template/components/dashboard-tabs.tsx +1 -1
- package/template/components/data-table/filter-date-calendar.tsx +1 -38
- package/template/components/data-table/filter-text-value-input.tsx +1 -77
- package/template/components/data-table/index.tsx +1 -1634
- package/template/components/data-table/pagination.tsx +1 -255
- package/template/components/data-table/types.ts +1 -94
- package/template/components/data-table/use-table-state.test.ts +420 -0
- package/template/components/data-table/use-table-state.ts +1 -758
- package/template/components/data-view-dashboard-charts-compliance.tsx +963 -0
- package/template/components/data-view-dashboard-charts-team.tsx +971 -0
- package/template/components/data-view-dashboard-charts.tsx +1503 -0
- package/template/components/data-views/board-card-primitives.tsx +1 -93
- package/template/components/data-views/data-row-list.tsx +1 -183
- package/template/components/data-views/finder-panel-view.tsx +1 -405
- package/template/components/data-views/folder-grid-view.tsx +1 -86
- package/template/components/data-views/hub-table.tsx +1 -0
- package/template/components/data-views/index.ts +50 -37
- package/template/components/data-views/list-page-board-card.tsx +1 -192
- package/template/components/data-views/list-page-board-template.tsx +1 -122
- package/template/components/data-views/list-page-connected-view-body.tsx +1 -66
- package/template/components/data-views/list-page-split-details-placeholder.tsx +1 -39
- package/template/components/data-views/list-page-split-hub-chrome.tsx +1 -68
- package/template/components/data-views/list-page-split-hub-tokens.ts +1 -16
- package/template/components/data-views/list-page-tree-column-header.tsx +1 -31
- package/template/components/data-views/list-page-tree-panel-shell.tsx +1 -91
- package/template/components/data-views/list-page-view-frame.tsx +5 -53
- package/template/components/data-views/os-folder-glyph.tsx +1 -129
- package/template/components/data-views/outline-tree-menu.tsx +1 -157
- package/template/components/export-drawer.test.tsx +71 -0
- package/template/components/export-drawer.tsx +1 -375
- package/template/components/exxat-product-logo.tsx +5 -5
- package/template/components/hub-tree-panel-view.tsx +2 -2
- package/template/components/invite-collaborators-drawer.tsx +3 -3
- package/template/components/key-metrics-ask-leo-bridge.tsx +40 -0
- package/template/components/key-metrics.tsx +1 -1063
- package/template/components/leo-insight-indicator.tsx +2 -2
- package/template/components/new-placement-back-btn.tsx +28 -0
- package/template/components/new-placement-form.tsx +942 -0
- package/template/components/new-question-composer.tsx +456 -408
- package/template/components/onboarding/index.ts +9 -0
- package/template/components/onboarding/onboarding-01.tsx +1 -1
- package/template/components/onboarding/onboarding-02.tsx +1 -1
- package/template/components/onboarding/onboarding-03.tsx +1 -1
- package/template/components/onboarding/onboarding-04.tsx +1 -1
- package/template/components/page-header.tsx +8 -226
- package/template/components/placement-board-card.tsx +250 -0
- package/template/components/placement-detail.tsx +438 -0
- package/template/components/placements-board-view.tsx +397 -0
- package/template/components/placements-client.tsx +220 -0
- package/template/components/placements-list-view.tsx +124 -0
- package/template/components/placements-page-header.tsx +166 -0
- package/template/components/placements-table-cells.test.tsx +22 -0
- package/template/components/placements-table-cells.tsx +173 -0
- package/template/components/placements-table-columns.tsx +210 -0
- package/template/components/placements-table.tsx +934 -0
- package/template/components/product-switcher.tsx +3 -4
- package/template/components/product-wordmark.tsx +2 -1
- package/template/components/question-bank-client.tsx +5 -5
- package/template/components/question-bank-hub-client.tsx +1 -1
- package/template/components/question-bank-new-folder-sheet.tsx +2 -2
- package/template/components/question-bank-secondary-nav.tsx +3 -3
- package/template/components/question-bank-table.tsx +541 -431
- package/template/components/rotations-empty-state.tsx +50 -0
- package/template/components/rotations-panel-activator.tsx +8 -0
- package/template/components/settings-appearance-card.tsx +3 -4
- package/template/components/settings-client.tsx +15 -59
- package/template/components/settings-form-row.tsx +4 -9
- package/template/components/{app-sidebar-dynamic.tsx → sidebar/app-sidebar-dynamic.tsx} +1 -1
- package/template/components/{app-sidebar.tsx → sidebar/app-sidebar.tsx} +59 -74
- package/template/components/sidebar/index.ts +16 -0
- package/template/components/{secondary-nav.tsx → sidebar/secondary-nav.tsx} +2 -2
- package/template/components/{secondary-panel.tsx → sidebar/secondary-panel.tsx} +50 -7
- package/template/components/{sidebar-auto-collapse.tsx → sidebar/sidebar-auto-collapse.tsx} +6 -2
- package/template/components/{sidebar-shell.tsx → sidebar/sidebar-shell.tsx} +1 -1
- package/template/components/site-header.tsx +1 -1
- package/template/components/sites-board-view.tsx +67 -0
- package/template/components/sites-client.tsx +154 -0
- package/template/components/sites-table.tsx +249 -0
- package/template/components/table-properties/column-row.tsx +1 -90
- package/template/components/table-properties/draggable-list.ts +1 -49
- package/template/components/table-properties/drawer-button.tsx +1 -262
- package/template/components/table-properties/drawer.tsx +1 -1166
- package/template/components/table-properties/filter-card.tsx +1 -251
- package/template/components/table-properties/sort-card.tsx +1 -59
- package/template/components/table-properties/types.ts +28 -71
- package/template/components/team-board-view.tsx +122 -0
- package/template/components/team-client.tsx +100 -0
- package/template/components/team-page-header.tsx +92 -0
- package/template/components/team-table.tsx +553 -0
- package/template/components/templates/dedicated-search-landing-template.tsx +1 -124
- package/template/components/templates/dedicated-search-results-template.tsx +1 -19
- package/template/components/templates/list-page.tsx +1 -608
- package/template/components/templates/nested-secondary-panel-shell.tsx +1 -63
- package/template/components/templates/new-focus-template.tsx +659 -0
- package/template/components/templates/secondary-panel-hub-template.tsx +1 -1
- package/template/components/ui/accordion.tsx +1 -0
- package/template/components/ui/alert-dialog.tsx +1 -0
- package/template/components/ui/context-menu.tsx +1 -0
- package/template/components/ui/dot-pattern.tsx +1 -183
- package/template/components/ui/hover-card.tsx +1 -0
- package/template/components/ui/resizable.tsx +1 -68
- package/template/components/ui/scroll-area.tsx +1 -0
- package/template/components/ui/slider.tsx +1 -0
- package/template/docs/blueprints/README.md +86 -0
- package/template/docs/blueprints/_template.md +91 -0
- package/template/docs/blueprints/board-card.md +123 -0
- package/template/docs/blueprints/data-table.md +139 -0
- package/template/docs/blueprints/key-metrics.md +128 -0
- package/template/docs/blueprints/list-page-template.md +123 -0
- package/template/docs/blueprints/page-header.md +130 -0
- package/template/docs/command-menu-pattern.md +1 -1
- package/template/docs/component-selection-guide.md +224 -0
- package/template/docs/components-audit-2026-05.md +158 -0
- package/template/docs/data-views-pattern.md +17 -54
- package/template/docs/drawer-vs-dialog-pattern.md +1 -3
- package/template/docs/migrations/0001-brand-deep-alias-stabilization.md +95 -0
- package/template/docs/migrations/0002-exxat-token-namespace.md +154 -0
- package/template/docs/migrations/0003-globals-css-canonical.md +110 -0
- package/template/docs/migrations/README.md +100 -0
- package/template/docs/migrations/_template.md +64 -0
- package/template/docs/shell-surface-elevation-pattern.md +3 -5
- package/template/docs/token-taxonomy.md +416 -0
- package/template/eslint.config.mjs +27 -0
- package/template/hooks/use-secondary-panel-hub-nav.ts +1 -1
- package/template/lib/command-menu-config.ts +0 -1
- package/template/lib/command-menu-search-data.ts +27 -11
- package/template/lib/compliance-supported-views.ts +10 -0
- package/template/lib/conditional-rule-match.ts +6 -97
- package/template/lib/data-list-display-options.ts +1 -49
- package/template/lib/data-list-view-registry.ts +1 -104
- package/template/lib/data-list-view-surface.ts +1 -83
- package/template/lib/data-list-view.ts +1 -47
- package/template/lib/data-view-dashboard-placements-layout.ts +215 -0
- package/template/lib/data-view-dashboard-storage.ts +35 -38
- package/template/lib/dev-log.ts +1 -8
- package/template/lib/editable-target.ts +1 -10
- package/template/lib/list-page-table-properties.ts +1 -48
- package/template/lib/list-status-badges.ts +97 -4
- package/template/lib/mock/compliance-kpi.ts +61 -0
- package/template/lib/mock/compliance.ts +146 -0
- package/template/lib/mock/navigation.tsx +0 -9
- package/template/lib/mock/placements-kpi.ts +134 -0
- package/template/lib/mock/placements.ts +176 -0
- package/template/lib/mock/sites-directory.ts +16 -0
- package/template/lib/mock/sites-kpi.ts +25 -0
- package/template/lib/mock/team-kpi.ts +60 -0
- package/template/lib/mock/team.ts +118 -0
- package/template/lib/placement-board-card-layout.ts +79 -0
- package/template/lib/placements-supported-views.ts +12 -0
- package/template/lib/question-bank-supported-views.ts +0 -1
- package/template/lib/raf-throttle.ts +1 -45
- package/template/lib/row-height.ts +4 -10
- package/template/lib/sidebar-state-cookie.ts +11 -2
- package/template/lib/sites-supported-views.ts +10 -0
- package/template/lib/table-state-lifecycle.ts +2 -2
- package/template/lib/team-supported-views.ts +10 -0
- package/template/package.json +1 -0
- package/template/tests/setup.ts +25 -0
- package/consumer-extras/AGENTS.md +0 -76
- package/consumer-extras/cursor-skills/exxat-consumer-app/SKILL.md +0 -37
- package/consumer-extras/cursor-skills/exxat-focused-workflow-page/SKILL.md +0 -57
- package/consumer-extras/patterns/consumer-app-pattern.md +0 -39
- package/consumer-extras/patterns/focused-workflow-page-pattern.md +0 -84
- package/src/components/ui/button-group.tsx +0 -81
- package/src/theme.css +0 -16
- package/src/tokens/README.md +0 -15
- package/src/tokens/base.css +0 -337
- package/src/tokens/high-contrast.css +0 -1195
- package/src/tokens/layers.css +0 -224
- package/src/tokens/tailwind-bridge.css +0 -118
- package/src/tokens/themes.css +0 -201
- package/template/app/(app)/data-list/layout.tsx +0 -43
- package/template/app/(app)/data-list/page.tsx +0 -10
- package/template/app/(app)/examples/focused-workflow/page.tsx +0 -5
- package/template/components/app-route-loading.tsx +0 -14
- package/template/components/dashboard-onboarding-gallery.tsx +0 -13
- package/template/components/dashboard-onboarding.tsx +0 -21
- package/template/components/data-views/list-page-calendar-view.tsx +0 -593
- package/template/components/data-views/list-page-folder-columns-panel.tsx +0 -345
- package/template/components/examples/focused-workflow-showcase.tsx +0 -183
- package/template/components/list-hub-board-view.tsx +0 -68
- package/template/components/list-hub-client.tsx +0 -186
- package/template/components/list-hub-list-view.tsx +0 -36
- package/template/components/list-hub-panel-activator.tsx +0 -8
- package/template/components/list-hub-secondary-nav.tsx +0 -121
- package/template/components/list-hub-table.tsx +0 -336
- package/template/components/question-bank-folder-columns-panel.tsx +0 -104
- package/template/components/question-bank-list-view.tsx +0 -53
- package/template/components/secondary-panel/nav-link-rows.tsx +0 -83
- package/template/components/secondary-panels/list-hub-panel.tsx +0 -39
- package/template/components/secondary-panels/question-bank-panel.tsx +0 -39
- package/template/components/secondary-panels/registry.tsx +0 -15
- package/template/components/section-cards.tsx +0 -106
- package/template/components/templates/focused-workflow-layouts.tsx +0 -448
- package/template/components/templates/focused-workflow-page-template.tsx +0 -69
- package/template/components/templates/page-loading-shell.tsx +0 -262
- package/template/components/ui/button-group.tsx +0 -1
- package/template/docs/consumer-app-pattern.md +0 -39
- package/template/docs/focused-workflow-page-pattern.md +0 -84
- package/template/lib/list-hub-nav.ts +0 -121
- package/template/lib/mock/list-hub-directory.ts +0 -27
- package/template/lib/mock/list-hub-kpi.ts +0 -27
- package/template/lib/page-loading-variant.ts +0 -40
- /package/template/components/{getting-started.tsx → onboarding/getting-started.tsx} +0 -0
- /package/template/components/{nav-documents.tsx → sidebar/nav-documents.tsx} +0 -0
- /package/template/components/{nav-main.tsx → sidebar/nav-main.tsx} +0 -0
- /package/template/components/{nav-secondary.tsx → sidebar/nav-secondary.tsx} +0 -0
- /package/template/components/{nav-user.tsx → sidebar/nav-user.tsx} +0 -0
- /package/template/components/{sidebar-auto-open.tsx → sidebar/sidebar-auto-open.tsx} +0 -0
package/src/globals.css
CHANGED
|
@@ -1,10 +1,18 @@
|
|
|
1
1
|
/* ==========================================================================
|
|
2
|
-
EXXAT DESIGN SYSTEM — globals.css
|
|
3
|
-
|
|
2
|
+
EXXAT DESIGN SYSTEM — globals.css
|
|
3
|
+
Brands: Exxat One (Lavender · hue 270) · Exxat Prism (Rose · hue 343)
|
|
4
|
+
Standard: WCAG 2.1 Level AA
|
|
5
|
+
• Text contrast ≥ 4.5 : 1 (SC 1.4.3)
|
|
6
|
+
• UI control contrast ≥ 3 : 1 (SC 1.4.11)
|
|
7
|
+
• Focus ring ≥ 3 : 1 (SC 2.4.11)
|
|
8
|
+
• Touch targets ≥ 44 × 44 px (SC 2.5.5 / mobile)
|
|
4
9
|
========================================================================== */
|
|
5
10
|
|
|
6
11
|
@import "tailwindcss";
|
|
7
12
|
@import "tw-animate-css";
|
|
13
|
+
/* Inter is loaded via next/font/google in the consuming app's layout — no @import needed here. */
|
|
14
|
+
/* `@source` is declared by the consuming app's globals.css so the path resolves relative to its location
|
|
15
|
+
(workspace clone vs. npm install). See apps/web/app/globals.css. */
|
|
8
16
|
|
|
9
17
|
/* RTL layout direction support */
|
|
10
18
|
@custom-variant dark (&:is(.dark *));
|
|
@@ -12,8 +20,2194 @@
|
|
|
12
20
|
/* High-contrast variant — in-app High or Windows (JSON) contrast */
|
|
13
21
|
@custom-variant hc (&:is([data-contrast="high"] *, [data-contrast="windows"] *));
|
|
14
22
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
@
|
|
19
|
-
|
|
23
|
+
/* --------------------------------------------------------------------------
|
|
24
|
+
Tailwind v4 theme bridge — maps CSS custom-props → utility classes
|
|
25
|
+
-------------------------------------------------------------------------- */
|
|
26
|
+
@theme inline {
|
|
27
|
+
/* Typography */
|
|
28
|
+
--font-heading: "ivypresto-text";
|
|
29
|
+
--font-sans: "Inter", ui-sans-serif, system-ui, sans-serif;
|
|
30
|
+
/* Minimum product text: 11px — use `text-xs` or larger; avoid arbitrary classes below 11px */
|
|
31
|
+
--text-xs: 0.6875rem; /* 11px at 16px root */
|
|
32
|
+
|
|
33
|
+
/* Semantic color map */
|
|
34
|
+
--color-background: var(--background);
|
|
35
|
+
--color-foreground: var(--foreground);
|
|
36
|
+
--color-card: var(--card);
|
|
37
|
+
--color-card-foreground: var(--card-foreground);
|
|
38
|
+
--color-popover: var(--popover);
|
|
39
|
+
--color-popover-foreground: var(--popover-foreground);
|
|
40
|
+
--color-primary: var(--primary);
|
|
41
|
+
--color-primary-foreground: var(--primary-foreground);
|
|
42
|
+
--color-secondary: var(--secondary);
|
|
43
|
+
--color-secondary-foreground: var(--secondary-foreground);
|
|
44
|
+
--color-muted: var(--muted);
|
|
45
|
+
--color-muted-foreground: var(--muted-foreground);
|
|
46
|
+
--color-accent: var(--accent);
|
|
47
|
+
--color-accent-foreground: var(--accent-foreground);
|
|
48
|
+
--color-destructive: var(--destructive);
|
|
49
|
+
--color-destructive-foreground: var(--destructive-foreground);
|
|
50
|
+
--color-border: var(--border);
|
|
51
|
+
--color-border-control: var(--border-control);
|
|
52
|
+
--color-input: var(--input);
|
|
53
|
+
--color-input-background: var(--input-background);
|
|
54
|
+
--color-ring: var(--ring);
|
|
55
|
+
/* Modal / sheet / drawer scrim */
|
|
56
|
+
--color-overlay: var(--overlay);
|
|
57
|
+
|
|
58
|
+
/* Chart tokens */
|
|
59
|
+
--color-chart-1: var(--chart-1);
|
|
60
|
+
--color-chart-2: var(--chart-2);
|
|
61
|
+
--color-chart-3: var(--chart-3);
|
|
62
|
+
--color-chart-4: var(--chart-4);
|
|
63
|
+
--color-chart-5: var(--chart-5);
|
|
64
|
+
|
|
65
|
+
/* Chip / badge tokens (AA-compliant on light bg: ≥ 4.5:1) */
|
|
66
|
+
--color-chip-1: var(--chip-1);
|
|
67
|
+
--color-chip-2: var(--chip-2);
|
|
68
|
+
--color-chip-3: var(--chip-3);
|
|
69
|
+
--color-chip-4: var(--chip-4);
|
|
70
|
+
--color-chip-5: var(--chip-5);
|
|
71
|
+
--color-chip-destructive: var(--chip-destructive);
|
|
72
|
+
|
|
73
|
+
/* Brand accent + Exxat One tint scale (see :root --brand-*) */
|
|
74
|
+
--color-brand: var(--brand-color);
|
|
75
|
+
--color-brand-dark: var(--brand-color-dark);
|
|
76
|
+
--color-brand-foreground: var(--brand-foreground);
|
|
77
|
+
--color-brand-tint: var(--brand-tint);
|
|
78
|
+
--color-brand-tint-light: var(--brand-tint-light);
|
|
79
|
+
--color-brand-tint-subtle: var(--brand-tint-subtle);
|
|
80
|
+
--color-brand-color-light: var(--brand-color-light);
|
|
81
|
+
--color-brand-deep: var(--brand-color-deep);
|
|
82
|
+
|
|
83
|
+
/* Prism banner highlight */
|
|
84
|
+
--color-banner-prism: var(--banner-prism-bg);
|
|
85
|
+
|
|
86
|
+
/* Sidebar */
|
|
87
|
+
--color-sidebar: var(--sidebar);
|
|
88
|
+
--color-sidebar-foreground: var(--sidebar-foreground);
|
|
89
|
+
--color-sidebar-primary: var(--sidebar-primary);
|
|
90
|
+
--color-sidebar-primary-foreground: var(--sidebar-primary-foreground);
|
|
91
|
+
--color-sidebar-accent: var(--sidebar-accent);
|
|
92
|
+
--color-sidebar-accent-foreground: var(--sidebar-accent-foreground);
|
|
93
|
+
--color-sidebar-border: var(--sidebar-border);
|
|
94
|
+
--color-sidebar-ring: var(--sidebar-ring);
|
|
95
|
+
/* WCAG 1.4.3 — always mixed against real --sidebar (lavender / rose / dark) */
|
|
96
|
+
--color-sidebar-section-label: var(--sidebar-section-label-foreground);
|
|
97
|
+
|
|
98
|
+
/* Interactive hover — single source for ghost controls, lists, table chrome */
|
|
99
|
+
--color-interactive-hover: var(--interactive-hover);
|
|
100
|
+
--color-interactive-hover-foreground: var(--interactive-hover-foreground);
|
|
101
|
+
--color-interactive-hover-subtle: var(--interactive-hover-subtle);
|
|
102
|
+
--color-interactive-hover-soft: var(--interactive-hover-soft);
|
|
103
|
+
--color-interactive-hover-medium: var(--interactive-hover-medium);
|
|
104
|
+
--color-interactive-hover-strong: var(--interactive-hover-strong);
|
|
105
|
+
--color-interactive-hover-row: var(--interactive-hover-row);
|
|
106
|
+
|
|
107
|
+
/* DataTable — opaque surfaces for pinned/sticky cells and row states */
|
|
108
|
+
--color-dt-row-bg: var(--dt-row-bg);
|
|
109
|
+
--color-dt-row-hover: var(--dt-row-hover);
|
|
110
|
+
--color-dt-row-selected: var(--dt-row-selected);
|
|
111
|
+
--color-dt-row-selected-fg: var(--dt-row-selected-fg);
|
|
112
|
+
--color-dt-header-bg: var(--dt-header-bg);
|
|
113
|
+
--color-dt-group-bg: var(--dt-group-bg);
|
|
114
|
+
--color-dt-new-row-bg: var(--dt-new-row-bg);
|
|
115
|
+
--color-dt-new-row-border: var(--dt-new-row-border);
|
|
116
|
+
|
|
117
|
+
/* Border-radius scale (4 px base → 8 px default) */
|
|
118
|
+
--radius-sm: 4px;
|
|
119
|
+
--radius-md: 8px;
|
|
120
|
+
--radius-lg: 12px;
|
|
121
|
+
--radius-xl: 16px;
|
|
122
|
+
--radius-2xl: 20px;
|
|
123
|
+
--radius-3xl: 24px;
|
|
124
|
+
|
|
125
|
+
/* ============================================================
|
|
126
|
+
Exxat L0 — Tailwind utility bridges (additive)
|
|
127
|
+
------------------------------------------------------------
|
|
128
|
+
Short utility forms backed by --exxat-* canonical primitives.
|
|
129
|
+
They coexist with the shadcn-named bridges above. Prefer
|
|
130
|
+
these for new code; see apps/web/docs/token-taxonomy.md.
|
|
131
|
+
============================================================ */
|
|
132
|
+
--color-surface-1: var(--exxat-color-surface-1);
|
|
133
|
+
--color-surface-2: var(--exxat-color-surface-2);
|
|
134
|
+
--color-surface-3: var(--exxat-color-surface-3);
|
|
135
|
+
--color-surface-muted: var(--exxat-color-surface-muted);
|
|
136
|
+
--color-surface-accent: var(--exxat-color-surface-accent);
|
|
137
|
+
--color-surface-sidebar: var(--exxat-color-surface-sidebar);
|
|
138
|
+
--color-ink-1: var(--exxat-color-ink-1);
|
|
139
|
+
--color-ink-2: var(--exxat-color-ink-2);
|
|
140
|
+
--color-ink-on-brand: var(--exxat-color-ink-on-brand);
|
|
141
|
+
--color-brand-1: var(--exxat-color-brand-1);
|
|
142
|
+
--color-brand-2: var(--exxat-color-brand-2);
|
|
143
|
+
--color-brand-3: var(--exxat-color-brand-3);
|
|
144
|
+
--color-brand-tint-1: var(--exxat-color-brand-tint-1);
|
|
145
|
+
--color-brand-tint-2: var(--exxat-color-brand-tint-2);
|
|
146
|
+
--color-brand-tint-3: var(--exxat-color-brand-tint-3);
|
|
147
|
+
--color-border-1: var(--exxat-color-border-1);
|
|
148
|
+
--color-focus-ring: var(--exxat-color-focus-ring);
|
|
149
|
+
|
|
150
|
+
/* Exxat L0 radius scale → rounded-1 … rounded-6 */
|
|
151
|
+
--radius-1: var(--exxat-radius-1);
|
|
152
|
+
--radius-2: var(--exxat-radius-2);
|
|
153
|
+
--radius-3: var(--exxat-radius-3);
|
|
154
|
+
--radius-4: var(--exxat-radius-4);
|
|
155
|
+
--radius-5: var(--exxat-radius-5);
|
|
156
|
+
--radius-6: var(--exxat-radius-6);
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/* --------------------------------------------------------------------------
|
|
160
|
+
Text size (Settings → Appearance)
|
|
161
|
+
Pattern: root `font-size` steps like iOS Larger Text / Android font scale /
|
|
162
|
+
browser zoom-at-root so rem-based components track together. We keep steps
|
|
163
|
+
modest; `compact` redefines `--text-xs` so minimum UI copy stays 11px (Exxat
|
|
164
|
+
accessibility rule) when the root is slightly below 16px.
|
|
165
|
+
-------------------------------------------------------------------------- */
|
|
166
|
+
html[data-text-size="compact"] {
|
|
167
|
+
font-size: 94%;
|
|
168
|
+
--text-xs: 0.7333rem; /* ~11px when 1rem ≈ 15px */
|
|
169
|
+
}
|
|
170
|
+
html[data-text-size="large"] {
|
|
171
|
+
font-size: 112.5%;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/* ==========================================================================
|
|
175
|
+
:root — Exxat One · Light Mode (brand hue 286.1)
|
|
176
|
+
All contrast ratios verified against oklch(1 0 0) white background.
|
|
177
|
+
========================================================================== */
|
|
178
|
+
:root {
|
|
179
|
+
/* font-size intentionally NOT overridden here.
|
|
180
|
+
Shadcn components assume 1rem = 16px (browser default).
|
|
181
|
+
Overriding to 87.5% / 14px breaks rem-based spacing on all devices,
|
|
182
|
+
and compounds incorrectly at Windows 150% system zoom.
|
|
183
|
+
If a compact 14px density is needed, apply it at the component/page level
|
|
184
|
+
via a scoped class, not globally on :root. */
|
|
185
|
+
/* Minimum readable UI copy: 11px (`text-xs` / --text-xs). Do not use smaller arbitrary sizes. */
|
|
186
|
+
|
|
187
|
+
/* ── Layout ─────────────────────────────────────────────────── */
|
|
188
|
+
/* SiteHeader / breadcrumb height. Mirrored on the SidebarProvider for
|
|
189
|
+
descendants; declared here too so JS that reads from documentElement
|
|
190
|
+
(e.g. DataTable sticky-head offset) can resolve it. Plain px so
|
|
191
|
+
`parseFloat` can read it as a number. Keep in sync with `headerHeight`
|
|
192
|
+
in components/sidebar-shell.tsx (currently `calc(var(--spacing) * 12)` = 48px). */
|
|
193
|
+
--header-height: 48px;
|
|
194
|
+
|
|
195
|
+
/* ── Typography ─────────────────────────────────────────────── */
|
|
196
|
+
/* Ivy Presto loaded via Adobe Fonts Kit wuk5wqn (use.typekit.net) */
|
|
197
|
+
--font-heading: "ivypresto-text";
|
|
198
|
+
|
|
199
|
+
/* ── Brand — Exxat One (hue 286.1) ─────────────────────────── */
|
|
200
|
+
/* Primary surface — requested token */
|
|
201
|
+
--brand-tint: oklch(0.9676 0.016 286.1);
|
|
202
|
+
/* Lighter / darker washes (same hue) for nested UI & hovers */
|
|
203
|
+
--brand-tint-light: oklch(0.993 0.007 286.1);
|
|
204
|
+
--brand-tint-subtle: oklch(0.935 0.024 286.1);
|
|
205
|
+
/* Interactive accent + scale (readable on white; pairs with --brand-tint) */
|
|
206
|
+
--brand-color: oklch(0.50 0.14 286.1);
|
|
207
|
+
--brand-color-light: oklch(0.78 0.09 286.1);
|
|
208
|
+
--brand-color-dark: oklch(0.38 0.11 286.1);
|
|
209
|
+
--brand-color-deep: oklch(0.28 0.085 286.1);
|
|
210
|
+
--brand-foreground: oklch(0.985 0 0);
|
|
211
|
+
/* Fixed swatches for brand picker (Exxat One vs Prism), independent of active theme */
|
|
212
|
+
--brand-preview-one: var(--brand-tint);
|
|
213
|
+
--brand-preview-prism: oklch(0.57 0.24 342);
|
|
214
|
+
|
|
215
|
+
/**
|
|
216
|
+
* Ask Leo panel tints (same mixes as the vertical wash). Use for blobs, cards, etc.
|
|
217
|
+
* `--leo-surface-gradient` is the full linear wash on `AskLeoSidebar`.
|
|
218
|
+
*/
|
|
219
|
+
--leo-surface-tint-a: color-mix(in oklch, var(--brand-color) 4%, var(--background));
|
|
220
|
+
--leo-surface-tint-b: color-mix(in oklch, var(--brand-color) 8%, var(--background));
|
|
221
|
+
--leo-surface-gradient: linear-gradient(180deg, var(--leo-surface-tint-a) 0%, var(--leo-surface-tint-b) 100%);
|
|
222
|
+
|
|
223
|
+
/* KeyMetrics `variant="flat"` — no band surface; bottom brand glow only (OKLCH). */
|
|
224
|
+
--key-metrics-flat-cell-bg: transparent;
|
|
225
|
+
--key-metrics-flat-divider: color-mix(in oklch, var(--sidebar-border) 55%, transparent);
|
|
226
|
+
--key-metrics-flat-band-radial: radial-gradient(
|
|
227
|
+
ellipse 120% 68% at 50% 100%,
|
|
228
|
+
color-mix(in oklch, var(--brand-color) 20%, transparent) 0%,
|
|
229
|
+
color-mix(in oklch, var(--brand-color) 8%, transparent) 42%,
|
|
230
|
+
transparent 72%
|
|
231
|
+
);
|
|
232
|
+
--key-metrics-flat-band-shadow: none;
|
|
233
|
+
--key-metrics-card-glow-radial: radial-gradient(
|
|
234
|
+
ellipse 110% 90% at 50% 100%,
|
|
235
|
+
color-mix(in oklch, var(--brand-color) 18%, transparent) 0%,
|
|
236
|
+
transparent 65%
|
|
237
|
+
);
|
|
238
|
+
|
|
239
|
+
/* ── Surfaces ────────────────────────────────────────────────── */
|
|
240
|
+
--background: oklch(1 0 0);
|
|
241
|
+
--foreground: oklch(0.145 0 0); /* ≈ #1A1A1A — 17:1 on white ✓ */
|
|
242
|
+
--card: oklch(1 0 0);
|
|
243
|
+
--card-foreground: oklch(0.145 0 0);
|
|
244
|
+
--popover: oklch(1 0 0);
|
|
245
|
+
--popover-foreground: oklch(0.145 0 0);
|
|
246
|
+
|
|
247
|
+
/* ── Primary ─────────────────────────────────────────────────── */
|
|
248
|
+
/* Default / ghost / solid primary actions — neutral charcoal (style guide) */
|
|
249
|
+
--primary: oklch(0.3457 0.0052 286.13);
|
|
250
|
+
--primary-foreground: oklch(0.985 0 0);
|
|
251
|
+
|
|
252
|
+
/* ── Secondary / Muted / Accent ──────────────────────────────── */
|
|
253
|
+
--secondary: oklch(0.95 0.0058 264.53);
|
|
254
|
+
--secondary-foreground: oklch(0.082 0 0);
|
|
255
|
+
--muted: oklch(0.945 0.002 270);
|
|
256
|
+
--muted-foreground: oklch(0.50 0.012 270); /* 5.5:1 on white ✓ */
|
|
257
|
+
--accent: oklch(0.925 0.005 260);
|
|
258
|
+
--accent-foreground: oklch(0.082 0 0);
|
|
259
|
+
|
|
260
|
+
/* ── Destructive ─────────────────────────────────────────────── */
|
|
261
|
+
/* oklch(0.55 0.22 25) ≈ #C0392B — 5.1:1 on white ✓ */
|
|
262
|
+
--destructive: oklch(0.55 0.22 25);
|
|
263
|
+
--destructive-foreground: oklch(1 0 0);
|
|
264
|
+
|
|
265
|
+
/* ── Borders ─────────────────────────────────────────────────── */
|
|
266
|
+
/* Decorative: cards, dividers — no AA contrast requirement */
|
|
267
|
+
--border: oklch(0.92 0.002 270);
|
|
268
|
+
|
|
269
|
+
/* Form-field boundary — WCAG 1.4.11 requires 3:1 against bg.
|
|
270
|
+
--border-control-3: L=0.62 ≈ #90929A → borderline; use with care.
|
|
271
|
+
--border-control-35: L=0.25 → ≥ 3.5:1 — recommended for inputs. */
|
|
272
|
+
--border-control: oklch(0.82 0.004 270); /* subtle (layout use only) */
|
|
273
|
+
--border-control-3: oklch(0.6196 0.0092 270); /* ≈ 3:1 on white (minimum) */
|
|
274
|
+
--border-control-35: oklch(0.25 0.01 270); /* ≈ 3.5:1+ (recommended) */
|
|
275
|
+
--control-border: var(--border-control-3); /* default form-field border */
|
|
276
|
+
|
|
277
|
+
/* ── Input ───────────────────────────────────────────────────── */
|
|
278
|
+
/* Raised contrast target for control outlines (>= 3.1:1 on white). */
|
|
279
|
+
--input: oklch(0.62 0.01 264.52);
|
|
280
|
+
--input-background: oklch(0.97 0.002 270);
|
|
281
|
+
|
|
282
|
+
/* ── Focus ring ──────────────────────────────────────────────── */
|
|
283
|
+
/* 3:1+ contrast on both light & dark backgrounds (WCAG 2.4.11) */
|
|
284
|
+
--ring: oklch(0.25 0 0);
|
|
285
|
+
|
|
286
|
+
/* ── Charts ──────────────────────────────────────────────────── */
|
|
287
|
+
--chart-1: oklch(0.55 0.22 264.116);
|
|
288
|
+
--chart-2: oklch(0.48 0.15 184.704);
|
|
289
|
+
--chart-3: oklch(0.32 0.08 227.392);
|
|
290
|
+
--chart-4: oklch(0.65 0.18 84.429);
|
|
291
|
+
--chart-5: oklch(0.58 0.18 70.08);
|
|
292
|
+
|
|
293
|
+
/* ── Chip / Badge ────────────────────────────────────────────── */
|
|
294
|
+
/* AA-compliant on white: all ≥ 4.5:1 (WCAG 1.4.3) */
|
|
295
|
+
--chip-1: oklch(0.38 0.18 264); /* indigo */
|
|
296
|
+
--chip-2: oklch(0.35 0.14 184); /* teal */
|
|
297
|
+
--chip-3: oklch(0.32 0.08 227); /* slate */
|
|
298
|
+
--chip-4: oklch(0.42 0.12 84); /* amber */
|
|
299
|
+
--chip-5: oklch(0.42 0.14 70); /* orange */
|
|
300
|
+
--chip-destructive: oklch(0.40 0.18 25); /* red */
|
|
301
|
+
|
|
302
|
+
/* ── Prism promo banner ──────────────────────────────────────── */
|
|
303
|
+
/* Rose hue 343 — used universally regardless of active theme */
|
|
304
|
+
--banner-prism-bg: oklch(0.97 0.02 343);
|
|
305
|
+
|
|
306
|
+
/* ── Sidebar — Exxat One brand tint ───────────────────────────── */
|
|
307
|
+
--sidebar: var(--brand-tint);
|
|
308
|
+
--sidebar-foreground: oklch(0.145 0 0);
|
|
309
|
+
--sidebar-primary: oklch(0.082 0 0);
|
|
310
|
+
--sidebar-primary-foreground: oklch(0.985 0 0);
|
|
311
|
+
--sidebar-accent: oklch(0.945 0.025 286.1);
|
|
312
|
+
--sidebar-accent-foreground: oklch(0.3457 0.0052 286.13);
|
|
313
|
+
--sidebar-border: oklch(0.92 0.025 286.1);
|
|
314
|
+
--sidebar-ring: oklch(0.25 0 0);
|
|
315
|
+
/* Nav section titles — ≥4.5:1 vs --sidebar (not vs page white) */
|
|
316
|
+
--sidebar-section-label-foreground: color-mix(in oklch, var(--sidebar-foreground) 58%, var(--sidebar));
|
|
317
|
+
/* Nested secondary rail — elevation 1: brand wash, lighter than `--sidebar` / `--brand-tint`. */
|
|
318
|
+
--secondary-panel-bg: color-mix(in oklch, var(--background) 40%, var(--brand-tint-light) 60%);
|
|
319
|
+
|
|
320
|
+
/* Browser UI (meta theme-color) — aligned with --brand-tint */
|
|
321
|
+
--theme-color-chrome: #f3f2f8;
|
|
322
|
+
|
|
323
|
+
/* ── Border radius ───────────────────────────────────────────── */
|
|
324
|
+
--radius: 0.5rem; /* 8px base */
|
|
325
|
+
|
|
326
|
+
/* ── Density / touch targets ─────────────────────────────────── */
|
|
327
|
+
--scaling: 1;
|
|
328
|
+
--control-height: calc(40px * var(--scaling));
|
|
329
|
+
--control-height-sm: calc(32px * var(--scaling));
|
|
330
|
+
/* WCAG 2.5.5 — minimum 44×44 px touch target (mobile only) */
|
|
331
|
+
--control-height-touch: 44px;
|
|
332
|
+
--control-padding-y: calc(8px * var(--scaling));
|
|
333
|
+
--control-padding-x: calc(12px * var(--scaling));
|
|
334
|
+
--table-row-height: calc(48px * var(--scaling));
|
|
335
|
+
|
|
336
|
+
/* ── Interactive hover (ties to --muted / --accent — theme overrides apply) ─ */
|
|
337
|
+
--interactive-hover: var(--muted);
|
|
338
|
+
--interactive-hover-foreground: var(--foreground);
|
|
339
|
+
--interactive-hover-subtle: color-mix(in oklch, var(--muted) 50%, var(--background));
|
|
340
|
+
--interactive-hover-soft: color-mix(in oklch, var(--muted) 40%, var(--background));
|
|
341
|
+
--interactive-hover-medium: color-mix(in oklch, var(--muted) 60%, var(--background));
|
|
342
|
+
--interactive-hover-strong: color-mix(in oklch, var(--muted) 70%, var(--background));
|
|
343
|
+
--interactive-hover-row: color-mix(in oklch, var(--accent) 50%, var(--background));
|
|
344
|
+
|
|
345
|
+
/* ── DataTable — opaque row/cell surfaces (pinned cells MUST be opaque) ── */
|
|
346
|
+
--dt-row-bg: var(--background);
|
|
347
|
+
--dt-row-hover: oklch(0.972 0.001 270);
|
|
348
|
+
--dt-row-selected: oklch(0.962 0.003 260);
|
|
349
|
+
--dt-row-selected-fg: var(--foreground);
|
|
350
|
+
--dt-header-bg: var(--background);
|
|
351
|
+
--dt-group-bg: oklch(0.972 0.001 270);
|
|
352
|
+
--dt-new-row-bg: oklch(from var(--brand-color) 0.985 0.006 h);
|
|
353
|
+
--dt-new-row-border: var(--brand-color);
|
|
354
|
+
|
|
355
|
+
/* ── Transitions ─────────────────────────────────────────────── */
|
|
356
|
+
--transition-fast: 0.15s ease;
|
|
357
|
+
--transition-normal: 0.25s ease-in-out;
|
|
358
|
+
--transition-colors: color 0.15s ease, background-color 0.15s ease, border-color 0.15s ease;
|
|
359
|
+
|
|
360
|
+
/* ── Shadows ─────────────────────────────────────────────────── */
|
|
361
|
+
--shadow-sm: oklch(0 0 0 / 0.08) 0px 1px 2px 0px;
|
|
362
|
+
--shadow-md: oklch(0 0 0 / 0.08) 0px 2px 4px -1px, oklch(0 0 0 / 0.06) 0px 1px 2px;
|
|
363
|
+
--shadow-lg: oklch(0 0 0 / 0.10) 0px 4px 8px -2px, oklch(0 0 0 / 0.06) 0px 2px 4px;
|
|
364
|
+
|
|
365
|
+
/* ── Sticky column edge fade (data tables) ───────────────────── */
|
|
366
|
+
--sticky-edge-fade: oklch(0 0 0 / 0.08);
|
|
367
|
+
|
|
368
|
+
/* ── Overlay scrim (Sheet / Drawer / Dialog) ─────────────────── */
|
|
369
|
+
/* Softer than raw bg-black/10; follows foreground hue (not pure black) */
|
|
370
|
+
--overlay: color-mix(in oklch, var(--foreground) 5%, transparent);
|
|
371
|
+
|
|
372
|
+
/* ── Avatar initials (table) ───────────────────────────────────── */
|
|
373
|
+
/* Soft brand wash + brand ink — no black fills; ≥4.5:1 on white rows */
|
|
374
|
+
--avatar-initials-bg: color-mix(in oklch, var(--brand-color) 14%, oklch(1 0 0));
|
|
375
|
+
--avatar-initials-fg: var(--brand-color-dark);
|
|
376
|
+
|
|
377
|
+
/* ── KPI insight severity (KeyMetrics) ────────────────────────── */
|
|
378
|
+
--insight-severity-warning-bg: color-mix(in oklch, var(--chart-4) 15%, transparent);
|
|
379
|
+
--insight-severity-warning-fg: color-mix(in oklch, var(--chart-4) 75%, var(--foreground));
|
|
380
|
+
--insight-severity-info-bg: color-mix(in oklch, var(--chart-1) 14%, transparent);
|
|
381
|
+
--insight-severity-info-fg: color-mix(in oklch, var(--chart-1) 75%, var(--foreground));
|
|
382
|
+
|
|
383
|
+
/* ── Tinted icon discs — soft wash (≈14% tint like legacy inline styles); contrast from --chip-* / brand-dark on fg */
|
|
384
|
+
--icon-disc-chart-2-bg: color-mix(in oklch, var(--chart-2) 14%, transparent);
|
|
385
|
+
--icon-disc-chart-2-fg: var(--chip-2);
|
|
386
|
+
--icon-disc-chart-4-bg: color-mix(in oklch, var(--chart-4) 14%, transparent);
|
|
387
|
+
--icon-disc-chart-4-fg: var(--chip-4);
|
|
388
|
+
--icon-disc-brand-bg: color-mix(in oklch, var(--brand-color) 12%, transparent);
|
|
389
|
+
--icon-disc-brand-fg: var(--brand-color-dark);
|
|
390
|
+
--icon-disc-danger-bg: color-mix(in oklch, var(--destructive) 14%, transparent);
|
|
391
|
+
--icon-disc-danger-fg: var(--chip-destructive);
|
|
392
|
+
|
|
393
|
+
/* ── Conditional formatting rule backgrounds (table drawer) ─── */
|
|
394
|
+
--conditional-rule-green: color-mix(in oklch, var(--chart-2) 22%, transparent);
|
|
395
|
+
--conditional-rule-yellow: color-mix(in oklch, var(--chart-4) 30%, transparent);
|
|
396
|
+
--conditional-rule-blue: color-mix(in oklch, var(--chart-1) 22%, transparent);
|
|
397
|
+
--conditional-rule-red: color-mix(in oklch, var(--destructive) 22%, transparent);
|
|
398
|
+
--conditional-rule-purple: color-mix(in oklch, var(--brand-color) 22%, transparent);
|
|
399
|
+
--conditional-rule-orange: color-mix(in oklch, var(--chart-5) 25%, transparent);
|
|
400
|
+
|
|
401
|
+
/* ============================================================
|
|
402
|
+
Exxat L0 — canonical namespace (additive aliases)
|
|
403
|
+
------------------------------------------------------------
|
|
404
|
+
SLDS-style flat namespace. These are the official names the
|
|
405
|
+
DS scales on — components SHOULD migrate to these over time.
|
|
406
|
+
Existing shadcn-style names above are L1 aliases that resolve
|
|
407
|
+
to the same values. The L0 names use var(...) so they inherit
|
|
408
|
+
every theme override (.dark / .theme-one / .theme-prism /
|
|
409
|
+
[data-contrast="high"]) automatically — no per-theme block
|
|
410
|
+
needed.
|
|
411
|
+
Reference: apps/web/docs/token-taxonomy.md (§ L0 Exxat).
|
|
412
|
+
============================================================ */
|
|
413
|
+
|
|
414
|
+
/* ── Surfaces (canvas → muted → input) ──────────────────────── */
|
|
415
|
+
--exxat-color-surface-1: var(--background);
|
|
416
|
+
--exxat-color-surface-2: var(--card);
|
|
417
|
+
--exxat-color-surface-3: var(--popover);
|
|
418
|
+
--exxat-color-surface-muted: var(--muted);
|
|
419
|
+
--exxat-color-surface-accent: var(--accent);
|
|
420
|
+
--exxat-color-surface-secondary: var(--secondary);
|
|
421
|
+
--exxat-color-surface-sidebar: var(--sidebar);
|
|
422
|
+
--exxat-color-surface-input: var(--input-background);
|
|
423
|
+
|
|
424
|
+
/* ── Ink (foreground / on-surface text) ─────────────────────── */
|
|
425
|
+
--exxat-color-ink-1: var(--foreground);
|
|
426
|
+
--exxat-color-ink-2: var(--muted-foreground);
|
|
427
|
+
--exxat-color-ink-on-surface-2: var(--card-foreground);
|
|
428
|
+
--exxat-color-ink-on-surface-3: var(--popover-foreground);
|
|
429
|
+
--exxat-color-ink-on-brand: var(--brand-foreground);
|
|
430
|
+
--exxat-color-ink-on-primary: var(--primary-foreground);
|
|
431
|
+
--exxat-color-ink-on-secondary: var(--secondary-foreground);
|
|
432
|
+
--exxat-color-ink-on-accent: var(--accent-foreground);
|
|
433
|
+
--exxat-color-ink-on-destructive: var(--destructive-foreground);
|
|
434
|
+
|
|
435
|
+
/* ── Brand (interactive accent + scale) ─────────────────────── */
|
|
436
|
+
--exxat-color-brand-1: var(--brand-color);
|
|
437
|
+
--exxat-color-brand-2: var(--brand-color-dark);
|
|
438
|
+
--exxat-color-brand-3: var(--brand-color-light);
|
|
439
|
+
--exxat-color-brand-deep: var(--brand-color-deep);
|
|
440
|
+
--exxat-color-brand-tint-1: var(--brand-tint);
|
|
441
|
+
--exxat-color-brand-tint-2: var(--brand-tint-subtle);
|
|
442
|
+
--exxat-color-brand-tint-3: var(--brand-tint-light);
|
|
443
|
+
|
|
444
|
+
/* ── Wordmark ink (Exxat product logo SVG + HTML prefix) ─────
|
|
445
|
+
Brand-frozen slate/cool-grey pair used by the "Exxat" SVG
|
|
446
|
+
letters and the HTML wordmark prefix. Held outside the
|
|
447
|
+
`--foreground` family because the wordmark stays at brand
|
|
448
|
+
ink even when the rest of the surface inverts. Replaces
|
|
449
|
+
the bare `#273441` / `#A8B2BA` literals in
|
|
450
|
+
`apps/web/components/exxat-product-logo.tsx` and
|
|
451
|
+
`product-wordmark.tsx`. */
|
|
452
|
+
--exxat-color-wordmark-ink-light: oklch(0.301 0.022 252); /* ≈ #273441 */
|
|
453
|
+
--exxat-color-wordmark-ink-dark: oklch(0.755 0.012 230); /* ≈ #A8B2BA */
|
|
454
|
+
|
|
455
|
+
/* ── Action surfaces ────────────────────────────────────────── */
|
|
456
|
+
--exxat-color-action-primary: var(--primary);
|
|
457
|
+
--exxat-color-action-secondary: var(--secondary);
|
|
458
|
+
--exxat-color-action-destructive: var(--destructive);
|
|
459
|
+
|
|
460
|
+
/* ── Borders (decorative + form-field ladder) ──────────────── */
|
|
461
|
+
--exxat-color-border-1: var(--border);
|
|
462
|
+
--exxat-color-border-control-subtle: var(--border-control);
|
|
463
|
+
--exxat-color-border-control-1: var(--border-control-3);
|
|
464
|
+
--exxat-color-border-control-2: var(--border-control-35);
|
|
465
|
+
|
|
466
|
+
/* ── Focus + overlay ────────────────────────────────────────── */
|
|
467
|
+
--exxat-color-focus-ring: var(--ring);
|
|
468
|
+
--exxat-color-overlay: var(--overlay);
|
|
469
|
+
|
|
470
|
+
/* ── Chart slots ────────────────────────────────────────────── */
|
|
471
|
+
--exxat-color-chart-1: var(--chart-1);
|
|
472
|
+
--exxat-color-chart-2: var(--chart-2);
|
|
473
|
+
--exxat-color-chart-3: var(--chart-3);
|
|
474
|
+
--exxat-color-chart-4: var(--chart-4);
|
|
475
|
+
--exxat-color-chart-5: var(--chart-5);
|
|
476
|
+
|
|
477
|
+
/* ── Chip / badge slots ─────────────────────────────────────── */
|
|
478
|
+
--exxat-color-chip-1: var(--chip-1);
|
|
479
|
+
--exxat-color-chip-2: var(--chip-2);
|
|
480
|
+
--exxat-color-chip-3: var(--chip-3);
|
|
481
|
+
--exxat-color-chip-4: var(--chip-4);
|
|
482
|
+
--exxat-color-chip-5: var(--chip-5);
|
|
483
|
+
--exxat-color-chip-destructive: var(--chip-destructive);
|
|
484
|
+
|
|
485
|
+
/* ── Radius scale ──────────────────────────────────────────── */
|
|
486
|
+
--exxat-radius-1: 4px;
|
|
487
|
+
--exxat-radius-2: 8px;
|
|
488
|
+
--exxat-radius-3: 12px;
|
|
489
|
+
--exxat-radius-4: 16px;
|
|
490
|
+
--exxat-radius-5: 20px;
|
|
491
|
+
--exxat-radius-6: 24px;
|
|
492
|
+
|
|
493
|
+
/* ── Spacing scale ─────────────────────────────────────────── */
|
|
494
|
+
--exxat-spacing-1: 0.25rem;
|
|
495
|
+
--exxat-spacing-2: 0.5rem;
|
|
496
|
+
--exxat-spacing-3: 0.75rem;
|
|
497
|
+
--exxat-spacing-4: 1rem;
|
|
498
|
+
--exxat-spacing-5: 1.25rem;
|
|
499
|
+
--exxat-spacing-6: 1.5rem;
|
|
500
|
+
--exxat-spacing-8: 2rem;
|
|
501
|
+
--exxat-spacing-12: 3rem;
|
|
502
|
+
|
|
503
|
+
/* ── Control height scale ──────────────────────────────────── */
|
|
504
|
+
--exxat-control-height-1: var(--control-height-sm);
|
|
505
|
+
--exxat-control-height-2: var(--control-height);
|
|
506
|
+
--exxat-control-height-3: var(--control-height-touch);
|
|
507
|
+
}
|
|
508
|
+
|
|
509
|
+
/* ==========================================================================
|
|
510
|
+
Dark Mode — Exxat One base (neutral surfaces; brand uses --brand-*)
|
|
511
|
+
========================================================================== */
|
|
512
|
+
.dark {
|
|
513
|
+
--sticky-edge-fade: oklch(0 0 0 / 0.32);
|
|
514
|
+
|
|
515
|
+
/* Brand-tint scale for dark mode — same hue family as :root but at dark-mode
|
|
516
|
+
lightness so derived surfaces (`--secondary-panel-bg`, `--sidebar` fallback
|
|
517
|
+
via `var(--brand-tint)`, etc.) read as dark brand surfaces, not pale
|
|
518
|
+
pastel washes. Themed `.dark` variants (`.theme-one.dark`,
|
|
519
|
+
`.theme-prism.dark`, …) override these with their own hue.
|
|
520
|
+
|
|
521
|
+
Chroma note: at L≈0.27 the OKLCH hue-discrimination threshold is much
|
|
522
|
+
higher than at L≈0.97 (Helmholtz–Kohlrausch). The PRIMARY brand surface
|
|
523
|
+
(`--brand-tint`) needs ~3–4× the chroma of its light-mode counterpart so
|
|
524
|
+
different products read as visibly different in dark mode. The lighter /
|
|
525
|
+
subtler scale steps stay low-chroma — they're elevation hints, not the
|
|
526
|
+
brand carrier. */
|
|
527
|
+
--brand-tint: oklch(0.30 0.05 270);
|
|
528
|
+
--brand-tint-light: oklch(0.34 0.04 270);
|
|
529
|
+
--brand-tint-subtle: oklch(0.26 0.025 270);
|
|
530
|
+
|
|
531
|
+
/* Canvas — charcoal grey with a perceptible whisper of brand chroma (still
|
|
532
|
+
≥ 12:1 against --foreground). Was 0.008 — below the OKLCH hue-perception
|
|
533
|
+
threshold at L 0.20, so the canvas read as dead-neutral grey. 0.014 ties
|
|
534
|
+
the canvas to the theme without compromising readability. */
|
|
535
|
+
--background: oklch(0.20 0.014 270);
|
|
536
|
+
--foreground: oklch(0.985 0 0);
|
|
537
|
+
/* Dark surface elevation ladder (see commentary at line ~605 for the full
|
|
538
|
+
stack across themed blocks):
|
|
539
|
+
--background L=0.20 canvas
|
|
540
|
+
--secondary-panel-bg L=0.22 nested chrome (between sidebar & canvas)
|
|
541
|
+
--card L=0.225 subtle inline elevation
|
|
542
|
+
--sidebar /input-bg L=0.245 outer chrome
|
|
543
|
+
--popover L=0.275 floating menus / dropdowns
|
|
544
|
+
|
|
545
|
+
Card stays at +0.025 above canvas so it reads as the same surface family.
|
|
546
|
+
Popover lifts further (+0.075) so it visibly floats above the canvas it
|
|
547
|
+
covers — a too-close popover blends into the page and a dropdown loses
|
|
548
|
+
its boundary. */
|
|
549
|
+
--card: oklch(0.225 0.008 270);
|
|
550
|
+
--card-foreground: oklch(0.985 0 0);
|
|
551
|
+
--popover: oklch(0.275 0.012 270);
|
|
552
|
+
--popover-foreground: oklch(0.985 0 0);
|
|
553
|
+
--primary: oklch(0.985 0 0);
|
|
554
|
+
--primary-foreground: oklch(0.3457 0.0052 286.13);
|
|
555
|
+
--secondary: oklch(0.31 0.04 270);
|
|
556
|
+
--secondary-foreground: oklch(0.985 0 0);
|
|
557
|
+
--muted: oklch(0.31 0.04 270);
|
|
558
|
+
--muted-foreground: oklch(0.72 0.012 270); /* ≥ 4.5:1 on dark bg ✓ */
|
|
559
|
+
--accent: oklch(0.33 0.06 270);
|
|
560
|
+
--accent-foreground: oklch(0.985 0 0);
|
|
561
|
+
--destructive: oklch(0.65 0.20 25); /* brighter for dark bg */
|
|
562
|
+
--destructive-foreground: oklch(0.10 0 0);
|
|
563
|
+
|
|
564
|
+
/* KeyMetrics flat band — no surface; bottom brand glow only (OKLCH). */
|
|
565
|
+
--key-metrics-flat-cell-bg: transparent;
|
|
566
|
+
--key-metrics-flat-divider: color-mix(in oklch, var(--sidebar-border) 55%, transparent);
|
|
567
|
+
--key-metrics-flat-band-radial: radial-gradient(
|
|
568
|
+
ellipse 120% 68% at 50% 100%,
|
|
569
|
+
color-mix(in oklch, var(--brand-color) 26%, transparent) 0%,
|
|
570
|
+
color-mix(in oklch, var(--brand-color) 10%, transparent) 42%,
|
|
571
|
+
transparent 72%
|
|
572
|
+
);
|
|
573
|
+
--key-metrics-flat-band-shadow: none;
|
|
574
|
+
--key-metrics-card-glow-radial: radial-gradient(
|
|
575
|
+
ellipse 110% 90% at 50% 100%,
|
|
576
|
+
color-mix(in oklch, var(--brand-color) 22%, transparent) 0%,
|
|
577
|
+
transparent 62%
|
|
578
|
+
);
|
|
579
|
+
|
|
580
|
+
/* Borders — visible but not washed out on dark surfaces */
|
|
581
|
+
--border: oklch(0.38 0.008 270);
|
|
582
|
+
--border-control: oklch(0.72 0.012 270);
|
|
583
|
+
--border-control-3: oklch(0.78 0.012 270);
|
|
584
|
+
--border-control-35: oklch(0.75 0.012 270);
|
|
585
|
+
--control-border: var(--border-control-3);
|
|
586
|
+
|
|
587
|
+
--input: oklch(0.72 0.012 270);
|
|
588
|
+
--input-background: oklch(0.245 0 0);
|
|
589
|
+
|
|
590
|
+
/* Focus ring — 3:1+ on dark bg */
|
|
591
|
+
--ring: oklch(0.85 0 0);
|
|
592
|
+
|
|
593
|
+
/* Charts — higher lightness for dark surfaces */
|
|
594
|
+
--chart-1: oklch(0.70 0.22 264.376);
|
|
595
|
+
--chart-2: oklch(0.75 0.15 162.48);
|
|
596
|
+
--chart-3: oklch(0.78 0.12 227.392);
|
|
597
|
+
--chart-4: oklch(0.80 0.18 84.429);
|
|
598
|
+
--chart-5: oklch(0.75 0.18 70.08);
|
|
599
|
+
|
|
600
|
+
/* Chips — AA-compliant on dark bg (L raised) */
|
|
601
|
+
--chip-1: oklch(0.72 0.18 264);
|
|
602
|
+
--chip-2: oklch(0.72 0.14 184);
|
|
603
|
+
--chip-3: oklch(0.78 0.12 227);
|
|
604
|
+
--chip-4: oklch(0.78 0.14 84);
|
|
605
|
+
--chip-5: oklch(0.78 0.16 70);
|
|
606
|
+
--chip-destructive: oklch(0.72 0.18 25);
|
|
607
|
+
|
|
608
|
+
/* Tinted icon discs — same soft transparency wash; fg stays readable on dark canvas */
|
|
609
|
+
--icon-disc-chart-2-bg: color-mix(in oklch, var(--chart-2) 14%, transparent);
|
|
610
|
+
--icon-disc-chart-2-fg: color-mix(in oklch, var(--foreground) 10%, var(--chart-2));
|
|
611
|
+
--icon-disc-chart-4-bg: color-mix(in oklch, var(--chart-4) 14%, transparent);
|
|
612
|
+
--icon-disc-chart-4-fg: color-mix(in oklch, var(--foreground) 10%, var(--chart-4));
|
|
613
|
+
--icon-disc-brand-bg: color-mix(in oklch, var(--brand-color) 12%, transparent);
|
|
614
|
+
--icon-disc-brand-fg: color-mix(in oklch, var(--foreground) 8%, var(--brand-color));
|
|
615
|
+
--icon-disc-danger-bg: color-mix(in oklch, var(--destructive) 14%, transparent);
|
|
616
|
+
--icon-disc-danger-fg: color-mix(in oklch, var(--foreground) 8%, var(--destructive));
|
|
617
|
+
|
|
618
|
+
/* Sidebar — same chroma-bump principle as `--brand-tint`: at L≈0.245 the
|
|
619
|
+
OKLCH hue-perception threshold is ~0.04, so 0.015 read as dead grey
|
|
620
|
+
regardless of brand. 0.04 reads as the brand without competing with the
|
|
621
|
+
content panel. `.theme-*.dark` blocks restate this scale at their hue. */
|
|
622
|
+
--sidebar: oklch(0.245 0.04 270);
|
|
623
|
+
--sidebar-foreground: oklch(0.985 0 0);
|
|
624
|
+
--sidebar-primary: oklch(0.488 0.243 264.376);
|
|
625
|
+
--sidebar-primary-foreground: oklch(0.985 0 0);
|
|
626
|
+
--sidebar-accent: oklch(0.30 0.035 270);
|
|
627
|
+
--sidebar-accent-foreground: oklch(0.985 0 0);
|
|
628
|
+
--sidebar-border: oklch(0.38 0.025 270);
|
|
629
|
+
--sidebar-ring: oklch(0.85 0 0);
|
|
630
|
+
--sidebar-section-label-foreground: color-mix(in oklch, var(--sidebar-foreground) 48%, var(--sidebar));
|
|
631
|
+
/* Nested secondary rail — nested chrome wedged between the outer sidebar
|
|
632
|
+
(L=0.245) and the page canvas (L=0.20). Previously this resolved to
|
|
633
|
+
`var(--brand-tint)` at L=0.30, which made the panel *brighter* than the
|
|
634
|
+
sidebar — it popped out instead of nestling in. Now L=0.22 places it just
|
|
635
|
+
above canvas with a whisper of brand chroma; each themed dark block below
|
|
636
|
+
overrides with the brand hue so it still reads as Exxat One vs Prism vs
|
|
637
|
+
Assessment vs custom. */
|
|
638
|
+
--secondary-panel-bg: oklch(0.22 0.020 270);
|
|
639
|
+
--theme-color-chrome: #2f2d36;
|
|
640
|
+
|
|
641
|
+
/* Lifted scrim on dark — white-tinted veil, not heavy black */
|
|
642
|
+
--overlay: color-mix(in oklch, var(--foreground) 10%, transparent);
|
|
643
|
+
|
|
644
|
+
/* Mid lavender chip + light text — no black circle; contrasts on dark table rows */
|
|
645
|
+
--avatar-initials-bg: color-mix(in oklch, var(--brand-color) 38%, oklch(0.40 0.05 286.1));
|
|
646
|
+
--avatar-initials-fg: oklch(0.99 0.01 286.1);
|
|
647
|
+
|
|
648
|
+
/* DataTable — opaque surfaces for dark mode */
|
|
649
|
+
--dt-row-bg: var(--background);
|
|
650
|
+
--dt-row-hover: oklch(0.24 0.01 270);
|
|
651
|
+
--dt-row-selected: oklch(0.27 0.02 270);
|
|
652
|
+
--dt-row-selected-fg: var(--foreground);
|
|
653
|
+
--dt-header-bg: var(--background);
|
|
654
|
+
--dt-group-bg: oklch(0.24 0.01 270);
|
|
655
|
+
--dt-new-row-bg: oklch(from var(--brand-color) 0.22 0.02 h);
|
|
656
|
+
--dt-new-row-border: var(--brand-color);
|
|
657
|
+
}
|
|
658
|
+
|
|
659
|
+
/* ==========================================================================
|
|
660
|
+
Theme: Exxat One · Lavender (explicit — also applied as :root default)
|
|
661
|
+
Usage: <html class="theme-one"> or <html class="theme-lavender">
|
|
662
|
+
========================================================================== */
|
|
663
|
+
.theme-one,
|
|
664
|
+
.theme-lavender {
|
|
665
|
+
--brand-tint: oklch(0.9676 0.016 286.1);
|
|
666
|
+
--brand-tint-light: oklch(0.993 0.007 286.1);
|
|
667
|
+
--brand-tint-subtle: oklch(0.935 0.024 286.1);
|
|
668
|
+
--brand-color: oklch(0.50 0.14 286.1);
|
|
669
|
+
--brand-color-light: oklch(0.78 0.09 286.1);
|
|
670
|
+
--brand-color-dark: oklch(0.38 0.11 286.1);
|
|
671
|
+
--brand-color-deep: oklch(0.28 0.085 286.1);
|
|
672
|
+
--ring: var(--brand-color-dark);
|
|
673
|
+
}
|
|
674
|
+
|
|
675
|
+
/* Light surfaces only — must NOT override .dark (otherwise muted/accent stay “paper white” in dark mode) */
|
|
676
|
+
.theme-one:not(.dark),
|
|
677
|
+
.theme-lavender:not(.dark) {
|
|
678
|
+
--sidebar: var(--brand-tint);
|
|
679
|
+
--sidebar-accent: oklch(0.945 0.025 286.1);
|
|
680
|
+
--sidebar-border: oklch(0.92 0.025 286.1);
|
|
681
|
+
--secondary: oklch(0.95 0.012 286.1);
|
|
682
|
+
--accent: oklch(0.925 0.015 286.1);
|
|
683
|
+
--muted: oklch(0.945 0.008 286.1);
|
|
684
|
+
}
|
|
685
|
+
|
|
686
|
+
.theme-one.dark,
|
|
687
|
+
.dark.theme-one,
|
|
688
|
+
.theme-lavender.dark,
|
|
689
|
+
.dark.theme-lavender {
|
|
690
|
+
--ring: var(--brand-color);
|
|
691
|
+
--background: oklch(0.20 0.014 286.1);
|
|
692
|
+
--sidebar: oklch(0.245 0.04 286.1);
|
|
693
|
+
--sidebar-accent: oklch(0.30 0.035 286.1);
|
|
694
|
+
--sidebar-border: oklch(0.38 0.025 286.1);
|
|
695
|
+
/* Restore dark surfaces (base .dark is overridden by :not(.dark) rules above when both classes apply) */
|
|
696
|
+
--secondary: oklch(0.31 0.04 286.1);
|
|
697
|
+
--muted: oklch(0.31 0.04 286.1);
|
|
698
|
+
--accent: oklch(0.33 0.06 286.1);
|
|
699
|
+
/* Surface elevation ladder — dark mode.
|
|
700
|
+
Card / input-background are *inline* elevations (same surface family as
|
|
701
|
+
canvas, small step). Popover is a *floating* surface — lifts further so a
|
|
702
|
+
dropdown over canvas reads as clearly above it instead of blending in.
|
|
703
|
+
Secondary panel is nested chrome — wedged between canvas (L=0.20) and
|
|
704
|
+
sidebar (L=0.245), so it nestles into the shell rather than popping out.
|
|
705
|
+
Brand chroma stays gentle on all three; the saturated brand expression
|
|
706
|
+
lives on --brand-tint / --sidebar. */
|
|
707
|
+
--secondary-panel-bg: oklch(0.22 0.025 286.1);
|
|
708
|
+
--card: oklch(0.225 0.017 286.1);
|
|
709
|
+
--popover: oklch(0.275 0.022 286.1);
|
|
710
|
+
--input-background: oklch(0.245 0.010 286.1);
|
|
711
|
+
/* Brand-tint scale — same hue (286.1 — Exxat One lavender), dark lightness.
|
|
712
|
+
PRIMARY (`--brand-tint`) carries enough chroma to read as visibly lavender
|
|
713
|
+
against the page canvas; LIGHT / SUBTLE steps are elevation aides only. */
|
|
714
|
+
--brand-tint: oklch(0.30 0.05 286.1);
|
|
715
|
+
--brand-tint-light: oklch(0.34 0.04 286.1);
|
|
716
|
+
--brand-tint-subtle: oklch(0.26 0.025 286.1);
|
|
717
|
+
}
|
|
718
|
+
|
|
719
|
+
/* ==========================================================================
|
|
720
|
+
Theme: Exxat Prism · Rose · hue 343
|
|
721
|
+
Usage: <html class="theme-prism"> or <html class="theme-rose">
|
|
722
|
+
========================================================================== */
|
|
723
|
+
.theme-prism,
|
|
724
|
+
.theme-rose {
|
|
725
|
+
--brand-tint: oklch(0.97 0.02 343);
|
|
726
|
+
--brand-tint-light: oklch(0.992 0.01 343);
|
|
727
|
+
--brand-tint-subtle: oklch(0.93 0.028 343);
|
|
728
|
+
--brand-color: oklch(0.57 0.24 342); /* Prism rose */
|
|
729
|
+
--brand-color-light: oklch(0.78 0.14 342);
|
|
730
|
+
--brand-color-dark: oklch(0.42 0.24 342);
|
|
731
|
+
--brand-color-deep: oklch(0.32 0.20 342);
|
|
732
|
+
--ring: var(--brand-color-dark);
|
|
733
|
+
}
|
|
734
|
+
|
|
735
|
+
.theme-prism:not(.dark),
|
|
736
|
+
.theme-rose:not(.dark) {
|
|
737
|
+
--sidebar: oklch(0.97 0.02 343);
|
|
738
|
+
--sidebar-accent: oklch(0.945 0.025 343);
|
|
739
|
+
--sidebar-border: oklch(0.92 0.025 343);
|
|
740
|
+
--secondary: oklch(0.95 0.012 343);
|
|
741
|
+
--accent: oklch(0.925 0.015 343);
|
|
742
|
+
--muted: oklch(0.945 0.008 343);
|
|
743
|
+
--banner-prism-bg: oklch(0.97 0.02 343);
|
|
744
|
+
--theme-color-chrome: #fff5f9;
|
|
745
|
+
}
|
|
746
|
+
|
|
747
|
+
.theme-prism.dark,
|
|
748
|
+
.dark.theme-prism,
|
|
749
|
+
.theme-rose.dark,
|
|
750
|
+
.dark.theme-rose {
|
|
751
|
+
--ring: var(--brand-color);
|
|
752
|
+
--background: oklch(0.20 0.014 342);
|
|
753
|
+
--sidebar: oklch(0.245 0.045 342);
|
|
754
|
+
--sidebar-accent: oklch(0.30 0.04 342);
|
|
755
|
+
--sidebar-border: oklch(0.38 0.028 342);
|
|
756
|
+
--secondary: oklch(0.31 0.04 342);
|
|
757
|
+
--muted: oklch(0.31 0.04 342);
|
|
758
|
+
--accent: oklch(0.33 0.06 342);
|
|
759
|
+
--theme-color-chrome: #2a2428;
|
|
760
|
+
/* Surface elevation ladder — see commentary in .theme-one.dark. Chroma is a
|
|
761
|
+
touch higher than lavender at every step because rose reads slightly
|
|
762
|
+
dimmer at equal chroma at these lightnesses. */
|
|
763
|
+
--secondary-panel-bg: oklch(0.22 0.030 342);
|
|
764
|
+
--card: oklch(0.225 0.020 342);
|
|
765
|
+
--popover: oklch(0.275 0.026 342);
|
|
766
|
+
--input-background: oklch(0.245 0.011 342);
|
|
767
|
+
/* Brand-tint scale — same hue (342 — Prism rose), dark lightness. Rose can
|
|
768
|
+
carry slightly higher chroma without warming-shift on dark surfaces. */
|
|
769
|
+
--brand-tint: oklch(0.30 0.055 342);
|
|
770
|
+
--brand-tint-light: oklch(0.34 0.045 342);
|
|
771
|
+
--brand-tint-subtle: oklch(0.26 0.028 342);
|
|
772
|
+
}
|
|
773
|
+
|
|
774
|
+
/* ==========================================================================
|
|
775
|
+
Theme: Exxat Assessment · Green · hue 159.88
|
|
776
|
+
Usage: <html class="theme-assessment">
|
|
777
|
+
========================================================================== */
|
|
778
|
+
.theme-assessment {
|
|
779
|
+
--brand-tint: oklch(0.965 0.018 159.88);
|
|
780
|
+
--brand-tint-light: oklch(0.992 0.008 159.88);
|
|
781
|
+
--brand-tint-subtle: oklch(0.93 0.028 159.88);
|
|
782
|
+
--brand-color: oklch(0.7 0.0913 159.88);
|
|
783
|
+
--brand-color-light: oklch(0.82 0.072 159.88);
|
|
784
|
+
--brand-color-dark: oklch(0.48 0.0913 159.88);
|
|
785
|
+
--brand-color-deep: oklch(0.34 0.075 159.88);
|
|
786
|
+
--ring: var(--brand-color-dark);
|
|
787
|
+
}
|
|
788
|
+
|
|
789
|
+
.theme-assessment:not(.dark) {
|
|
790
|
+
--sidebar: var(--brand-tint);
|
|
791
|
+
--sidebar-accent: oklch(0.945 0.026 159.88);
|
|
792
|
+
--sidebar-border: oklch(0.90 0.026 159.88);
|
|
793
|
+
--secondary: oklch(0.95 0.012 159.88);
|
|
794
|
+
--accent: oklch(0.925 0.016 159.88);
|
|
795
|
+
--muted: oklch(0.945 0.008 159.88);
|
|
796
|
+
--theme-color-chrome: #f1faf5;
|
|
797
|
+
}
|
|
798
|
+
|
|
799
|
+
.theme-assessment.dark,
|
|
800
|
+
.dark.theme-assessment {
|
|
801
|
+
--ring: var(--brand-color);
|
|
802
|
+
--background: oklch(0.20 0.014 159.88);
|
|
803
|
+
--sidebar: oklch(0.245 0.04 159.88);
|
|
804
|
+
--sidebar-accent: oklch(0.30 0.035 159.88);
|
|
805
|
+
--sidebar-border: oklch(0.38 0.025 159.88);
|
|
806
|
+
--secondary: oklch(0.31 0.04 159.88);
|
|
807
|
+
--muted: oklch(0.31 0.04 159.88);
|
|
808
|
+
--accent: oklch(0.33 0.06 159.88);
|
|
809
|
+
--theme-color-chrome: #242a27;
|
|
810
|
+
/* Surface elevation ladder — see commentary in .theme-one.dark. */
|
|
811
|
+
--secondary-panel-bg: oklch(0.22 0.025 159.88);
|
|
812
|
+
--card: oklch(0.225 0.017 159.88);
|
|
813
|
+
--popover: oklch(0.275 0.022 159.88);
|
|
814
|
+
--input-background: oklch(0.245 0.010 159.88);
|
|
815
|
+
/* Brand-tint scale — same hue (159.88 — Assessment teal-green), dark
|
|
816
|
+
lightness. Green at this lightness reads cleanly against the dark canvas. */
|
|
817
|
+
--brand-tint: oklch(0.30 0.05 159.88);
|
|
818
|
+
--brand-tint-light: oklch(0.34 0.04 159.88);
|
|
819
|
+
--brand-tint-subtle: oklch(0.26 0.025 159.88);
|
|
820
|
+
}
|
|
821
|
+
|
|
822
|
+
/* ==========================================================================
|
|
823
|
+
Theme: Custom product · user-selected hue
|
|
824
|
+
Usage: <html class="theme-custom" style="--custom-product-brand-color: …">
|
|
825
|
+
========================================================================== */
|
|
826
|
+
/*
|
|
827
|
+
* Tint chroma is **derived from the source's chroma** so neighbouring hues
|
|
828
|
+
* (e.g. Blue h=252 vs Indigo h=280 vs Purple h=286) read as distinct pale
|
|
829
|
+
* tints instead of collapsing to the same near-white. The earlier formula
|
|
830
|
+
* pinned chroma to a fixed `0.018`, which is below the hue-discrimination
|
|
831
|
+
* threshold at L≈0.96 for closely-spaced hues — that's why Blue / Indigo /
|
|
832
|
+
* Purple looked identical in the sidebar.
|
|
833
|
+
*
|
|
834
|
+
* `max(<floor>, calc(c * <fraction>))` rules:
|
|
835
|
+
* - vibrant brand colours (c ≈ 0.10–0.23) get a meaningfully tinted
|
|
836
|
+
* sidebar / accent / muted scale → product chrome visibly changes per
|
|
837
|
+
* pick
|
|
838
|
+
* - low-chroma custom-hex picks (greys) fall back to the floor so they
|
|
839
|
+
* don't render as pure white
|
|
840
|
+
* - lightness + hue stay pinned to the original mock-up values, so the
|
|
841
|
+
* overall "very pale background" feel is unchanged
|
|
842
|
+
*/
|
|
843
|
+
.theme-custom {
|
|
844
|
+
--brand-tint: oklch(from var(--custom-product-brand-color) 0.965 max(0.018, calc(c * 0.20)) h);
|
|
845
|
+
--brand-tint-light: oklch(from var(--custom-product-brand-color) 0.992 max(0.008, calc(c * 0.08)) h);
|
|
846
|
+
--brand-tint-subtle: oklch(from var(--custom-product-brand-color) 0.93 max(0.028, calc(c * 0.30)) h);
|
|
847
|
+
--brand-color: var(--custom-product-brand-color);
|
|
848
|
+
--brand-color-light: oklch(from var(--custom-product-brand-color) 0.82 c h);
|
|
849
|
+
--brand-color-dark: oklch(from var(--custom-product-brand-color) 0.48 c h);
|
|
850
|
+
--brand-color-deep: oklch(from var(--custom-product-brand-color) 0.34 c h);
|
|
851
|
+
--ring: var(--brand-color-dark);
|
|
852
|
+
}
|
|
853
|
+
|
|
854
|
+
.theme-custom:not(.dark) {
|
|
855
|
+
--sidebar: var(--brand-tint);
|
|
856
|
+
--sidebar-accent: oklch(from var(--custom-product-brand-color) 0.945 max(0.026, calc(c * 0.28)) h);
|
|
857
|
+
--sidebar-border: oklch(from var(--custom-product-brand-color) 0.90 max(0.026, calc(c * 0.28)) h);
|
|
858
|
+
--secondary: oklch(from var(--custom-product-brand-color) 0.95 max(0.012, calc(c * 0.14)) h);
|
|
859
|
+
--accent: oklch(from var(--custom-product-brand-color) 0.925 max(0.016, calc(c * 0.18)) h);
|
|
860
|
+
--muted: oklch(from var(--custom-product-brand-color) 0.945 max(0.008, calc(c * 0.10)) h);
|
|
861
|
+
--theme-color-chrome: color-mix(in oklch, var(--custom-product-brand-color) 10%, white);
|
|
862
|
+
}
|
|
863
|
+
|
|
864
|
+
.theme-custom.dark,
|
|
865
|
+
.dark.theme-custom {
|
|
866
|
+
--ring: var(--brand-color);
|
|
867
|
+
--background: oklch(from var(--custom-product-brand-color) 0.20 max(0.014, calc(c * 0.12)) h);
|
|
868
|
+
--sidebar: oklch(from var(--custom-product-brand-color) 0.245 max(0.035, calc(c * 0.28)) h);
|
|
869
|
+
--sidebar-accent: oklch(from var(--custom-product-brand-color) 0.30 max(0.030, calc(c * 0.24)) h);
|
|
870
|
+
--sidebar-border: oklch(from var(--custom-product-brand-color) 0.38 max(0.022, calc(c * 0.18)) h);
|
|
871
|
+
--secondary: oklch(from var(--custom-product-brand-color) 0.31 max(0.04, calc(c * 0.40)) h);
|
|
872
|
+
--muted: oklch(from var(--custom-product-brand-color) 0.31 max(0.04, calc(c * 0.40)) h);
|
|
873
|
+
--accent: oklch(from var(--custom-product-brand-color) 0.33 max(0.06, calc(c * 0.50)) h);
|
|
874
|
+
--theme-color-chrome: color-mix(in oklch, var(--custom-product-brand-color) 12%, black);
|
|
875
|
+
/* Surface elevation ladder — derived from the custom picked hue. See
|
|
876
|
+
commentary in .theme-one.dark for the full ladder. Chroma scales with
|
|
877
|
+
the source colour (~13% for inline cards / 16% for floating popovers /
|
|
878
|
+
20% for secondary panel) with floors that keep near-grey picks from
|
|
879
|
+
collapsing back to neutral. */
|
|
880
|
+
--secondary-panel-bg: oklch(from var(--custom-product-brand-color) 0.22 max(0.020, calc(c * 0.20)) h);
|
|
881
|
+
--card: oklch(from var(--custom-product-brand-color) 0.225 max(0.015, calc(c * 0.13)) h);
|
|
882
|
+
--popover: oklch(from var(--custom-product-brand-color) 0.275 max(0.018, calc(c * 0.16)) h);
|
|
883
|
+
--input-background: oklch(from var(--custom-product-brand-color) 0.245 max(0.008, calc(c * 0.08)) h);
|
|
884
|
+
/* Brand-tint scale — derived from the picked hue, dark lightness. PRIMARY
|
|
885
|
+
carries chroma high enough for the secondary panel to read as the brand
|
|
886
|
+
hue; floor 0.04 prevents low-chroma picks (greys) from collapsing back to
|
|
887
|
+
a flat surface. */
|
|
888
|
+
--brand-tint: oklch(from var(--custom-product-brand-color) 0.30 max(0.04, calc(c * 0.30)) h);
|
|
889
|
+
--brand-tint-light: oklch(from var(--custom-product-brand-color) 0.34 max(0.03, calc(c * 0.24)) h);
|
|
890
|
+
--brand-tint-subtle: oklch(from var(--custom-product-brand-color) 0.26 max(0.022, calc(c * 0.20)) h);
|
|
891
|
+
}
|
|
892
|
+
|
|
893
|
+
/* ==========================================================================
|
|
894
|
+
HIGH CONTRAST MODE
|
|
895
|
+
──────────────────────────────────────────────────────────────────────────
|
|
896
|
+
Three guiding principles (WCAG 1.4.6 Enhanced + research-backed UX):
|
|
897
|
+
|
|
898
|
+
1. FORCED-COLORS APPROACH
|
|
899
|
+
Strip gradients, shadows, and background images.
|
|
900
|
+
Use borders to define shape and elevation — not fills.
|
|
901
|
+
Limited palette: 4–6 named tokens, nothing decorative.
|
|
902
|
+
|
|
903
|
+
2. DON'T RELY ON COLOR ALONE
|
|
904
|
+
Error/warning states get a thick border AND an icon differentiator.
|
|
905
|
+
Charts and badges use luminance separation (grayscale steps), not hue.
|
|
906
|
+
Interactive state (hover / focus / active) is communicated via outline,
|
|
907
|
+
not background-color change alone.
|
|
908
|
+
|
|
909
|
+
3. DARK MODE ≠ HIGH CONTRAST
|
|
910
|
+
Dark mode = aesthetic; uses subtle greys.
|
|
911
|
+
High-contrast dark = functional; uses near-black grey canvas, pure white
|
|
912
|
+
(#FFF), and a "hot" neon-yellow focus accent for maximum visibility.
|
|
913
|
+
========================================================================== */
|
|
914
|
+
|
|
915
|
+
/* ── Light High Contrast ─────────────────────────────────────────────────── */
|
|
916
|
+
/* Fluent 2 / Microsoft 6-color strategy. */
|
|
917
|
+
/* Highlight = saturated bright brand color (follows theme hue). */
|
|
918
|
+
html[data-contrast="high"]:not(.dark) {
|
|
919
|
+
--hc-highlight: oklch(from var(--brand-color) 0.35 0.30 h);
|
|
920
|
+
--hc-highlight-text: oklch(1 0 0);
|
|
921
|
+
|
|
922
|
+
--background: oklch(1 0 0);
|
|
923
|
+
--foreground: oklch(0.14 0 0);
|
|
924
|
+
--card: oklch(1 0 0);
|
|
925
|
+
--card-foreground: oklch(0.14 0 0);
|
|
926
|
+
--popover: oklch(1 0 0);
|
|
927
|
+
--popover-foreground: oklch(0.14 0 0);
|
|
928
|
+
--primary: oklch(0.14 0 0);
|
|
929
|
+
--primary-foreground: oklch(1 0 0);
|
|
930
|
+
--secondary: oklch(1 0 0);
|
|
931
|
+
--secondary-foreground: oklch(0.14 0 0);
|
|
932
|
+
--muted: oklch(0.94 0 0);
|
|
933
|
+
--muted-foreground: oklch(0.14 0 0);
|
|
934
|
+
--accent: var(--hc-highlight);
|
|
935
|
+
--accent-foreground: var(--hc-highlight-text);
|
|
936
|
+
--destructive: oklch(0.45 0.24 25);
|
|
937
|
+
--destructive-foreground: oklch(1 0 0);
|
|
938
|
+
--border: oklch(0.14 0 0);
|
|
939
|
+
--border-control: oklch(0.14 0 0);
|
|
940
|
+
--border-control-3: oklch(0.14 0 0);
|
|
941
|
+
--border-control-35: oklch(0.14 0 0);
|
|
942
|
+
--control-border: oklch(0.14 0 0);
|
|
943
|
+
--input: oklch(0.14 0 0);
|
|
944
|
+
--input-background: oklch(1 0 0);
|
|
945
|
+
--ring: var(--hc-highlight);
|
|
946
|
+
--sidebar: oklch(1 0 0);
|
|
947
|
+
--sidebar-foreground: oklch(0.14 0 0);
|
|
948
|
+
--sidebar-primary: oklch(0.14 0 0);
|
|
949
|
+
--sidebar-primary-foreground: oklch(1 0 0);
|
|
950
|
+
--sidebar-accent: oklch(0.90 0 0);
|
|
951
|
+
--sidebar-accent-foreground: oklch(0.14 0 0);
|
|
952
|
+
--sidebar-border: oklch(0.14 0 0);
|
|
953
|
+
--sidebar-ring: var(--hc-highlight);
|
|
954
|
+
--sidebar-section-label-foreground: oklch(0.40 0 0);
|
|
955
|
+
--chart-1: oklch(0.14 0 0);
|
|
956
|
+
--chart-2: oklch(0.35 0 0);
|
|
957
|
+
--chart-3: oklch(0.55 0 0);
|
|
958
|
+
--chart-4: oklch(0.72 0 0);
|
|
959
|
+
--chart-5: oklch(0.86 0 0);
|
|
960
|
+
--chip-1: oklch(0.14 0 0);
|
|
961
|
+
--chip-2: oklch(0.14 0 0);
|
|
962
|
+
--chip-3: oklch(0.14 0 0);
|
|
963
|
+
--chip-4: oklch(0.14 0 0);
|
|
964
|
+
--chip-5: oklch(0.14 0 0);
|
|
965
|
+
--chip-destructive: oklch(0.45 0.24 25);
|
|
966
|
+
--interactive-hover: oklch(0.88 0 0);
|
|
967
|
+
--interactive-hover-foreground: oklch(0.14 0 0);
|
|
968
|
+
--interactive-hover-subtle: oklch(0.92 0 0);
|
|
969
|
+
--interactive-hover-soft: oklch(0.92 0 0);
|
|
970
|
+
--interactive-hover-medium: oklch(0.86 0 0);
|
|
971
|
+
--interactive-hover-strong: oklch(0.82 0 0);
|
|
972
|
+
--interactive-hover-row: oklch(0.88 0 0);
|
|
973
|
+
--overlay: color-mix(in oklch, var(--foreground) 18%, transparent);
|
|
974
|
+
--dt-row-bg: oklch(1 0 0);
|
|
975
|
+
--dt-row-hover: oklch(0.92 0 0);
|
|
976
|
+
--dt-row-selected: var(--accent);
|
|
977
|
+
--dt-row-selected-fg: var(--accent-foreground);
|
|
978
|
+
--dt-header-bg: oklch(1 0 0);
|
|
979
|
+
--dt-group-bg: oklch(0.92 0 0);
|
|
980
|
+
--dt-new-row-bg: oklch(1 0 0);
|
|
981
|
+
--dt-new-row-border: oklch(0.14 0 0);
|
|
982
|
+
}
|
|
983
|
+
|
|
984
|
+
/* ── Dark High Contrast ──────────────────────────────────────────────────── */
|
|
985
|
+
/* Same 6-color strategy inverted for dark canvas. */
|
|
986
|
+
/* Highlight = very bright saturated brand (like MS cyan but brand hue). */
|
|
987
|
+
html[data-contrast="high"].dark {
|
|
988
|
+
--hc-highlight: oklch(from var(--brand-color) 0.78 0.30 h);
|
|
989
|
+
--hc-highlight-text: oklch(0.08 0 0);
|
|
990
|
+
|
|
991
|
+
--background: oklch(0.14 0 0);
|
|
992
|
+
--foreground: oklch(0.96 0 0);
|
|
993
|
+
--card: oklch(0.14 0 0);
|
|
994
|
+
--card-foreground: oklch(0.96 0 0);
|
|
995
|
+
--popover: oklch(0.20 0 0);
|
|
996
|
+
--popover-foreground: oklch(0.96 0 0);
|
|
997
|
+
--primary: oklch(0.96 0 0);
|
|
998
|
+
--primary-foreground: oklch(0.10 0 0);
|
|
999
|
+
--secondary: oklch(0.14 0 0);
|
|
1000
|
+
--secondary-foreground: oklch(0.96 0 0);
|
|
1001
|
+
--muted: oklch(0.22 0 0);
|
|
1002
|
+
--muted-foreground: oklch(0.96 0 0);
|
|
1003
|
+
--accent: var(--hc-highlight);
|
|
1004
|
+
--accent-foreground: var(--hc-highlight-text);
|
|
1005
|
+
--destructive: oklch(0.72 0.18 18);
|
|
1006
|
+
--destructive-foreground: oklch(0.10 0 0);
|
|
1007
|
+
--border: oklch(0.75 0 0);
|
|
1008
|
+
--border-control: oklch(0.75 0 0);
|
|
1009
|
+
--border-control-3: oklch(0.75 0 0);
|
|
1010
|
+
--border-control-35: oklch(0.75 0 0);
|
|
1011
|
+
--control-border: oklch(0.75 0 0);
|
|
1012
|
+
--input: oklch(0.75 0 0);
|
|
1013
|
+
--input-background: oklch(0.14 0 0);
|
|
1014
|
+
--ring: var(--hc-highlight);
|
|
1015
|
+
--sidebar: oklch(0.14 0 0);
|
|
1016
|
+
--sidebar-foreground: oklch(0.96 0 0);
|
|
1017
|
+
--sidebar-primary: oklch(0.96 0 0);
|
|
1018
|
+
--sidebar-primary-foreground: oklch(0.10 0 0);
|
|
1019
|
+
--sidebar-accent: oklch(0.24 0 0);
|
|
1020
|
+
--sidebar-accent-foreground: oklch(0.96 0 0);
|
|
1021
|
+
--sidebar-border: oklch(0.75 0 0);
|
|
1022
|
+
--sidebar-ring: var(--hc-highlight);
|
|
1023
|
+
--sidebar-section-label-foreground: oklch(0.65 0 0);
|
|
1024
|
+
--chart-1: oklch(0.96 0 0);
|
|
1025
|
+
--chart-2: oklch(0.75 0 0);
|
|
1026
|
+
--chart-3: oklch(0.55 0 0);
|
|
1027
|
+
--chart-4: oklch(0.38 0 0);
|
|
1028
|
+
--chart-5: oklch(0.22 0 0);
|
|
1029
|
+
--chip-1: oklch(0.96 0 0);
|
|
1030
|
+
--chip-2: oklch(0.96 0 0);
|
|
1031
|
+
--chip-3: oklch(0.96 0 0);
|
|
1032
|
+
--chip-4: oklch(0.96 0 0);
|
|
1033
|
+
--chip-5: oklch(0.96 0 0);
|
|
1034
|
+
--chip-destructive: oklch(0.72 0.18 18);
|
|
1035
|
+
--interactive-hover: oklch(0.26 0 0);
|
|
1036
|
+
--interactive-hover-foreground: oklch(0.96 0 0);
|
|
1037
|
+
--interactive-hover-subtle: oklch(0.22 0 0);
|
|
1038
|
+
--interactive-hover-soft: oklch(0.22 0 0);
|
|
1039
|
+
--interactive-hover-medium: oklch(0.28 0 0);
|
|
1040
|
+
--interactive-hover-strong: oklch(0.32 0 0);
|
|
1041
|
+
--interactive-hover-row: oklch(0.26 0 0);
|
|
1042
|
+
--overlay: color-mix(in oklch, var(--foreground) 22%, transparent);
|
|
1043
|
+
--dt-row-bg: oklch(0.14 0 0);
|
|
1044
|
+
--dt-row-hover: oklch(0.22 0 0);
|
|
1045
|
+
--dt-row-selected: var(--accent);
|
|
1046
|
+
--dt-row-selected-fg: var(--accent-foreground);
|
|
1047
|
+
--dt-header-bg: oklch(0.14 0 0);
|
|
1048
|
+
--dt-group-bg: oklch(0.22 0 0);
|
|
1049
|
+
--dt-new-row-bg: oklch(0.14 0 0);
|
|
1050
|
+
--dt-new-row-border: oklch(0.96 0 0);
|
|
1051
|
+
}
|
|
1052
|
+
|
|
1053
|
+
/* Neutralize brand tint washes in HC so bg-brand-tint doesn't compete */
|
|
1054
|
+
html:is([data-contrast="high"], [data-contrast="windows"]):not(.dark) {
|
|
1055
|
+
--brand-tint: oklch(0.94 0 0);
|
|
1056
|
+
--brand-tint-light: oklch(0.97 0 0);
|
|
1057
|
+
--brand-tint-subtle: oklch(0.98 0 0);
|
|
1058
|
+
}
|
|
1059
|
+
html:is([data-contrast="high"], [data-contrast="windows"]).dark {
|
|
1060
|
+
--brand-tint: oklch(0.22 0 0);
|
|
1061
|
+
--brand-tint-light: oklch(0.18 0 0);
|
|
1062
|
+
--brand-tint-subtle: oklch(0.16 0 0);
|
|
1063
|
+
}
|
|
1064
|
+
|
|
1065
|
+
/* ── Structural rules shared by BOTH light and dark HC ──────────────────── */
|
|
1066
|
+
/* Pattern 1: "Borders over Fills" — strip decorative chrome */
|
|
1067
|
+
html:is([data-contrast="high"], [data-contrast="windows"]) {
|
|
1068
|
+
|
|
1069
|
+
/* 1a. Remove ALL box-shadows (elevation via outline, not shadow) */
|
|
1070
|
+
& * {
|
|
1071
|
+
box-shadow: none !important;
|
|
1072
|
+
text-shadow: none !important;
|
|
1073
|
+
}
|
|
1074
|
+
|
|
1075
|
+
/* 1b. Strip gradient fills from cards; use border to define shape */
|
|
1076
|
+
& [data-slot="card"] {
|
|
1077
|
+
background-image: none !important;
|
|
1078
|
+
border: 2px solid var(--foreground) !important;
|
|
1079
|
+
}
|
|
1080
|
+
|
|
1081
|
+
/* 1c. Thicker borders on all form controls (WCAG 1.4.11: 3:1 UI contrast) */
|
|
1082
|
+
& [data-slot="input"],
|
|
1083
|
+
& [data-slot="select-trigger"],
|
|
1084
|
+
& [data-slot="textarea"],
|
|
1085
|
+
& [data-slot="checkbox"],
|
|
1086
|
+
& [data-slot="switch"] {
|
|
1087
|
+
border-width: 2px !important;
|
|
1088
|
+
border-color: var(--foreground) !important;
|
|
1089
|
+
}
|
|
1090
|
+
|
|
1091
|
+
/* 1d. Sidebar defined by its edge border, not background colour */
|
|
1092
|
+
& [data-slot="sidebar"] {
|
|
1093
|
+
border-inline-end: 2px solid var(--sidebar-border) !important;
|
|
1094
|
+
}
|
|
1095
|
+
|
|
1096
|
+
/* 1e. Tab list — border not fill */
|
|
1097
|
+
& [data-slot="tabs-list"] {
|
|
1098
|
+
background-color: transparent !important;
|
|
1099
|
+
border: 2px solid var(--foreground) !important;
|
|
1100
|
+
}
|
|
1101
|
+
|
|
1102
|
+
/* 1f. Badge / chip — border-based; no decorative fills */
|
|
1103
|
+
& [data-slot="badge"] {
|
|
1104
|
+
border-width: 2px !important;
|
|
1105
|
+
border-color: var(--foreground) !important;
|
|
1106
|
+
background-color: var(--background) !important;
|
|
1107
|
+
font-weight: 700 !important;
|
|
1108
|
+
box-shadow: none !important;
|
|
1109
|
+
outline: none !important;
|
|
1110
|
+
color: var(--foreground) !important;
|
|
1111
|
+
}
|
|
1112
|
+
|
|
1113
|
+
& [data-slot="badge"] * {
|
|
1114
|
+
color: var(--foreground) !important;
|
|
1115
|
+
}
|
|
1116
|
+
|
|
1117
|
+
/* Status chip — same treatment as Badge (border-based, no decorative fill) */
|
|
1118
|
+
& [data-slot="status-badge"] {
|
|
1119
|
+
border-width: 2px !important;
|
|
1120
|
+
border-color: var(--foreground) !important;
|
|
1121
|
+
background-color: var(--background) !important;
|
|
1122
|
+
font-weight: 700 !important;
|
|
1123
|
+
box-shadow: none !important;
|
|
1124
|
+
outline: none !important;
|
|
1125
|
+
color: var(--foreground) !important;
|
|
1126
|
+
}
|
|
1127
|
+
|
|
1128
|
+
/* Sidebar wrapper is positioning-only when it wraps Badge/StatusBadge — avoid double border */
|
|
1129
|
+
& [data-slot="sidebar-menu-badge"]:has([data-slot="badge"]),
|
|
1130
|
+
& [data-slot="sidebar-menu-badge"]:has([data-slot="status-badge"]) {
|
|
1131
|
+
border-width: 0 !important;
|
|
1132
|
+
background-color: transparent !important;
|
|
1133
|
+
box-shadow: none !important;
|
|
1134
|
+
outline: none !important;
|
|
1135
|
+
}
|
|
1136
|
+
|
|
1137
|
+
& [data-slot="view-toolbar-count"] {
|
|
1138
|
+
border-width: 2px !important;
|
|
1139
|
+
border-color: currentColor !important;
|
|
1140
|
+
background-color: var(--background) !important;
|
|
1141
|
+
font-weight: 700 !important;
|
|
1142
|
+
color: var(--foreground) !important;
|
|
1143
|
+
box-shadow: none !important;
|
|
1144
|
+
outline: none !important;
|
|
1145
|
+
}
|
|
1146
|
+
|
|
1147
|
+
& [data-slot="sidebar-menu-badge"]:not(:has([data-slot="badge"])):not(:has([data-slot="status-badge"])) {
|
|
1148
|
+
border-width: 2px !important;
|
|
1149
|
+
border-color: currentColor !important;
|
|
1150
|
+
background-color: var(--background) !important;
|
|
1151
|
+
font-weight: 700 !important;
|
|
1152
|
+
color: var(--foreground) !important;
|
|
1153
|
+
}
|
|
1154
|
+
|
|
1155
|
+
/* Segmented tab buttons: global HC button border + count pill border = double ring */
|
|
1156
|
+
& button[data-slot="view-segmented-item"] {
|
|
1157
|
+
border-width: 0 !important;
|
|
1158
|
+
border-color: transparent !important;
|
|
1159
|
+
}
|
|
1160
|
+
|
|
1161
|
+
/* Radix Tabs — active state must not rely on muted fill / pseudo underline only */
|
|
1162
|
+
& [data-slot="tabs-trigger"] {
|
|
1163
|
+
color: var(--foreground) !important;
|
|
1164
|
+
opacity: 1 !important;
|
|
1165
|
+
}
|
|
1166
|
+
|
|
1167
|
+
& [data-slot="tabs-trigger"][data-state="active"] {
|
|
1168
|
+
background-color: var(--accent) !important;
|
|
1169
|
+
color: var(--accent-foreground) !important;
|
|
1170
|
+
outline: none !important;
|
|
1171
|
+
font-weight: 600 !important;
|
|
1172
|
+
}
|
|
1173
|
+
|
|
1174
|
+
/* KPI strip + chart card mini-metrics — force readable copy (muted grays fail in HC) */
|
|
1175
|
+
& [data-slot="key-metrics"] :where(span, p, button, a, i, label, div) {
|
|
1176
|
+
color: var(--foreground) !important;
|
|
1177
|
+
}
|
|
1178
|
+
|
|
1179
|
+
& [data-slot="key-metrics"] :where(svg) {
|
|
1180
|
+
color: var(--foreground) !important;
|
|
1181
|
+
}
|
|
1182
|
+
|
|
1183
|
+
/* List / menu rows — Highlight brand color for selection */
|
|
1184
|
+
& [data-slot="dropdown-menu-item"][data-highlighted],
|
|
1185
|
+
& [data-slot="dropdown-menu-checkbox-item"][data-highlighted],
|
|
1186
|
+
& [data-slot="dropdown-menu-radio-item"][data-highlighted],
|
|
1187
|
+
& [data-slot="dropdown-menu-sub-trigger"][data-highlighted],
|
|
1188
|
+
& [data-slot="select-item"][data-highlighted],
|
|
1189
|
+
& [data-slot="command-item"][data-selected],
|
|
1190
|
+
& [data-slot="command-item"][aria-selected="true"] {
|
|
1191
|
+
background-color: var(--accent) !important;
|
|
1192
|
+
color: var(--accent-foreground) !important;
|
|
1193
|
+
}
|
|
1194
|
+
|
|
1195
|
+
& [data-slot="dropdown-menu-item"][data-highlighted] *,
|
|
1196
|
+
& [data-slot="dropdown-menu-checkbox-item"][data-highlighted] *,
|
|
1197
|
+
& [data-slot="dropdown-menu-radio-item"][data-highlighted] *,
|
|
1198
|
+
& [data-slot="dropdown-menu-sub-trigger"][data-highlighted] *,
|
|
1199
|
+
& [data-slot="select-item"][data-highlighted] *,
|
|
1200
|
+
& [data-slot="command-item"][data-selected] *,
|
|
1201
|
+
& [data-slot="command-item"][aria-selected="true"] * {
|
|
1202
|
+
color: var(--accent-foreground) !important;
|
|
1203
|
+
}
|
|
1204
|
+
|
|
1205
|
+
/* List hub views toolbar + segmented radiogroup (not Radix Tabs / tabs-list) */
|
|
1206
|
+
& [data-slot="view-segmented-toolbar"] {
|
|
1207
|
+
background-color: transparent !important;
|
|
1208
|
+
border: 2px solid var(--foreground) !important;
|
|
1209
|
+
}
|
|
1210
|
+
|
|
1211
|
+
& [data-slot="view-segmented-item"][aria-pressed="true"],
|
|
1212
|
+
& [data-slot="view-segmented-item"][aria-checked="true"] {
|
|
1213
|
+
background-color: var(--accent) !important;
|
|
1214
|
+
color: var(--accent-foreground) !important;
|
|
1215
|
+
outline: none !important;
|
|
1216
|
+
}
|
|
1217
|
+
|
|
1218
|
+
/* Floating surfaces — portal menus, popovers, sheets, dialogs */
|
|
1219
|
+
& [data-slot="dropdown-menu-content"],
|
|
1220
|
+
& [data-slot="dropdown-menu-sub-content"],
|
|
1221
|
+
& [data-slot="popover-content"],
|
|
1222
|
+
& [data-slot="select-content"],
|
|
1223
|
+
& [data-slot="dialog-content"],
|
|
1224
|
+
& [data-slot="sheet-content"],
|
|
1225
|
+
& [data-slot="drawer-content"] {
|
|
1226
|
+
border: 2px solid var(--foreground) !important;
|
|
1227
|
+
background-color: var(--background) !important;
|
|
1228
|
+
color: var(--foreground) !important;
|
|
1229
|
+
}
|
|
1230
|
+
|
|
1231
|
+
& [data-slot="command"] {
|
|
1232
|
+
background-color: var(--background) !important;
|
|
1233
|
+
color: var(--foreground) !important;
|
|
1234
|
+
}
|
|
1235
|
+
|
|
1236
|
+
/* Strip conditional-formatting inline bg from table cells in HC */
|
|
1237
|
+
& td[style*="background"] {
|
|
1238
|
+
background: var(--dt-row-bg) !important;
|
|
1239
|
+
}
|
|
1240
|
+
& td.pinned-cell {
|
|
1241
|
+
background-color: var(--dt-row-bg) !important;
|
|
1242
|
+
}
|
|
1243
|
+
& tr:hover td.pinned-cell,
|
|
1244
|
+
& tr:hover td {
|
|
1245
|
+
background-color: var(--dt-row-hover) !important;
|
|
1246
|
+
}
|
|
1247
|
+
& tr[data-state="selected"] td.pinned-cell,
|
|
1248
|
+
& tr[data-state="selected"] td {
|
|
1249
|
+
background-color: var(--dt-row-selected) !important;
|
|
1250
|
+
color: var(--dt-row-selected-fg) !important;
|
|
1251
|
+
}
|
|
1252
|
+
|
|
1253
|
+
/* Table selected rows — Highlight brand color (like MS Teams selection) */
|
|
1254
|
+
& tr[data-state="selected"] {
|
|
1255
|
+
background-color: var(--dt-row-selected) !important;
|
|
1256
|
+
color: var(--dt-row-selected-fg) !important;
|
|
1257
|
+
}
|
|
1258
|
+
& tr[data-state="selected"] *:not([data-slot="checkbox"] *):not([data-slot="badge"] *):not([data-slot="checkbox"]):not([data-slot="badge"]) {
|
|
1259
|
+
color: var(--accent-foreground) !important;
|
|
1260
|
+
}
|
|
1261
|
+
& tr[data-state="selected"] [data-slot="badge"] {
|
|
1262
|
+
background-color: var(--accent-foreground) !important;
|
|
1263
|
+
color: var(--accent) !important;
|
|
1264
|
+
border-color: var(--accent-foreground) !important;
|
|
1265
|
+
}
|
|
1266
|
+
& tr[data-state="selected"] [data-slot="badge"] * {
|
|
1267
|
+
color: var(--accent) !important;
|
|
1268
|
+
}
|
|
1269
|
+
|
|
1270
|
+
& tr[data-state="selected"] [data-slot="checkbox"][data-state="checked"],
|
|
1271
|
+
& tr[data-state="selected"] [data-slot="checkbox"][data-state="indeterminate"] {
|
|
1272
|
+
background-color: var(--accent-foreground) !important;
|
|
1273
|
+
border-color: var(--accent-foreground) !important;
|
|
1274
|
+
color: var(--accent) !important;
|
|
1275
|
+
}
|
|
1276
|
+
& tr[data-state="selected"] [data-slot="checkbox"][data-state="checked"] *,
|
|
1277
|
+
& tr[data-state="selected"] [data-slot="checkbox"][data-state="indeterminate"] * {
|
|
1278
|
+
color: var(--accent) !important;
|
|
1279
|
+
}
|
|
1280
|
+
& tr[data-state="selected"] [data-slot="checkbox"]:not([data-state="checked"]):not([data-state="indeterminate"]) {
|
|
1281
|
+
background-color: var(--accent) !important;
|
|
1282
|
+
border-color: var(--accent-foreground) !important;
|
|
1283
|
+
color: var(--accent-foreground) !important;
|
|
1284
|
+
}
|
|
1285
|
+
|
|
1286
|
+
/* ── Pattern 2: Stronger focus ring (WCAG 2.4.11 / 2.4.12) ── */
|
|
1287
|
+
& :focus-visible {
|
|
1288
|
+
outline: 3px solid var(--ring) !important;
|
|
1289
|
+
outline-offset: 3px !important;
|
|
1290
|
+
}
|
|
1291
|
+
|
|
1292
|
+
/* ── Pattern 2: Error state — thick border + no colour-only signal ── */
|
|
1293
|
+
& [aria-invalid="true"],
|
|
1294
|
+
& [data-invalid] {
|
|
1295
|
+
border-width: 3px !important;
|
|
1296
|
+
border-color: var(--destructive) !important;
|
|
1297
|
+
/* Downstream: pair with a ⚠ icon in the component for non-colour signal */
|
|
1298
|
+
}
|
|
1299
|
+
|
|
1300
|
+
/* ── Pattern 3: Active nav — Highlight brand fill (like MS Teams) ── */
|
|
1301
|
+
& [data-slot="sidebar-menu-button"][data-active="true"] {
|
|
1302
|
+
background-color: var(--accent) !important;
|
|
1303
|
+
color: var(--accent-foreground) !important;
|
|
1304
|
+
outline: none !important;
|
|
1305
|
+
}
|
|
1306
|
+
& [data-slot="sidebar-menu-button"][data-active="true"] * {
|
|
1307
|
+
color: var(--accent-foreground) !important;
|
|
1308
|
+
}
|
|
1309
|
+
& [data-slot="sidebar-menu-button"][data-active="true"] [data-slot="badge"],
|
|
1310
|
+
& [data-slot="sidebar-menu-button"][data-active="true"] [data-slot="sidebar-menu-badge"] {
|
|
1311
|
+
background-color: var(--accent-foreground) !important;
|
|
1312
|
+
color: var(--accent) !important;
|
|
1313
|
+
border-color: var(--accent-foreground) !important;
|
|
1314
|
+
}
|
|
1315
|
+
& [data-slot="sidebar-menu-button"][data-active="true"] [data-slot="badge"] *,
|
|
1316
|
+
& [data-slot="sidebar-menu-button"][data-active="true"] [data-slot="sidebar-menu-badge"] * {
|
|
1317
|
+
color: var(--accent) !important;
|
|
1318
|
+
}
|
|
1319
|
+
& [data-slot="toggle-group-item"][data-state="on"] {
|
|
1320
|
+
outline: 2px solid var(--accent) !important;
|
|
1321
|
+
outline-offset: -2px !important;
|
|
1322
|
+
background-color: var(--accent) !important;
|
|
1323
|
+
color: var(--accent-foreground) !important;
|
|
1324
|
+
}
|
|
1325
|
+
|
|
1326
|
+
/* ── Pattern 3b: Checked checkboxes — Highlight brand fill ── */
|
|
1327
|
+
& [data-slot="checkbox"][data-state="checked"],
|
|
1328
|
+
& [data-slot="checkbox"][data-state="indeterminate"] {
|
|
1329
|
+
background-color: var(--accent) !important;
|
|
1330
|
+
border-color: var(--accent) !important;
|
|
1331
|
+
color: var(--accent-foreground) !important;
|
|
1332
|
+
}
|
|
1333
|
+
& [data-slot="checkbox"][data-state="checked"] *,
|
|
1334
|
+
& [data-slot="checkbox"][data-state="indeterminate"] * {
|
|
1335
|
+
color: var(--accent-foreground) !important;
|
|
1336
|
+
}
|
|
1337
|
+
|
|
1338
|
+
/* ── Pattern 3c: Checked radio buttons — Highlight brand fill ── */
|
|
1339
|
+
& [data-slot="radio-group-item"][data-state="checked"] {
|
|
1340
|
+
background-color: var(--accent) !important;
|
|
1341
|
+
border-color: var(--accent) !important;
|
|
1342
|
+
color: var(--accent-foreground) !important;
|
|
1343
|
+
}
|
|
1344
|
+
& [data-slot="radio-group-item"][data-state="checked"] [data-slot="radio-group-indicator"] span {
|
|
1345
|
+
background-color: var(--accent-foreground) !important;
|
|
1346
|
+
}
|
|
1347
|
+
|
|
1348
|
+
/* ── Pattern 3d: Toggle on state — Highlight brand fill ── */
|
|
1349
|
+
& [data-slot="toggle"][data-state="on"] {
|
|
1350
|
+
background-color: var(--accent) !important;
|
|
1351
|
+
color: var(--accent-foreground) !important;
|
|
1352
|
+
border: 2px solid var(--accent) !important;
|
|
1353
|
+
}
|
|
1354
|
+
|
|
1355
|
+
/* ── Pattern 3e: Switch (toggle-switch) — visible track + knob ── */
|
|
1356
|
+
& [role="switch"] {
|
|
1357
|
+
border: 2px solid var(--foreground) !important;
|
|
1358
|
+
background-color: var(--background) !important;
|
|
1359
|
+
}
|
|
1360
|
+
& [role="switch"][aria-checked="true"] {
|
|
1361
|
+
background-color: var(--accent) !important;
|
|
1362
|
+
border-color: var(--accent) !important;
|
|
1363
|
+
}
|
|
1364
|
+
& [role="switch"] > span {
|
|
1365
|
+
background-color: var(--foreground) !important;
|
|
1366
|
+
}
|
|
1367
|
+
& [role="switch"][aria-checked="true"] > span {
|
|
1368
|
+
background-color: var(--accent-foreground) !important;
|
|
1369
|
+
}
|
|
1370
|
+
|
|
1371
|
+
/* ── Pattern 3f: Select / dropdown item focus — Highlight brand fill ── */
|
|
1372
|
+
& [data-slot="select-item"]:focus,
|
|
1373
|
+
& [data-slot="dropdown-menu-item"]:focus,
|
|
1374
|
+
& [data-slot="dropdown-menu-checkbox-item"]:focus,
|
|
1375
|
+
& [data-slot="dropdown-menu-radio-item"]:focus,
|
|
1376
|
+
& [data-slot="dropdown-menu-sub-trigger"]:focus {
|
|
1377
|
+
background-color: var(--accent) !important;
|
|
1378
|
+
color: var(--accent-foreground) !important;
|
|
1379
|
+
}
|
|
1380
|
+
& [data-slot="select-item"]:focus *,
|
|
1381
|
+
& [data-slot="dropdown-menu-item"]:focus *,
|
|
1382
|
+
& [data-slot="dropdown-menu-checkbox-item"]:focus *,
|
|
1383
|
+
& [data-slot="dropdown-menu-radio-item"]:focus *,
|
|
1384
|
+
& [data-slot="dropdown-menu-sub-trigger"]:focus * {
|
|
1385
|
+
color: var(--accent-foreground) !important;
|
|
1386
|
+
}
|
|
1387
|
+
|
|
1388
|
+
/* ── Pattern 3g: Dropdown check / radio indicator — inherit from parent ── */
|
|
1389
|
+
& [data-slot="dropdown-menu-checkbox-item"][data-state="checked"],
|
|
1390
|
+
& [data-slot="dropdown-menu-radio-item"][data-state="checked"] {
|
|
1391
|
+
font-weight: 700 !important;
|
|
1392
|
+
}
|
|
1393
|
+
|
|
1394
|
+
/* ── Pattern 4: Board cards — border-defined, no decorative fills ── */
|
|
1395
|
+
& [data-slot="board-card"] {
|
|
1396
|
+
border: 2px solid var(--foreground) !important;
|
|
1397
|
+
background-image: none !important;
|
|
1398
|
+
}
|
|
1399
|
+
|
|
1400
|
+
/* ── Pattern 6: List hub status badges — border not fill ── */
|
|
1401
|
+
& [data-slot="list-hub-status-badge"] {
|
|
1402
|
+
border: 2px solid var(--foreground) !important;
|
|
1403
|
+
background-color: var(--background) !important;
|
|
1404
|
+
font-weight: 700 !important;
|
|
1405
|
+
color: var(--foreground) !important;
|
|
1406
|
+
}
|
|
1407
|
+
|
|
1408
|
+
/* ── Pattern 7: Insight cards — border-based, strip gradient bg ── */
|
|
1409
|
+
& [aria-label="Insight"],
|
|
1410
|
+
& [data-slot="insight-card"] {
|
|
1411
|
+
border: 2px solid var(--foreground) !important;
|
|
1412
|
+
background-image: none !important;
|
|
1413
|
+
background: var(--background) !important;
|
|
1414
|
+
}
|
|
1415
|
+
|
|
1416
|
+
/* ── Pattern 8: Coach marks — strong border + readable text ── */
|
|
1417
|
+
& [data-slot="coach-mark"] {
|
|
1418
|
+
border: 2px solid var(--foreground) !important;
|
|
1419
|
+
background: var(--background) !important;
|
|
1420
|
+
background-color: var(--background) !important;
|
|
1421
|
+
color: var(--foreground) !important;
|
|
1422
|
+
background-image: none !important;
|
|
1423
|
+
opacity: 1 !important;
|
|
1424
|
+
}
|
|
1425
|
+
& [data-slot="coach-mark"] *:not(button):not(button *) {
|
|
1426
|
+
color: var(--foreground) !important;
|
|
1427
|
+
}
|
|
1428
|
+
|
|
1429
|
+
/* ── Pattern 9: Avatars — thicken ring, strip blend modes, force contrast ── */
|
|
1430
|
+
& [data-slot="avatar"] {
|
|
1431
|
+
border: 2px solid var(--foreground) !important;
|
|
1432
|
+
}
|
|
1433
|
+
& [data-slot="avatar"]::after {
|
|
1434
|
+
display: none !important;
|
|
1435
|
+
}
|
|
1436
|
+
& [data-slot="avatar-fallback"] {
|
|
1437
|
+
background-color: var(--background) !important;
|
|
1438
|
+
color: var(--foreground) !important;
|
|
1439
|
+
}
|
|
1440
|
+
& tr[data-state="selected"] [data-slot="avatar"] {
|
|
1441
|
+
border-color: var(--accent-foreground) !important;
|
|
1442
|
+
}
|
|
1443
|
+
& tr[data-state="selected"] [data-slot="avatar-fallback"] {
|
|
1444
|
+
background-color: var(--accent-foreground) !important;
|
|
1445
|
+
color: var(--accent) !important;
|
|
1446
|
+
}
|
|
1447
|
+
|
|
1448
|
+
/* ── Pattern 10: Breadcrumbs — ensure separators are visible ── */
|
|
1449
|
+
& [data-slot="breadcrumb-separator"] {
|
|
1450
|
+
color: var(--foreground) !important;
|
|
1451
|
+
}
|
|
1452
|
+
& [data-slot="breadcrumb-link"] {
|
|
1453
|
+
color: var(--foreground) !important;
|
|
1454
|
+
text-decoration: underline !important;
|
|
1455
|
+
}
|
|
1456
|
+
& [data-slot="breadcrumb-page"] {
|
|
1457
|
+
color: var(--foreground) !important;
|
|
1458
|
+
font-weight: 700 !important;
|
|
1459
|
+
}
|
|
1460
|
+
|
|
1461
|
+
/* ── Pattern 11: Tooltip / popover arrow — match border ── */
|
|
1462
|
+
& [data-slot="tooltip-content"] {
|
|
1463
|
+
border: 2px solid var(--foreground) !important;
|
|
1464
|
+
background-color: var(--background) !important;
|
|
1465
|
+
color: var(--foreground) !important;
|
|
1466
|
+
}
|
|
1467
|
+
|
|
1468
|
+
/* ── Pattern 12: Separator — visible in HC ── */
|
|
1469
|
+
& [data-slot="separator"] {
|
|
1470
|
+
background-color: var(--foreground) !important;
|
|
1471
|
+
opacity: 1 !important;
|
|
1472
|
+
}
|
|
1473
|
+
|
|
1474
|
+
/* ── Pattern 13: Strip ALL hardcoded Tailwind palette colors ──────────── */
|
|
1475
|
+
& [data-slot="banner"],
|
|
1476
|
+
& [data-slot="local-banner"] {
|
|
1477
|
+
background-color: var(--background) !important;
|
|
1478
|
+
background-image: none !important;
|
|
1479
|
+
border: 2px solid var(--foreground) !important;
|
|
1480
|
+
color: var(--foreground) !important;
|
|
1481
|
+
}
|
|
1482
|
+
& [data-slot="banner"] *,
|
|
1483
|
+
& [data-slot="local-banner"] * {
|
|
1484
|
+
color: var(--foreground) !important;
|
|
1485
|
+
}
|
|
1486
|
+
|
|
1487
|
+
& .recharts-bar-rectangle,
|
|
1488
|
+
& .recharts-funnel-trapezoid {
|
|
1489
|
+
stroke: var(--background) !important;
|
|
1490
|
+
stroke-width: 2 !important;
|
|
1491
|
+
}
|
|
1492
|
+
|
|
1493
|
+
& [role="progressbar"] {
|
|
1494
|
+
border: 1px solid var(--foreground) !important;
|
|
1495
|
+
background-color: var(--background) !important;
|
|
1496
|
+
}
|
|
1497
|
+
& [role="progressbar"] > * {
|
|
1498
|
+
background-color: var(--foreground) !important;
|
|
1499
|
+
}
|
|
1500
|
+
|
|
1501
|
+
& [class*="text-emerald"],
|
|
1502
|
+
& [class*="text-amber"],
|
|
1503
|
+
& [class*="text-red-"],
|
|
1504
|
+
& [class*="text-blue-"],
|
|
1505
|
+
& [class*="text-green-"],
|
|
1506
|
+
& [class*="text-yellow-"],
|
|
1507
|
+
& [class*="text-slate-"],
|
|
1508
|
+
& [class*="text-orange-"],
|
|
1509
|
+
& [class*="text-pink-"],
|
|
1510
|
+
& [class*="text-purple-"] {
|
|
1511
|
+
color: var(--foreground) !important;
|
|
1512
|
+
}
|
|
1513
|
+
|
|
1514
|
+
& [class*="text-brand"] {
|
|
1515
|
+
color: var(--accent) !important;
|
|
1516
|
+
}
|
|
1517
|
+
& [class*="bg-brand"]:not([data-slot="coach-mark"]) {
|
|
1518
|
+
background-color: var(--background) !important;
|
|
1519
|
+
}
|
|
1520
|
+
& [class*="border-brand"] {
|
|
1521
|
+
border-color: var(--foreground) !important;
|
|
1522
|
+
}
|
|
1523
|
+
|
|
1524
|
+
& [class*="bg-emerald"],
|
|
1525
|
+
& [class*="bg-amber"],
|
|
1526
|
+
& [class*="bg-red-"],
|
|
1527
|
+
& [class*="bg-blue-"],
|
|
1528
|
+
& [class*="bg-green-"],
|
|
1529
|
+
& [class*="bg-yellow-"],
|
|
1530
|
+
& [class*="bg-slate-"],
|
|
1531
|
+
& [class*="bg-orange-"],
|
|
1532
|
+
& [class*="bg-pink-"],
|
|
1533
|
+
& [class*="bg-purple-"] {
|
|
1534
|
+
background-color: var(--background) !important;
|
|
1535
|
+
}
|
|
1536
|
+
|
|
1537
|
+
& [class*="border-emerald"],
|
|
1538
|
+
& [class*="border-amber"],
|
|
1539
|
+
& [class*="border-red-"],
|
|
1540
|
+
& [class*="border-blue-"],
|
|
1541
|
+
& [class*="border-green-"],
|
|
1542
|
+
& [class*="border-yellow-"],
|
|
1543
|
+
& [class*="border-slate-"],
|
|
1544
|
+
& [class*="border-orange-"],
|
|
1545
|
+
& [class*="border-pink-"],
|
|
1546
|
+
& [class*="border-purple-"] {
|
|
1547
|
+
border-color: var(--foreground) !important;
|
|
1548
|
+
}
|
|
1549
|
+
}
|
|
1550
|
+
|
|
1551
|
+
/* Coach mark HC override (top-level, outside nesting — bulletproof for portaled content) */
|
|
1552
|
+
html:is([data-contrast="high"], [data-contrast="windows"]) [data-slot="coach-mark"] {
|
|
1553
|
+
border: 2px solid var(--foreground) !important;
|
|
1554
|
+
background: var(--background) !important;
|
|
1555
|
+
background-color: var(--background) !important;
|
|
1556
|
+
color: var(--foreground) !important;
|
|
1557
|
+
background-image: none !important;
|
|
1558
|
+
opacity: 1 !important;
|
|
1559
|
+
}
|
|
1560
|
+
html:is([data-contrast="high"], [data-contrast="windows"]) [data-slot="coach-mark"] *:not(button):not(button *) {
|
|
1561
|
+
color: var(--foreground) !important;
|
|
1562
|
+
}
|
|
1563
|
+
|
|
1564
|
+
/* ── OS-level "Increase Contrast" — macOS / iOS / Android ───────────────── */
|
|
1565
|
+
@media (prefers-contrast: more) {
|
|
1566
|
+
:root:not([data-contrast="off"]):not([data-contrast="windows"]) {
|
|
1567
|
+
--foreground: oklch(0.06 0 0);
|
|
1568
|
+
--muted-foreground: oklch(0.10 0 0);
|
|
1569
|
+
--border: oklch(0.10 0 0);
|
|
1570
|
+
--border-control: oklch(0.06 0 0);
|
|
1571
|
+
--border-control-35: oklch(0.06 0 0);
|
|
1572
|
+
--border-control-3: oklch(0.06 0 0);
|
|
1573
|
+
--ring: oklch(0.06 0 0);
|
|
1574
|
+
}
|
|
1575
|
+
.dark:not([data-contrast="off"]):not([data-contrast="windows"]) {
|
|
1576
|
+
--foreground: oklch(1 0 0);
|
|
1577
|
+
--muted-foreground: oklch(0.88 0 0);
|
|
1578
|
+
--border: oklch(1 0 0);
|
|
1579
|
+
--border-control: oklch(0.88 0 0);
|
|
1580
|
+
--border-control-35: oklch(0.88 0 0);
|
|
1581
|
+
--border-control-3: oklch(0.88 0 0);
|
|
1582
|
+
--ring: oklch(0.97 0.19 110); /* neon yellow on dark */
|
|
1583
|
+
}
|
|
1584
|
+
}
|
|
1585
|
+
|
|
1586
|
+
/* ── Windows Forced Colors (High Contrast Mode in OS) ───────────────────── */
|
|
1587
|
+
/* When `forced-colors: active`, Windows REPLACES our colours entirely. */
|
|
1588
|
+
/* Our job: map semantic roles to system palette keywords so the OS */
|
|
1589
|
+
/* colouring makes sense, and ensure borders/outlines remain visible. */
|
|
1590
|
+
@media (forced-colors: active) {
|
|
1591
|
+
:root {
|
|
1592
|
+
--border: CanvasText;
|
|
1593
|
+
--border-control: CanvasText;
|
|
1594
|
+
--border-control-35: CanvasText;
|
|
1595
|
+
--border-control-3: CanvasText;
|
|
1596
|
+
--ring: Highlight;
|
|
1597
|
+
--destructive: LinkText;
|
|
1598
|
+
}
|
|
1599
|
+
|
|
1600
|
+
/* Always show a 2px outline so focus is forced-color-safe */
|
|
1601
|
+
:focus-visible {
|
|
1602
|
+
outline: 2px solid Highlight !important;
|
|
1603
|
+
outline-offset: 2px !important;
|
|
1604
|
+
}
|
|
1605
|
+
|
|
1606
|
+
body {
|
|
1607
|
+
background-color: Canvas;
|
|
1608
|
+
color: CanvasText;
|
|
1609
|
+
}
|
|
1610
|
+
|
|
1611
|
+
a { color: LinkText; }
|
|
1612
|
+
button { border: 1px solid ButtonText !important; }
|
|
1613
|
+
|
|
1614
|
+
/* Cards: OS strips bg fills — add explicit border so shape is preserved */
|
|
1615
|
+
[data-slot="card"],
|
|
1616
|
+
.card {
|
|
1617
|
+
border: 2px solid CanvasText !important;
|
|
1618
|
+
}
|
|
1619
|
+
|
|
1620
|
+
/* Sidebar edge */
|
|
1621
|
+
[data-slot="sidebar"] {
|
|
1622
|
+
border-inline-end: 2px solid CanvasText !important;
|
|
1623
|
+
}
|
|
1624
|
+
|
|
1625
|
+
/* Wrapper-only sidebar badge (no inner Badge) — rare; keep single ring */
|
|
1626
|
+
[data-slot="sidebar-menu-badge"]:not(:has([data-slot="badge"])) {
|
|
1627
|
+
border: 2px solid CanvasText !important;
|
|
1628
|
+
background-color: Canvas !important;
|
|
1629
|
+
color: CanvasText !important;
|
|
1630
|
+
outline: none !important;
|
|
1631
|
+
box-shadow: none !important;
|
|
1632
|
+
}
|
|
1633
|
+
|
|
1634
|
+
/* Positioning shell around <Badge/> — do not draw a second ring */
|
|
1635
|
+
[data-slot="sidebar-menu-badge"]:has([data-slot="badge"]) {
|
|
1636
|
+
border: none !important;
|
|
1637
|
+
background: transparent !important;
|
|
1638
|
+
outline: none !important;
|
|
1639
|
+
box-shadow: none !important;
|
|
1640
|
+
}
|
|
1641
|
+
|
|
1642
|
+
[data-slot="badge"],
|
|
1643
|
+
[data-slot="view-toolbar-count"] {
|
|
1644
|
+
border: 2px solid CanvasText !important;
|
|
1645
|
+
background-color: Canvas !important;
|
|
1646
|
+
color: CanvasText !important;
|
|
1647
|
+
outline: none !important;
|
|
1648
|
+
box-shadow: none !important;
|
|
1649
|
+
}
|
|
1650
|
+
|
|
1651
|
+
[data-slot="badge"] *,
|
|
1652
|
+
[data-slot="view-toolbar-count"] * {
|
|
1653
|
+
color: CanvasText !important;
|
|
1654
|
+
}
|
|
1655
|
+
|
|
1656
|
+
/* Avoid button chrome + inner count pill = double border */
|
|
1657
|
+
button[data-slot="view-segmented-item"] {
|
|
1658
|
+
border: none !important;
|
|
1659
|
+
}
|
|
1660
|
+
|
|
1661
|
+
/* Radix Tabs (ChartCard, library, etc.) — gray inactive + invisible active in OS HC */
|
|
1662
|
+
[data-slot="tabs-list"] {
|
|
1663
|
+
border: 2px solid CanvasText !important;
|
|
1664
|
+
background-color: transparent !important;
|
|
1665
|
+
}
|
|
1666
|
+
|
|
1667
|
+
[data-slot="tabs-trigger"] {
|
|
1668
|
+
color: CanvasText !important;
|
|
1669
|
+
background-color: transparent !important;
|
|
1670
|
+
opacity: 1 !important;
|
|
1671
|
+
}
|
|
1672
|
+
|
|
1673
|
+
[data-slot="tabs-trigger"][data-state="active"] {
|
|
1674
|
+
background-color: Highlight !important;
|
|
1675
|
+
color: HighlightText !important;
|
|
1676
|
+
outline: none !important;
|
|
1677
|
+
font-weight: 600 !important;
|
|
1678
|
+
}
|
|
1679
|
+
|
|
1680
|
+
/* Key metrics strip — labels/values/trend icons must not stay muted */
|
|
1681
|
+
[data-slot="key-metrics"] :where(span, p, button, a, i, label, div) {
|
|
1682
|
+
color: CanvasText !important;
|
|
1683
|
+
}
|
|
1684
|
+
|
|
1685
|
+
/* Menu / select / command palette — accent fill is often low-contrast in forced mode */
|
|
1686
|
+
[data-slot="dropdown-menu-item"][data-highlighted]:not([data-disabled]),
|
|
1687
|
+
[data-slot="dropdown-menu-checkbox-item"][data-highlighted]:not([data-disabled]),
|
|
1688
|
+
[data-slot="dropdown-menu-radio-item"][data-highlighted]:not([data-disabled]),
|
|
1689
|
+
[data-slot="dropdown-menu-sub-trigger"][data-highlighted]:not([data-disabled]),
|
|
1690
|
+
[data-slot="select-item"][data-highlighted]:not([data-disabled]),
|
|
1691
|
+
[data-slot="command-item"][data-selected]:not([data-disabled]),
|
|
1692
|
+
[data-slot="command-item"][aria-selected="true"]:not([data-disabled]) {
|
|
1693
|
+
background-color: Highlight !important;
|
|
1694
|
+
color: HighlightText !important;
|
|
1695
|
+
}
|
|
1696
|
+
|
|
1697
|
+
[data-slot="dropdown-menu-item"][data-highlighted] *,
|
|
1698
|
+
[data-slot="dropdown-menu-checkbox-item"][data-highlighted] *,
|
|
1699
|
+
[data-slot="dropdown-menu-radio-item"][data-highlighted] *,
|
|
1700
|
+
[data-slot="dropdown-menu-sub-trigger"][data-highlighted] *,
|
|
1701
|
+
[data-slot="select-item"][data-highlighted] *,
|
|
1702
|
+
[data-slot="command-item"][data-selected] *,
|
|
1703
|
+
[data-slot="command-item"][aria-selected="true"] * {
|
|
1704
|
+
color: HighlightText !important;
|
|
1705
|
+
}
|
|
1706
|
+
|
|
1707
|
+
/* Views toolbar (list hubs) + segmented radiogroup — selection via outline, not fill */
|
|
1708
|
+
[data-slot="view-segmented-toolbar"] {
|
|
1709
|
+
border: 2px solid CanvasText !important;
|
|
1710
|
+
background: transparent !important;
|
|
1711
|
+
}
|
|
1712
|
+
|
|
1713
|
+
[data-slot="view-segmented-item"] {
|
|
1714
|
+
color: CanvasText !important;
|
|
1715
|
+
background: transparent !important;
|
|
1716
|
+
}
|
|
1717
|
+
|
|
1718
|
+
[data-slot="view-segmented-item"][aria-pressed="true"],
|
|
1719
|
+
[data-slot="view-segmented-item"][aria-checked="true"] {
|
|
1720
|
+
background-color: Highlight !important;
|
|
1721
|
+
color: HighlightText !important;
|
|
1722
|
+
outline: none !important;
|
|
1723
|
+
}
|
|
1724
|
+
|
|
1725
|
+
/* Sidebar active item — Highlight brand fill */
|
|
1726
|
+
[data-slot="sidebar-menu-button"][data-active="true"] {
|
|
1727
|
+
background-color: Highlight !important;
|
|
1728
|
+
color: HighlightText !important;
|
|
1729
|
+
outline: none !important;
|
|
1730
|
+
}
|
|
1731
|
+
[data-slot="sidebar-menu-button"][data-active="true"] * {
|
|
1732
|
+
color: HighlightText !important;
|
|
1733
|
+
}
|
|
1734
|
+
[data-slot="sidebar-menu-button"][data-active="true"] [data-slot="badge"],
|
|
1735
|
+
[data-slot="sidebar-menu-button"][data-active="true"] [data-slot="sidebar-menu-badge"] {
|
|
1736
|
+
background-color: HighlightText !important;
|
|
1737
|
+
color: Highlight !important;
|
|
1738
|
+
border-color: HighlightText !important;
|
|
1739
|
+
}
|
|
1740
|
+
[data-slot="sidebar-menu-button"][data-active="true"] [data-slot="badge"] *,
|
|
1741
|
+
[data-slot="sidebar-menu-button"][data-active="true"] [data-slot="sidebar-menu-badge"] * {
|
|
1742
|
+
color: Highlight !important;
|
|
1743
|
+
}
|
|
1744
|
+
|
|
1745
|
+
/* Strip conditional-formatting inline bg in forced-colors */
|
|
1746
|
+
td[style*="background"] {
|
|
1747
|
+
background: Canvas !important;
|
|
1748
|
+
}
|
|
1749
|
+
td.pinned-cell {
|
|
1750
|
+
background-color: Canvas !important;
|
|
1751
|
+
}
|
|
1752
|
+
tr:hover td,
|
|
1753
|
+
tr:hover td.pinned-cell {
|
|
1754
|
+
background-color: Highlight !important;
|
|
1755
|
+
color: HighlightText !important;
|
|
1756
|
+
}
|
|
1757
|
+
|
|
1758
|
+
/* Table selected rows — Highlight brand fill */
|
|
1759
|
+
tr[data-state="selected"] {
|
|
1760
|
+
background-color: Highlight !important;
|
|
1761
|
+
color: HighlightText !important;
|
|
1762
|
+
}
|
|
1763
|
+
tr[data-state="selected"] td {
|
|
1764
|
+
background: Highlight !important;
|
|
1765
|
+
background-color: Highlight !important;
|
|
1766
|
+
color: HighlightText !important;
|
|
1767
|
+
}
|
|
1768
|
+
tr[data-state="selected"] *:not([data-slot="checkbox"] *):not([data-slot="badge"] *):not([data-slot="checkbox"]):not([data-slot="badge"]) {
|
|
1769
|
+
color: HighlightText !important;
|
|
1770
|
+
}
|
|
1771
|
+
tr[data-state="selected"] [data-slot="checkbox"][data-state="checked"],
|
|
1772
|
+
tr[data-state="selected"] [data-slot="checkbox"][data-state="indeterminate"] {
|
|
1773
|
+
background-color: HighlightText !important;
|
|
1774
|
+
border-color: HighlightText !important;
|
|
1775
|
+
color: Highlight !important;
|
|
1776
|
+
}
|
|
1777
|
+
tr[data-state="selected"] [data-slot="checkbox"][data-state="checked"] *,
|
|
1778
|
+
tr[data-state="selected"] [data-slot="checkbox"][data-state="indeterminate"] * {
|
|
1779
|
+
color: Highlight !important;
|
|
1780
|
+
}
|
|
1781
|
+
tr[data-state="selected"] [data-slot="checkbox"]:not([data-state="checked"]):not([data-state="indeterminate"]) {
|
|
1782
|
+
background-color: Highlight !important;
|
|
1783
|
+
border-color: HighlightText !important;
|
|
1784
|
+
color: HighlightText !important;
|
|
1785
|
+
}
|
|
1786
|
+
tr[data-state="selected"] [data-slot="badge"] {
|
|
1787
|
+
background-color: HighlightText !important;
|
|
1788
|
+
color: Highlight !important;
|
|
1789
|
+
border-color: HighlightText !important;
|
|
1790
|
+
}
|
|
1791
|
+
tr[data-state="selected"] [data-slot="badge"] * {
|
|
1792
|
+
color: Highlight !important;
|
|
1793
|
+
}
|
|
1794
|
+
tr[data-state="selected"] [data-slot="avatar"] {
|
|
1795
|
+
border-color: HighlightText !important;
|
|
1796
|
+
}
|
|
1797
|
+
tr[data-state="selected"] [data-slot="avatar-fallback"] {
|
|
1798
|
+
background-color: HighlightText !important;
|
|
1799
|
+
color: Highlight !important;
|
|
1800
|
+
}
|
|
1801
|
+
/* Badge in forced-colors — opaque canvas bg */
|
|
1802
|
+
[data-slot="badge"] {
|
|
1803
|
+
background-color: Canvas !important;
|
|
1804
|
+
border-color: CanvasText !important;
|
|
1805
|
+
color: CanvasText !important;
|
|
1806
|
+
}
|
|
1807
|
+
|
|
1808
|
+
/* Checked checkboxes — Highlight fill */
|
|
1809
|
+
[data-slot="checkbox"][data-state="checked"] *,
|
|
1810
|
+
[data-slot="checkbox"][data-state="indeterminate"] * {
|
|
1811
|
+
color: HighlightText !important;
|
|
1812
|
+
}
|
|
1813
|
+
|
|
1814
|
+
/* Avatar in forced-colors */
|
|
1815
|
+
[data-slot="avatar"] {
|
|
1816
|
+
border: 2px solid CanvasText !important;
|
|
1817
|
+
}
|
|
1818
|
+
[data-slot="avatar"]::after {
|
|
1819
|
+
display: none !important;
|
|
1820
|
+
}
|
|
1821
|
+
[data-slot="avatar-fallback"] {
|
|
1822
|
+
background-color: Canvas !important;
|
|
1823
|
+
color: CanvasText !important;
|
|
1824
|
+
}
|
|
1825
|
+
|
|
1826
|
+
/* Checked checkboxes / radios — Highlight fill */
|
|
1827
|
+
[data-slot="checkbox"][data-state="checked"],
|
|
1828
|
+
[data-slot="checkbox"][data-state="indeterminate"] {
|
|
1829
|
+
background-color: Highlight !important;
|
|
1830
|
+
border-color: Highlight !important;
|
|
1831
|
+
color: HighlightText !important;
|
|
1832
|
+
}
|
|
1833
|
+
[data-slot="radio-group-item"][data-state="checked"] {
|
|
1834
|
+
background-color: Highlight !important;
|
|
1835
|
+
border-color: Highlight !important;
|
|
1836
|
+
}
|
|
1837
|
+
|
|
1838
|
+
/* Switch ON — Highlight fill */
|
|
1839
|
+
[role="switch"][aria-checked="true"] {
|
|
1840
|
+
background-color: Highlight !important;
|
|
1841
|
+
border-color: Highlight !important;
|
|
1842
|
+
}
|
|
1843
|
+
[role="switch"][aria-checked="true"] > span {
|
|
1844
|
+
background-color: HighlightText !important;
|
|
1845
|
+
}
|
|
1846
|
+
|
|
1847
|
+
/* Toggle ON — Highlight fill */
|
|
1848
|
+
[data-slot="toggle"][data-state="on"],
|
|
1849
|
+
[data-slot="toggle-group-item"][data-state="on"] {
|
|
1850
|
+
background-color: Highlight !important;
|
|
1851
|
+
color: HighlightText !important;
|
|
1852
|
+
border-color: Highlight !important;
|
|
1853
|
+
}
|
|
1854
|
+
|
|
1855
|
+
/* Progress bars — bordered track with CanvasText fill */
|
|
1856
|
+
[role="progressbar"] {
|
|
1857
|
+
border: 1px solid CanvasText !important;
|
|
1858
|
+
background-color: Canvas !important;
|
|
1859
|
+
}
|
|
1860
|
+
[role="progressbar"] > * {
|
|
1861
|
+
background-color: CanvasText !important;
|
|
1862
|
+
}
|
|
1863
|
+
|
|
1864
|
+
/* Portal overlays — explicit Canvas pairing (OS often strips popover fills) */
|
|
1865
|
+
[data-slot="dropdown-menu-content"],
|
|
1866
|
+
[data-slot="dropdown-menu-sub-content"],
|
|
1867
|
+
[data-slot="popover-content"],
|
|
1868
|
+
[data-slot="select-content"],
|
|
1869
|
+
[data-slot="dialog-content"],
|
|
1870
|
+
[data-slot="sheet-content"],
|
|
1871
|
+
[data-slot="drawer-content"] {
|
|
1872
|
+
border: 2px solid CanvasText !important;
|
|
1873
|
+
background-color: Canvas !important;
|
|
1874
|
+
color: CanvasText !important;
|
|
1875
|
+
}
|
|
1876
|
+
|
|
1877
|
+
[data-slot="command"] {
|
|
1878
|
+
background-color: Canvas !important;
|
|
1879
|
+
color: CanvasText !important;
|
|
1880
|
+
}
|
|
1881
|
+
|
|
1882
|
+
/* Board cards — border-defined shape when fills are stripped */
|
|
1883
|
+
[data-slot="board-card"] {
|
|
1884
|
+
border: 2px solid CanvasText !important;
|
|
1885
|
+
background-color: Canvas !important;
|
|
1886
|
+
color: CanvasText !important;
|
|
1887
|
+
}
|
|
1888
|
+
|
|
1889
|
+
/* List hub status badges — border-only, text readable */
|
|
1890
|
+
[data-slot="list-hub-status-badge"] {
|
|
1891
|
+
border: 2px solid CanvasText !important;
|
|
1892
|
+
background-color: Canvas !important;
|
|
1893
|
+
color: CanvasText !important;
|
|
1894
|
+
font-weight: 700 !important;
|
|
1895
|
+
}
|
|
1896
|
+
|
|
1897
|
+
/* Insight cards — strip gradient, add border */
|
|
1898
|
+
[aria-label="Insight"],
|
|
1899
|
+
[data-slot="insight-card"] {
|
|
1900
|
+
border: 2px solid CanvasText !important;
|
|
1901
|
+
background: Canvas !important;
|
|
1902
|
+
color: CanvasText !important;
|
|
1903
|
+
}
|
|
1904
|
+
|
|
1905
|
+
/* Coach marks / guided tours */
|
|
1906
|
+
[data-slot="coach-mark"] {
|
|
1907
|
+
border: 2px solid CanvasText !important;
|
|
1908
|
+
background-color: Canvas !important;
|
|
1909
|
+
color: CanvasText !important;
|
|
1910
|
+
}
|
|
1911
|
+
[data-slot="coach-mark"] * {
|
|
1912
|
+
color: CanvasText !important;
|
|
1913
|
+
}
|
|
1914
|
+
|
|
1915
|
+
/* Avatars — thicken existing ::after ring */
|
|
1916
|
+
[data-slot="avatar"]::after {
|
|
1917
|
+
border-width: 2px !important;
|
|
1918
|
+
border-color: CanvasText !important;
|
|
1919
|
+
}
|
|
1920
|
+
|
|
1921
|
+
/* Breadcrumbs */
|
|
1922
|
+
[data-slot="breadcrumb-separator"] {
|
|
1923
|
+
color: CanvasText !important;
|
|
1924
|
+
}
|
|
1925
|
+
[data-slot="breadcrumb-link"] {
|
|
1926
|
+
color: LinkText !important;
|
|
1927
|
+
}
|
|
1928
|
+
[data-slot="breadcrumb-page"] {
|
|
1929
|
+
color: CanvasText !important;
|
|
1930
|
+
font-weight: 700 !important;
|
|
1931
|
+
}
|
|
1932
|
+
|
|
1933
|
+
/* Tooltip */
|
|
1934
|
+
[data-slot="tooltip-content"] {
|
|
1935
|
+
border: 2px solid CanvasText !important;
|
|
1936
|
+
background-color: Canvas !important;
|
|
1937
|
+
color: CanvasText !important;
|
|
1938
|
+
}
|
|
1939
|
+
|
|
1940
|
+
/* Export drawer */
|
|
1941
|
+
[data-slot="export-drawer"] {
|
|
1942
|
+
border: 2px solid CanvasText !important;
|
|
1943
|
+
background-color: Canvas !important;
|
|
1944
|
+
color: CanvasText !important;
|
|
1945
|
+
}
|
|
1946
|
+
|
|
1947
|
+
/* Separators */
|
|
1948
|
+
[data-slot="separator"] {
|
|
1949
|
+
background-color: CanvasText !important;
|
|
1950
|
+
opacity: 1 !important;
|
|
1951
|
+
}
|
|
1952
|
+
|
|
1953
|
+
/* Charts — forced-colors strips SVG fills; add stroke as fallback */
|
|
1954
|
+
svg path, svg rect, svg circle {
|
|
1955
|
+
forced-color-adjust: none;
|
|
1956
|
+
}
|
|
1957
|
+
|
|
1958
|
+
/* Recharts radial bars, lines, and area — explicit stroke fallbacks */
|
|
1959
|
+
.recharts-radial-bar-sector,
|
|
1960
|
+
.recharts-line-curve,
|
|
1961
|
+
.recharts-area-curve {
|
|
1962
|
+
forced-color-adjust: none;
|
|
1963
|
+
stroke: CanvasText !important;
|
|
1964
|
+
}
|
|
1965
|
+
|
|
1966
|
+
.recharts-radial-bar-background-sector {
|
|
1967
|
+
forced-color-adjust: none;
|
|
1968
|
+
fill: Canvas !important;
|
|
1969
|
+
stroke: GrayText !important;
|
|
1970
|
+
}
|
|
1971
|
+
|
|
1972
|
+
.recharts-cartesian-axis-tick-value {
|
|
1973
|
+
fill: CanvasText !important;
|
|
1974
|
+
}
|
|
1975
|
+
|
|
1976
|
+
.recharts-cartesian-grid line {
|
|
1977
|
+
stroke: GrayText !important;
|
|
1978
|
+
}
|
|
1979
|
+
|
|
1980
|
+
.recharts-legend-item-text {
|
|
1981
|
+
color: CanvasText !important;
|
|
1982
|
+
}
|
|
1983
|
+
|
|
1984
|
+
.recharts-tooltip-wrapper {
|
|
1985
|
+
border: 2px solid CanvasText !important;
|
|
1986
|
+
background-color: Canvas !important;
|
|
1987
|
+
}
|
|
1988
|
+
}
|
|
1989
|
+
|
|
1990
|
+
/* ==========================================================================
|
|
1991
|
+
Base layer — global element defaults with AA focus management
|
|
1992
|
+
========================================================================== */
|
|
1993
|
+
@layer base {
|
|
1994
|
+
/* Reset + border-color default */
|
|
1995
|
+
*, *::before, *::after {
|
|
1996
|
+
@apply border-border;
|
|
1997
|
+
box-sizing: border-box;
|
|
1998
|
+
}
|
|
1999
|
+
|
|
2000
|
+
/* Body — outer canvas matches sidebar; main column uses bg-background (white in light) */
|
|
2001
|
+
body {
|
|
2002
|
+
@apply bg-sidebar text-foreground antialiased;
|
|
2003
|
+
font-family: var(--font-sans);
|
|
2004
|
+
/* 14px baseline on body. 1rem stays = 16px so all shadcn rem-based
|
|
2005
|
+
layout (spacing, heights, radii) is unaffected at any zoom level. */
|
|
2006
|
+
font-size: 0.875rem;
|
|
2007
|
+
line-height: 1.5;
|
|
2008
|
+
/* Font smoothing (Tailwind `antialiased` = -webkit-font-smoothing + -moz-osx):
|
|
2009
|
+
Industry practice per Josh Comeau’s CSS reset and 2024 cross-browser testing
|
|
2010
|
+
(e.g. David Bushell): the -webkit property affects macOS WebKit browsers only —
|
|
2011
|
+
it tones down browser-only subpixel AA (Mojave+ system UI already moved away).
|
|
2012
|
+
Windows/Linux/iOS/Android: no practical effect; OS font rasterizer (ClearType, etc.)
|
|
2013
|
+
owns rendering. Safe to apply on body for Mac parity without changing Windows output. */
|
|
2014
|
+
}
|
|
2015
|
+
|
|
2016
|
+
html {
|
|
2017
|
+
@apply font-sans;
|
|
2018
|
+
color-scheme: light;
|
|
2019
|
+
/* Match sidebar canvas (body) on overscroll */
|
|
2020
|
+
background-color: var(--sidebar);
|
|
2021
|
+
}
|
|
2022
|
+
|
|
2023
|
+
html.dark {
|
|
2024
|
+
color-scheme: dark;
|
|
2025
|
+
}
|
|
2026
|
+
|
|
2027
|
+
/* ── Focus management (WCAG 2.4.11 / 2.4.7) ──────────────────── */
|
|
2028
|
+
/* Visible on keyboard navigation only; hidden for mouse users */
|
|
2029
|
+
:focus-visible {
|
|
2030
|
+
outline: 2px solid var(--ring);
|
|
2031
|
+
outline-offset: 2px;
|
|
2032
|
+
border-radius: var(--radius-sm, 4px);
|
|
2033
|
+
}
|
|
2034
|
+
|
|
2035
|
+
/* Suppress outline for mouse/touch (Safari workaround) */
|
|
2036
|
+
:focus:not(:focus-visible) {
|
|
2037
|
+
outline: none;
|
|
2038
|
+
}
|
|
2039
|
+
|
|
2040
|
+
/* ── Reduced motion (WCAG 2.3.3) ────────────────────────────── */
|
|
2041
|
+
@media (prefers-reduced-motion: reduce) {
|
|
2042
|
+
*, *::before, *::after {
|
|
2043
|
+
animation-duration: 0.01ms !important;
|
|
2044
|
+
animation-iteration-count: 1 !important;
|
|
2045
|
+
transition-duration: 0.01ms !important;
|
|
2046
|
+
scroll-behavior: auto !important;
|
|
2047
|
+
}
|
|
2048
|
+
}
|
|
2049
|
+
|
|
2050
|
+
/* ── Touch targets (WCAG 2.5.5) ─────────────────────────────── */
|
|
2051
|
+
/* Applied via utility: min-h-[var(--control-height-touch)] */
|
|
2052
|
+
/* Coarse pointer only: browser zoom (200–400%) shrinks the *layout* viewport
|
|
2053
|
+
in CSS px, so max-width: 767px becomes true on desktop — without pointer: coarse,
|
|
2054
|
+
44px min-height hits every button and [role=checkbox], stretching 16px-wide
|
|
2055
|
+
checkboxes into tall pills and blowing up table/toolbar controls. Real phones
|
|
2056
|
+
and tablets report pointer: coarse. */
|
|
2057
|
+
@media (max-width: 767px) and (pointer: coarse) {
|
|
2058
|
+
button,
|
|
2059
|
+
[role="button"],
|
|
2060
|
+
[role="radio"],
|
|
2061
|
+
[role="switch"],
|
|
2062
|
+
[role="menuitem"],
|
|
2063
|
+
[role="tab"],
|
|
2064
|
+
a {
|
|
2065
|
+
min-height: var(--control-height-touch, 44px);
|
|
2066
|
+
}
|
|
2067
|
+
}
|
|
2068
|
+
/* Checkboxes use compact box + pseudo-element hit slop (see ui/checkbox). */
|
|
2069
|
+
|
|
2070
|
+
/* ── Heading hierarchy ───────────────────────────────────────── */
|
|
2071
|
+
/* Ivy Presto (font-heading) applied ONLY via explicit class/inline style
|
|
2072
|
+
on PageHeader <h1>. All other headings use Inter (font-sans). */
|
|
2073
|
+
h1, h2, h3, h4, h5, h6 {
|
|
2074
|
+
font-family: var(--font-sans);
|
|
2075
|
+
font-weight: 600;
|
|
2076
|
+
line-height: 1.25;
|
|
2077
|
+
color: var(--foreground);
|
|
2078
|
+
}
|
|
2079
|
+
|
|
2080
|
+
/* ── Skip to main content (WCAG 2.4.1) ─────────────────────── */
|
|
2081
|
+
.skip-to-content {
|
|
2082
|
+
position: absolute;
|
|
2083
|
+
left: -9999px;
|
|
2084
|
+
top: auto;
|
|
2085
|
+
width: 1px;
|
|
2086
|
+
height: 1px;
|
|
2087
|
+
overflow: hidden;
|
|
2088
|
+
z-index: 9999;
|
|
2089
|
+
}
|
|
2090
|
+
|
|
2091
|
+
.skip-to-content:focus {
|
|
2092
|
+
position: fixed;
|
|
2093
|
+
top: 0;
|
|
2094
|
+
left: 0;
|
|
2095
|
+
width: auto;
|
|
2096
|
+
height: auto;
|
|
2097
|
+
padding: 0.75rem 1.25rem;
|
|
2098
|
+
background: var(--background);
|
|
2099
|
+
color: var(--foreground);
|
|
2100
|
+
border: 2px solid var(--ring);
|
|
2101
|
+
border-radius: var(--radius-md);
|
|
2102
|
+
font-weight: 600;
|
|
2103
|
+
font-size: 1rem;
|
|
2104
|
+
z-index: 9999;
|
|
2105
|
+
}
|
|
2106
|
+
}
|
|
2107
|
+
|
|
2108
|
+
/* ==========================================================================
|
|
2109
|
+
Utility layer — design-system helpers
|
|
2110
|
+
========================================================================== */
|
|
2111
|
+
@layer utilities {
|
|
2112
|
+
/* Visually hidden but accessible to screen readers (WCAG 1.3.1) */
|
|
2113
|
+
.sr-only {
|
|
2114
|
+
position: absolute;
|
|
2115
|
+
width: 1px;
|
|
2116
|
+
height: 1px;
|
|
2117
|
+
padding: 0;
|
|
2118
|
+
margin: -1px;
|
|
2119
|
+
overflow: hidden;
|
|
2120
|
+
clip: rect(0, 0, 0, 0);
|
|
2121
|
+
white-space: nowrap;
|
|
2122
|
+
border-width: 0;
|
|
2123
|
+
}
|
|
2124
|
+
|
|
2125
|
+
/* AA-safe muted text — use instead of text-muted-foreground on light bg */
|
|
2126
|
+
.text-aa-muted {
|
|
2127
|
+
color: oklch(0.50 0.012 270); /* 5.5:1 on white ✓ */
|
|
2128
|
+
}
|
|
2129
|
+
|
|
2130
|
+
/* Touch-target wrapper for icon buttons (mobile only) */
|
|
2131
|
+
.touch-target {
|
|
2132
|
+
min-height: var(--control-height-touch, 44px);
|
|
2133
|
+
min-width: var(--control-height-touch, 44px);
|
|
2134
|
+
display: inline-flex;
|
|
2135
|
+
align-items: center;
|
|
2136
|
+
justify-content: center;
|
|
2137
|
+
}
|
|
2138
|
+
|
|
2139
|
+
@media (min-width: 768px) {
|
|
2140
|
+
.touch-target {
|
|
2141
|
+
min-height: unset;
|
|
2142
|
+
min-width: unset;
|
|
2143
|
+
}
|
|
2144
|
+
}
|
|
2145
|
+
|
|
2146
|
+
/* Form field border — use --control-border (3:1 minimum) */
|
|
2147
|
+
.field-border {
|
|
2148
|
+
border-color: var(--control-border);
|
|
2149
|
+
}
|
|
2150
|
+
|
|
2151
|
+
/* Exxat Prism highlight banner */
|
|
2152
|
+
.banner-prism {
|
|
2153
|
+
background-color: var(--banner-prism-bg);
|
|
2154
|
+
}
|
|
2155
|
+
|
|
2156
|
+
/* Sidebar nav — little pop when an item becomes active. Key swap on the
|
|
2157
|
+
wrapper remounts the span, so the animation replays on selection. */
|
|
2158
|
+
@keyframes sidebar-icon-pop {
|
|
2159
|
+
0% { opacity: 0.4; transform: scale(0.7) rotate(-6deg); }
|
|
2160
|
+
60% { opacity: 1; transform: scale(1.15) rotate(2deg); }
|
|
2161
|
+
100% { opacity: 1; transform: scale(1) rotate(0); }
|
|
2162
|
+
}
|
|
2163
|
+
|
|
2164
|
+
/* Radix Collapsible / Accordion — slide the children open/closed using the
|
|
2165
|
+
`--radix-collapsible-content-height` CSS var that Radix sets on the
|
|
2166
|
+
content element. Mirrors the shadcn accordion pattern (Tailwind v3
|
|
2167
|
+
"accordion-down" / "accordion-up"); we keep our own name so it can be
|
|
2168
|
+
reused by both Collapsible and Accordion primitives. */
|
|
2169
|
+
@keyframes collapsible-down {
|
|
2170
|
+
from { height: 0; }
|
|
2171
|
+
to { height: var(--radix-collapsible-content-height); }
|
|
2172
|
+
}
|
|
2173
|
+
@keyframes collapsible-up {
|
|
2174
|
+
from { height: var(--radix-collapsible-content-height); }
|
|
2175
|
+
to { height: 0; }
|
|
2176
|
+
}
|
|
2177
|
+
|
|
2178
|
+
/* Ask Leo suggestion chips — staggered fade-in + lift on first render. */
|
|
2179
|
+
@keyframes leo-chip-in {
|
|
2180
|
+
0% { opacity: 0; transform: translateY(8px) scale(0.96); }
|
|
2181
|
+
100% { opacity: 1; transform: translateY(0) scale(1); }
|
|
2182
|
+
}
|
|
2183
|
+
|
|
2184
|
+
/* Leo typing indicator — 3 dots bouncing opacity/scale, staggered via delay. */
|
|
2185
|
+
@keyframes leo-typing-dot {
|
|
2186
|
+
0%, 80%, 100% { opacity: 0.3; transform: scale(0.8); }
|
|
2187
|
+
40% { opacity: 1; transform: scale(1); }
|
|
2188
|
+
}
|
|
2189
|
+
|
|
2190
|
+
/* Whole-panel brand radial glow pulse — runs on the BG layer while Leo thinks. */
|
|
2191
|
+
@keyframes leo-panel-pulse {
|
|
2192
|
+
0%, 100% { opacity: 0.5; transform: scale(1); }
|
|
2193
|
+
50% { opacity: 0.75; transform: scale(1.01); }
|
|
2194
|
+
}
|
|
2195
|
+
|
|
2196
|
+
/* Chart “Leo insight” marker — soft breathing halo behind the chip. */
|
|
2197
|
+
@keyframes leo-chart-insight-halo {
|
|
2198
|
+
0%, 100% { opacity: 0.45; transform: scale(1); }
|
|
2199
|
+
50% { opacity: 0.72; transform: scale(1.12); }
|
|
2200
|
+
}
|
|
2201
|
+
|
|
2202
|
+
/* Accent dot on the insight marker — gentle pulse (respect motion-reduce in markup). */
|
|
2203
|
+
@keyframes leo-chart-insight-dot {
|
|
2204
|
+
0%, 100% { opacity: 0.9; transform: scale(1); }
|
|
2205
|
+
50% { opacity: 1; transform: scale(1.35); }
|
|
2206
|
+
}
|
|
2207
|
+
}
|
|
2208
|
+
|
|
2209
|
+
/* After all @layer rules: win over Tailwind preflight / layer merge so real controls show a pointer. */
|
|
2210
|
+
button:not(:disabled):not([disabled]),
|
|
2211
|
+
[role="button"]:not([aria-disabled="true"]):not([data-disabled]) {
|
|
2212
|
+
cursor: pointer;
|
|
2213
|
+
}
|