documentation-hub 5.7.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (271) hide show
  1. package/.eslintrc.json +43 -0
  2. package/.github/workflows/build.yml +64 -0
  3. package/.github/workflows/ci.yml +39 -0
  4. package/.vscode/extensions.json +3 -0
  5. package/Current.md +97 -0
  6. package/DocHub_Image.png +0 -0
  7. package/README.md +666 -0
  8. package/USER_GUIDE.md +1173 -0
  9. package/Updater.md +311 -0
  10. package/build/256x256.png +0 -0
  11. package/build/512x512.png +0 -0
  12. package/build/app-update.yml +4 -0
  13. package/build/create-icon.js +208 -0
  14. package/build/icon.ico +0 -0
  15. package/build/icon.png +0 -0
  16. package/build/icon_1024x1024.png +0 -0
  17. package/dist/assets/Analytics-BpsG9895.js +1 -0
  18. package/dist/assets/Card-IAZin8kp.js +1 -0
  19. package/dist/assets/CurrentSession-B-rFkHvf.js +12 -0
  20. package/dist/assets/Dashboard-C_5gMb0q.js +1 -0
  21. package/dist/assets/Documents-CqZ25axS.js +1 -0
  22. package/dist/assets/Input-l89xwXBi.js +1 -0
  23. package/dist/assets/Reporting-DqdHJY_a.js +1 -0
  24. package/dist/assets/Search-XNbu5z_3.js +1 -0
  25. package/dist/assets/SessionManager-lH9hZfzH.js +1 -0
  26. package/dist/assets/Sessions-ClZOPYNc.js +1 -0
  27. package/dist/assets/Settings-DUEHGURa.js +11 -0
  28. package/dist/assets/index-8xUe8ptc.js +24 -0
  29. package/dist/assets/index-RYyJqF7O.css +1 -0
  30. package/dist/assets/path-BkOl0AGO.js +1 -0
  31. package/dist/assets/promises-ID_B9S-h.js +1 -0
  32. package/dist/assets/urlHelpers-TvgahX0r.js +1 -0
  33. package/dist/assets/useToast-yRSO1dkm.js +1 -0
  34. package/dist/assets/vendor-charts-RkGK5ROP.js +36 -0
  35. package/dist/assets/vendor-db-l0sNRNKZ.js +1 -0
  36. package/dist/assets/vendor-react-BVZ_anCF.js +4 -0
  37. package/dist/assets/vendor-search-Dw8P0qyA.js +1 -0
  38. package/dist/assets/vendor-ui-BU7NfluV.js +53 -0
  39. package/dist/electron/PowerAutomateApiService-LfW09ZGr.js +147 -0
  40. package/dist/electron/main-CXkNtyv-.js +19789 -0
  41. package/dist/electron/main.js +5 -0
  42. package/dist/electron/preload.js +1 -0
  43. package/dist/icon.png +0 -0
  44. package/dist/index.html +27 -0
  45. package/docs/CODEBASE_ANALYSIS_REPORT.md +309 -0
  46. package/docs/DEBUG_LOGGING_GUIDE.md +244 -0
  47. package/docs/README.md +115 -0
  48. package/docs/TOC_WIRING_GUIDE.md +344 -0
  49. package/docs/analysis/Bullet_Symbol_Bug_Analysis.md +136 -0
  50. package/docs/analysis/DOCXMLATER_ANALYSIS_SUMMARY.txt +169 -0
  51. package/docs/analysis/Document_Processing_Issues_Analysis.md +704 -0
  52. package/docs/analysis/FIELD_PRESERVATION_ANALYSIS.md +1200 -0
  53. package/docs/analysis/INDENTATION_PRESERVE_ANALYSIS.md +181 -0
  54. package/docs/analysis/INDENTATION_PRESERVE_IMPLEMENTATION.md +207 -0
  55. package/docs/analysis/List_Implementation.md +206 -0
  56. package/docs/analysis/List_Implementation_Accuracy_Report.md +366 -0
  57. package/docs/analysis/PROCESSING_OPTIONS_UI_UPDATES.md +220 -0
  58. package/docs/analysis/RefactorStyles.md +852 -0
  59. package/docs/analysis/STYLE_PARAMETER_ENHANCEMENT.md +143 -0
  60. package/docs/analysis/docxmlater-comparison-todo-2025-11-13.md +636 -0
  61. package/docs/analysis/docxmlater-implementation-analysis-2025-11-13.md +340 -0
  62. package/docs/analysis/docxmlater-template_ui-integration-analysis.md +263 -0
  63. package/docs/analysis/github-issues-to-create.md +237 -0
  64. package/docs/api/API_README.md +538 -0
  65. package/docs/api/API_REFERENCE.md +751 -0
  66. package/docs/api/TYPE_DEFINITIONS.md +869 -0
  67. package/docs/architecture/FONT_EMBEDDING_GUIDE.md +318 -0
  68. package/docs/architecture/docxmlater-functions-and-structure.md +726 -0
  69. package/docs/docxmlater-readme.md +1341 -0
  70. package/docs/fixes/EXECUTION_LOG_TEST_BASE.md +573 -0
  71. package/docs/fixes/HYPERLINK_TEXT_SANITIZATION.md +253 -0
  72. package/docs/fixes/README.md +37 -0
  73. package/docs/github-issues/issue-1-body.md +125 -0
  74. package/docs/github-issues/issue-10-body.md +850 -0
  75. package/docs/github-issues/issue-2-body.md +200 -0
  76. package/docs/github-issues/issue-3-body.md +270 -0
  77. package/docs/github-issues/issue-4-body.md +169 -0
  78. package/docs/github-issues/issue-5-body.md +173 -0
  79. package/docs/github-issues/issue-6-body.md +158 -0
  80. package/docs/github-issues/issue-7-body.md +171 -0
  81. package/docs/github-issues/issue-8-body.md +407 -0
  82. package/docs/github-issues/issue-9-body.md +515 -0
  83. package/docs/github-issues/issue-tracker.md +274 -0
  84. package/docs/github-issues/predictive-analysis-2025-10-18.md +2131 -0
  85. package/docs/implementation/List_Framework_Refactor_Plan.md +336 -0
  86. package/docs/implementation/PRIMARY_TEXT_COLOR_FEATURE.md +217 -0
  87. package/docs/implementation/RELEASE_PLAN_v2.1.0.md +362 -0
  88. package/docs/implementation/RefactorStyles.md +588 -0
  89. package/docs/implementation/implement-plan.md +489 -0
  90. package/docs/implementation/missing-helpers-implementation.md +391 -0
  91. package/docs/implementation/refactor-plan.md +520 -0
  92. package/docs/implementation/session-implementation-complete.md +233 -0
  93. package/docs/implementation/session-management-plan.md +250 -0
  94. package/docs/setup-checklist.md +77 -0
  95. package/docs/versions/changelog.md +345 -0
  96. package/electron/customUpdater.ts +656 -0
  97. package/electron/main.ts +2441 -0
  98. package/electron/memoryConfig.ts +187 -0
  99. package/electron/preload.ts +394 -0
  100. package/electron/proxyConfig.ts +340 -0
  101. package/electron/services/BackupService.ts +452 -0
  102. package/electron/services/DictionaryService.ts +402 -0
  103. package/electron/services/LocalDictionaryLookupService.ts +147 -0
  104. package/electron/services/PowerAutomateApiService.ts +231 -0
  105. package/electron/services/SharePointSyncService.ts +474 -0
  106. package/electron/windowsCertStore.ts +427 -0
  107. package/electron/zscalerConfig.ts +381 -0
  108. package/eslint.config.js +92 -0
  109. package/jest.config.js +52 -0
  110. package/package.json +214 -0
  111. package/postcss.config.mjs +6 -0
  112. package/public/icon.png +0 -0
  113. package/publish-release.ps1 +5 -0
  114. package/renovate.json +30 -0
  115. package/src/App.tsx +216 -0
  116. package/src/__mocks__/p-limit.js +12 -0
  117. package/src/__mocks__/styleMock.js +1 -0
  118. package/src/components/common/BugReportButton.tsx +44 -0
  119. package/src/components/common/BugReportDialog.tsx +193 -0
  120. package/src/components/common/Button.tsx +153 -0
  121. package/src/components/common/Card.tsx +86 -0
  122. package/src/components/common/ColorPickerDialog.tsx +177 -0
  123. package/src/components/common/ConfirmDialog.tsx +96 -0
  124. package/src/components/common/DebugConsole.tsx +275 -0
  125. package/src/components/common/EmptyState.tsx +183 -0
  126. package/src/components/common/ErrorBoundary.tsx +98 -0
  127. package/src/components/common/ErrorDetailsDialog.tsx +153 -0
  128. package/src/components/common/ErrorFallback.tsx +218 -0
  129. package/src/components/common/Input.tsx +109 -0
  130. package/src/components/common/Skeleton.tsx +184 -0
  131. package/src/components/common/SplashScreen.tsx +81 -0
  132. package/src/components/common/Toast.tsx +155 -0
  133. package/src/components/common/Tooltip.tsx +79 -0
  134. package/src/components/common/UpdateNotification.tsx +320 -0
  135. package/src/components/comparison/ComparisonWindow.tsx +374 -0
  136. package/src/components/comparison/SideBySideDiff.tsx +486 -0
  137. package/src/components/comparison/index.ts +8 -0
  138. package/src/components/document/DocumentUploader.tsx +288 -0
  139. package/src/components/document/HyperlinkPreview.tsx +430 -0
  140. package/src/components/document/HyperlinkService.md +1484 -0
  141. package/src/components/document/Hyperlink_Technical_Documentation.md +496 -0
  142. package/src/components/document/InlineChangesView.tsx +707 -0
  143. package/src/components/document/ProcessingProgress.tsx +303 -0
  144. package/src/components/document/ProcessingResults.tsx +256 -0
  145. package/src/components/document/TrackedChangesDetail.tsx +530 -0
  146. package/src/components/document/TrackedChangesPanel.tsx +546 -0
  147. package/src/components/document/VirtualDocumentList.tsx +240 -0
  148. package/src/components/editor/DocumentEditor.tsx +723 -0
  149. package/src/components/editor/DocumentEditorModal.tsx +640 -0
  150. package/src/components/editor/EditorQuickActions.tsx +502 -0
  151. package/src/components/editor/EditorToolbar.tsx +312 -0
  152. package/src/components/editor/TableEditor.tsx +926 -0
  153. package/src/components/editor/index.ts +18 -0
  154. package/src/components/layout/Header.tsx +190 -0
  155. package/src/components/layout/Sidebar.tsx +313 -0
  156. package/src/components/layout/TitleBar.tsx +190 -0
  157. package/src/components/navigation/CommandPalette.tsx +233 -0
  158. package/src/components/navigation/KeyboardShortcutsModal.tsx +173 -0
  159. package/src/components/sessions/ChangeItem.tsx +408 -0
  160. package/src/components/sessions/ChangeViewer.tsx +1155 -0
  161. package/src/components/sessions/DocumentComparisonModal.tsx +314 -0
  162. package/src/components/sessions/ProcessingOptions.tsx +297 -0
  163. package/src/components/sessions/ReplacementsTab.tsx +438 -0
  164. package/src/components/sessions/RevisionHandlingOptions.tsx +87 -0
  165. package/src/components/sessions/SessionManager.tsx +188 -0
  166. package/src/components/sessions/StylesEditor.tsx +1335 -0
  167. package/src/components/sessions/TabContainer.tsx +151 -0
  168. package/src/components/sessions/VirtualSessionList.tsx +157 -0
  169. package/src/components/sessions/sessionToProcessorManager.tsx +420 -0
  170. package/src/components/settings/CertificateManager.tsx +410 -0
  171. package/src/components/settings/SegmentedControl.tsx +88 -0
  172. package/src/components/settings/SettingRow.tsx +52 -0
  173. package/src/contexts/GlobalStatsContext.tsx +396 -0
  174. package/src/contexts/SessionContext.tsx +2129 -0
  175. package/src/contexts/ThemeContext.tsx +428 -0
  176. package/src/contexts/UserSettingsContext.tsx +290 -0
  177. package/src/contexts/__tests__/GlobalStatsContext.test.tsx +390 -0
  178. package/src/global.d.ts +273 -0
  179. package/src/hooks/useDocumentQueue.tsx +210 -0
  180. package/src/hooks/useToast.tsx +55 -0
  181. package/src/main.tsx +10 -0
  182. package/src/pages/Analytics.tsx +386 -0
  183. package/src/pages/CurrentSession.tsx +1174 -0
  184. package/src/pages/Dashboard.tsx +319 -0
  185. package/src/pages/Documents.tsx +317 -0
  186. package/src/pages/Projects.tsx +250 -0
  187. package/src/pages/Reporting.tsx +386 -0
  188. package/src/pages/Search.tsx +349 -0
  189. package/src/pages/Sessions.tsx +285 -0
  190. package/src/pages/Settings.tsx +2662 -0
  191. package/src/services/HyperlinkService.ts +1085 -0
  192. package/src/services/document/DocXMLaterProcessor.ts +617 -0
  193. package/src/services/document/DocumentProcessingComparison.ts +856 -0
  194. package/src/services/document/DocumentSnapshotService.ts +575 -0
  195. package/src/services/document/WordDocumentProcessor.ts +10509 -0
  196. package/src/services/document/__tests__/DocXMLaterProcessor.hyperlinks.test.md +311 -0
  197. package/src/services/document/__tests__/WordDocumentProcessor.integration.test.ts +515 -0
  198. package/src/services/document/__tests__/WordDocumentProcessor.test.ts +812 -0
  199. package/src/services/document/blanklines/BlankLineManager.ts +658 -0
  200. package/src/services/document/blanklines/__tests__/paragraphChecks.test.ts +281 -0
  201. package/src/services/document/blanklines/helpers/blankLineInsertion.ts +87 -0
  202. package/src/services/document/blanklines/helpers/blankLineSnapshot.ts +251 -0
  203. package/src/services/document/blanklines/helpers/clearCustom.ts +121 -0
  204. package/src/services/document/blanklines/helpers/contextChecks.ts +117 -0
  205. package/src/services/document/blanklines/helpers/imageChecks.ts +51 -0
  206. package/src/services/document/blanklines/helpers/paragraphChecks.ts +236 -0
  207. package/src/services/document/blanklines/helpers/removeBlanksBetweenListItems.ts +91 -0
  208. package/src/services/document/blanklines/helpers/removeTrailingBlanks.ts +35 -0
  209. package/src/services/document/blanklines/helpers/tableGuards.ts +21 -0
  210. package/src/services/document/blanklines/index.ts +67 -0
  211. package/src/services/document/blanklines/rules/additionRules.ts +337 -0
  212. package/src/services/document/blanklines/rules/indentationRules.ts +317 -0
  213. package/src/services/document/blanklines/rules/removalRules.ts +362 -0
  214. package/src/services/document/blanklines/rules/ruleTypes.ts +92 -0
  215. package/src/services/document/blanklines/types.ts +29 -0
  216. package/src/services/document/helpers/ImageBorderCropper.ts +377 -0
  217. package/src/services/document/helpers/__tests__/whitespace.test.ts +272 -0
  218. package/src/services/document/helpers/whitespace.ts +117 -0
  219. package/src/services/document/list/ListNormalizer.ts +947 -0
  220. package/src/services/document/list/index.ts +45 -0
  221. package/src/services/document/list/list-detection.ts +275 -0
  222. package/src/services/document/list/list-types.ts +162 -0
  223. package/src/services/document/processors/HyperlinkProcessor.ts +370 -0
  224. package/src/services/document/processors/ListProcessor.ts +257 -0
  225. package/src/services/document/processors/StructureProcessor.ts +176 -0
  226. package/src/services/document/processors/StyleProcessor.ts +389 -0
  227. package/src/services/document/processors/TableProcessor.ts +2238 -0
  228. package/src/services/document/processors/__tests__/HyperlinkProcessor.test.ts +314 -0
  229. package/src/services/document/processors/__tests__/ListProcessor.test.ts +291 -0
  230. package/src/services/document/processors/__tests__/StructureProcessor.test.ts +257 -0
  231. package/src/services/document/processors/__tests__/TableProcessor.hlp-tips-bullets.test.ts +459 -0
  232. package/src/services/document/processors/__tests__/TableProcessor.test.ts +1604 -0
  233. package/src/services/document/processors/index.ts +28 -0
  234. package/src/services/document/types/docx-processing.ts +310 -0
  235. package/src/services/editor/EditorActionHandlers.ts +901 -0
  236. package/src/services/editor/index.ts +13 -0
  237. package/src/setupTests.ts +47 -0
  238. package/src/styles/global.css +782 -0
  239. package/src/types/backup.ts +132 -0
  240. package/src/types/dictionary.ts +125 -0
  241. package/src/types/document-processing.ts +331 -0
  242. package/src/types/docxmlater-augments.d.ts +142 -0
  243. package/src/types/editor.ts +280 -0
  244. package/src/types/electron.ts +340 -0
  245. package/src/types/globalStats.ts +155 -0
  246. package/src/types/hyperlink.ts +471 -0
  247. package/src/types/operations.ts +354 -0
  248. package/src/types/session.ts +427 -0
  249. package/src/types/settings.ts +112 -0
  250. package/src/utils/MemoryMonitor.ts +248 -0
  251. package/src/utils/cn.ts +6 -0
  252. package/src/utils/colorConvert.ts +306 -0
  253. package/src/utils/diffUtils.ts +347 -0
  254. package/src/utils/documentUtils.ts +202 -0
  255. package/src/utils/electronGuard.ts +62 -0
  256. package/src/utils/indexedDB.ts +915 -0
  257. package/src/utils/logger.ts +717 -0
  258. package/src/utils/pathSecurity.ts +232 -0
  259. package/src/utils/pathValidator.ts +236 -0
  260. package/src/utils/processingTimeEstimator.ts +153 -0
  261. package/src/utils/safeJsonParse.ts +62 -0
  262. package/src/utils/textSanitizer.ts +162 -0
  263. package/src/utils/urlHelpers.ts +304 -0
  264. package/src/utils/urlPatterns.ts +198 -0
  265. package/src/utils/urlSanitizer.ts +152 -0
  266. package/src/vite-env.d.ts +11 -0
  267. package/tsconfig.electron.json +19 -0
  268. package/tsconfig.json +36 -0
  269. package/tsconfig.node.json +12 -0
  270. package/typedoc.json +45 -0
  271. package/vite.config.ts +152 -0
@@ -0,0 +1,782 @@
1
+ /* Tailwind CSS v4 - Modern CSS-First Configuration */
2
+ @import 'tailwindcss';
3
+
4
+ /* Enable class-based dark mode */
5
+ @custom-variant dark (&:where(.dark, .dark *));
6
+
7
+ /* Base Theme Definition */
8
+ @theme {
9
+ /* Semantic Colors - Light Mode Defaults */
10
+ --color-background: hsl(0 0% 100%);
11
+ --color-foreground: hsl(240 10% 4%);
12
+ --color-card: hsl(0 0% 100%);
13
+ --color-card-foreground: hsl(240 10% 4%);
14
+ --color-popover: hsl(0 0% 100%);
15
+ --color-popover-foreground: hsl(240 10% 4%);
16
+ --color-primary: hsl(217 91% 60%);
17
+ --color-primary-foreground: hsl(210 40% 98%);
18
+ --color-secondary: hsl(210 40% 96%);
19
+ --color-secondary-foreground: hsl(222 47% 11%);
20
+ --color-muted: hsl(210 40% 96%);
21
+ --color-muted-foreground: hsl(215 16% 47%);
22
+ --color-accent: hsl(210 40% 96%);
23
+ --color-accent-foreground: hsl(222 47% 11%);
24
+ --color-destructive: hsl(0 84% 60%);
25
+ --color-destructive-foreground: hsl(210 40% 98%);
26
+ --color-border: hsl(214 32% 91%);
27
+ --color-input: hsl(214 32% 91%);
28
+ --color-ring: hsl(217 91% 60%);
29
+
30
+ /* Design Tokens */
31
+ --radius: 0.5rem;
32
+ --spacing-unit: 1;
33
+
34
+ /* Gradient Colors */
35
+ --gradient-from: hsl(217 91% 60%);
36
+ --gradient-to: hsl(258 90% 66%);
37
+
38
+ /* Custom Font Settings (defaults) */
39
+ --custom-font-size: 15px;
40
+ --custom-font-family: system-ui;
41
+ --custom-font-weight: 400;
42
+ --custom-font-style: normal;
43
+ --custom-letter-spacing: 0;
44
+ --custom-line-height: 1.5;
45
+ }
46
+
47
+ /* Theme Variants */
48
+ @layer base {
49
+ /* ========================================
50
+ DARK MODE
51
+ ======================================== */
52
+ .dark {
53
+ --color-background: hsl(240 10% 4%);
54
+ --color-foreground: hsl(0 0% 98%);
55
+ --color-card: hsl(240 10% 4%);
56
+ --color-card-foreground: hsl(0 0% 98%);
57
+ --color-popover: hsl(240 10% 4%);
58
+ --color-popover-foreground: hsl(0 0% 98%);
59
+ --color-primary: hsl(213 94% 68%);
60
+ --color-primary-foreground: hsl(210 40% 98%);
61
+ --color-secondary: hsl(240 5% 10%);
62
+ --color-secondary-foreground: hsl(0 0% 98%);
63
+ --color-muted: hsl(240 5% 10%);
64
+ --color-muted-foreground: hsl(240 5% 65%);
65
+ --color-accent: hsl(240 5% 10%);
66
+ --color-accent-foreground: hsl(0 0% 98%);
67
+ --color-destructive: hsl(0 63% 31%);
68
+ --color-destructive-foreground: hsl(0 0% 98%);
69
+ --color-border: hsl(240 5% 16%);
70
+ --color-input: hsl(240 5% 16%);
71
+ --color-ring: hsl(217 91% 60%);
72
+ }
73
+
74
+ /* ========================================
75
+ ACCENT THEMES
76
+ ======================================== */
77
+
78
+ /* Purple Accent */
79
+ [data-accent='purple'] {
80
+ --color-primary: hsl(270 91% 65%);
81
+ --color-ring: hsl(270 91% 65%);
82
+ --gradient-from: hsl(270 91% 65%);
83
+ --gradient-to: hsl(270 91% 57%);
84
+ }
85
+
86
+ [data-accent='purple'].dark {
87
+ --color-primary: hsl(270 91% 76%);
88
+ --color-primary-foreground: hsl(0 0% 98%);
89
+ --color-ring: hsl(270 91% 65%);
90
+ }
91
+
92
+ /* Green Accent */
93
+ [data-accent='green'] {
94
+ --color-primary: hsl(142 71% 45%);
95
+ --color-ring: hsl(142 71% 45%);
96
+ --gradient-from: hsl(142 71% 45%);
97
+ --gradient-to: hsl(142 70% 37%);
98
+ }
99
+
100
+ [data-accent='green'].dark {
101
+ --color-primary: hsl(142 71% 65%);
102
+ --color-primary-foreground: hsl(0 0% 98%);
103
+ --color-ring: hsl(142 71% 45%);
104
+ }
105
+
106
+ /* Orange Accent */
107
+ [data-accent='orange'] {
108
+ --color-primary: hsl(25 95% 53%);
109
+ --color-ring: hsl(25 95% 53%);
110
+ --gradient-from: hsl(25 95% 53%);
111
+ --gradient-to: hsl(25 95% 48%);
112
+ }
113
+
114
+ [data-accent='orange'].dark {
115
+ --color-primary: hsl(25 95% 61%);
116
+ --color-primary-foreground: hsl(0 0% 98%);
117
+ --color-ring: hsl(25 95% 53%);
118
+ }
119
+
120
+ /* Pink Accent */
121
+ [data-accent='pink'] {
122
+ --color-primary: hsl(330 81% 60%);
123
+ --color-ring: hsl(330 81% 60%);
124
+ --gradient-from: hsl(330 81% 60%);
125
+ --gradient-to: hsl(330 81% 50%);
126
+ }
127
+
128
+ [data-accent='pink'].dark {
129
+ --color-primary: hsl(330 81% 70%);
130
+ --color-primary-foreground: hsl(0 0% 98%);
131
+ --color-ring: hsl(330 81% 60%);
132
+ }
133
+
134
+ /* Cyan Accent */
135
+ [data-accent='cyan'] {
136
+ --color-primary: hsl(189 94% 43%);
137
+ --color-ring: hsl(189 94% 43%);
138
+ --gradient-from: hsl(189 94% 43%);
139
+ --gradient-to: hsl(189 94% 37%);
140
+ }
141
+
142
+ [data-accent='cyan'].dark {
143
+ --color-primary: hsl(189 94% 53%);
144
+ --color-primary-foreground: hsl(0 0% 98%);
145
+ --color-ring: hsl(189 94% 43%);
146
+ }
147
+
148
+ /* Indigo Accent */
149
+ [data-accent='indigo'] {
150
+ --color-primary: hsl(239 84% 67%);
151
+ --color-ring: hsl(239 84% 67%);
152
+ --gradient-from: hsl(239 84% 67%);
153
+ --gradient-to: hsl(239 84% 59%);
154
+ }
155
+
156
+ [data-accent='indigo'].dark {
157
+ --color-primary: hsl(239 84% 75%);
158
+ --color-primary-foreground: hsl(0 0% 98%);
159
+ --color-ring: hsl(239 84% 67%);
160
+ }
161
+
162
+ /* Custom Accent (user-defined) */
163
+ [data-accent='custom'] {
164
+ --color-primary: hsl(var(--custom-accent));
165
+ --color-ring: hsl(var(--custom-accent));
166
+ --gradient-from: hsl(var(--custom-accent));
167
+ --gradient-to: hsl(var(--custom-accent));
168
+ }
169
+
170
+ [data-accent='custom'].dark {
171
+ --color-primary: hsl(var(--custom-accent));
172
+ --color-primary-foreground: hsl(0 0% 98%);
173
+ --color-ring: hsl(var(--custom-accent));
174
+ }
175
+
176
+ /* ========================================
177
+ CUSTOM COLORS OVERRIDE
178
+ ======================================== */
179
+ [data-custom-colors='true'] {
180
+ --color-primary: hsl(var(--custom-primary)) !important;
181
+ --color-background: hsl(var(--custom-background)) !important;
182
+ --color-foreground: hsl(
183
+ var(--custom-foreground)
184
+ ) !important; /* Auto-calculated based on luminance */
185
+ --color-border: hsl(var(--custom-border)) !important;
186
+ --color-card: hsl(var(--custom-background)) !important;
187
+ --color-card-foreground: hsl(var(--custom-foreground)) !important;
188
+ --color-popover: hsl(var(--custom-background)) !important;
189
+ --color-popover-foreground: hsl(var(--custom-foreground)) !important;
190
+ --color-muted-foreground: hsl(var(--custom-secondary-font)) !important;
191
+ --color-secondary-foreground: hsl(var(--custom-secondary-font)) !important;
192
+
193
+ /* Adaptive hover state colors - ensures readability with any custom color scheme */
194
+ --color-accent: color-mix(
195
+ in srgb,
196
+ hsl(var(--custom-foreground)) 12%,
197
+ hsl(var(--custom-background))
198
+ ) !important;
199
+ --color-accent-foreground: hsl(var(--custom-foreground)) !important;
200
+ --color-muted: color-mix(
201
+ in srgb,
202
+ hsl(var(--custom-foreground)) 8%,
203
+ hsl(var(--custom-background))
204
+ ) !important;
205
+ --color-secondary: color-mix(
206
+ in srgb,
207
+ hsl(var(--custom-foreground)) 6%,
208
+ hsl(var(--custom-background))
209
+ ) !important;
210
+ }
211
+
212
+ /* Custom header with auto-calculated text color */
213
+ [data-custom-colors='true'] .header-bg {
214
+ background-color: hsl(var(--custom-header)) !important;
215
+ color: hsl(var(--custom-header-text)) !important; /* Auto-calculated for contrast */
216
+ }
217
+
218
+ /* Force all text elements in header to use the auto-calculated header text color */
219
+ [data-custom-colors='true'] .header-bg *,
220
+ [data-custom-colors='true'] .header-bg button,
221
+ [data-custom-colors='true'] .header-bg span,
222
+ [data-custom-colors='true'] .header-bg p {
223
+ color: hsl(var(--custom-header-text)) !important;
224
+ }
225
+
226
+ /* Icons inherit text color */
227
+ [data-custom-colors='true'] .header-bg svg {
228
+ color: inherit !important;
229
+ }
230
+
231
+ /* Subtle variation for secondary text (descriptions, muted elements) */
232
+ [data-custom-colors='true'] .header-bg .text-muted-foreground {
233
+ opacity: 0.7;
234
+ }
235
+
236
+ /* Clock widget background adapts to custom header color */
237
+ [data-custom-colors='true'] .header-bg .clock-widget {
238
+ background-color: color-mix(
239
+ in srgb,
240
+ hsl(var(--custom-header)) 85%,
241
+ hsl(var(--custom-header-text)) 15%
242
+ ) !important;
243
+ }
244
+
245
+ /* Custom sidebar with auto-calculated text color */
246
+ [data-custom-colors='true'] .sidebar-bg {
247
+ background-color: hsl(var(--custom-sidebar)) !important;
248
+ color: hsl(var(--custom-sidebar-text)) !important; /* Auto-calculated for contrast */
249
+ }
250
+
251
+ /* Force base text elements in sidebar to use the auto-calculated sidebar text color */
252
+ [data-custom-colors='true']
253
+ .sidebar-bg
254
+ span:not(.text-primary-foreground):not(.text-accent-foreground),
255
+ [data-custom-colors='true']
256
+ .sidebar-bg
257
+ svg:not(.text-primary):not([class*='group-hover:text-primary']) {
258
+ color: hsl(var(--custom-sidebar-text)) !important;
259
+ }
260
+
261
+ /* Sidebar hover states - adaptive background with proper contrast */
262
+ [data-custom-colors='true'] .sidebar-bg [class*='hover:bg-accent']:hover {
263
+ background-color: color-mix(
264
+ in srgb,
265
+ hsl(var(--custom-sidebar-text)) 12%,
266
+ hsl(var(--custom-sidebar))
267
+ ) !important;
268
+ }
269
+
270
+ [data-custom-colors='true'] .sidebar-bg [class*='hover:text-accent-foreground']:hover {
271
+ color: hsl(var(--custom-sidebar-text)) !important;
272
+ }
273
+
274
+ /* Let active states keep their semantic colors - ensure all text is visible */
275
+ /* Doubled attribute selector bumps specificity to (0,5,1), beating the span:not() rule above at (0,4,1) */
276
+ [data-custom-colors='true'][data-custom-colors='true'] .sidebar-bg .bg-primary span,
277
+ [data-custom-colors='true'][data-custom-colors='true'] .sidebar-bg .bg-primary div,
278
+ [data-custom-colors='true'][data-custom-colors='true'] .sidebar-bg .bg-primary div span,
279
+ [data-custom-colors='true'][data-custom-colors='true'] .sidebar-bg .bg-primary button,
280
+ [data-custom-colors='true'][data-custom-colors='true'] .sidebar-bg button.bg-primary,
281
+ [data-custom-colors='true'][data-custom-colors='true'] .sidebar-bg button.bg-primary span,
282
+ [data-custom-colors='true'][data-custom-colors='true'] .sidebar-bg button.bg-primary div,
283
+ [data-custom-colors='true'][data-custom-colors='true'] .sidebar-bg button.bg-primary svg {
284
+ color: hsl(var(--custom-primary-text)) !important;
285
+ }
286
+
287
+ /* SVG stroke override for Lucide icons inside active sidebar items */
288
+ [data-custom-colors='true'][data-custom-colors='true'] .sidebar-bg .bg-primary svg,
289
+ [data-custom-colors='true'][data-custom-colors='true'] .sidebar-bg .bg-primary svg *,
290
+ [data-custom-colors='true'][data-custom-colors='true'] .sidebar-bg button.bg-primary svg,
291
+ [data-custom-colors='true'][data-custom-colors='true'] .sidebar-bg button.bg-primary svg * {
292
+ color: hsl(var(--custom-primary-text)) !important;
293
+ stroke: hsl(var(--custom-primary-text)) !important;
294
+ }
295
+
296
+ /* Apply subtle secondary text color to muted elements */
297
+ [data-custom-colors='true'] .text-muted-foreground {
298
+ color: hsl(var(--custom-secondary-font)) !important;
299
+ }
300
+
301
+ /* Checkbox/toggle with auto-calculated colors for custom theme */
302
+ [data-custom-colors='true'] .checkbox-checked,
303
+ [data-custom-colors='true'] .toggle-checked {
304
+ background-color: hsl(var(--custom-primary)) !important;
305
+ border-color: hsl(var(--custom-primary)) !important;
306
+ }
307
+
308
+ /* Checkmark icon color based on primary color luminance */
309
+ [data-custom-colors='true'] .checkbox-checkmark {
310
+ color: hsl(var(--custom-primary-text)) !important;
311
+ }
312
+
313
+ /* ========================================
314
+ PRIMARY ELEMENT TEXT COLOR (LUMINANCE-BASED)
315
+ ======================================== */
316
+ /* Override primary-foreground color to use luminance-calculated text color */
317
+ [data-custom-colors='true'] {
318
+ --color-primary-foreground: hsl(var(--custom-primary-text)) !important;
319
+ }
320
+
321
+ /* Ensure all text on primary-colored elements uses the calculated color */
322
+ [data-custom-colors='true'] .bg-primary,
323
+ [data-custom-colors='true'] .bg-primary *,
324
+ [data-custom-colors='true'] button.bg-primary,
325
+ [data-custom-colors='true'] button.bg-primary *,
326
+ [data-custom-colors='true'] a.bg-primary,
327
+ [data-custom-colors='true'] a.bg-primary *,
328
+ [data-custom-colors='true'] div.bg-primary,
329
+ [data-custom-colors='true'] div.bg-primary * {
330
+ color: hsl(var(--custom-primary-text)) !important;
331
+ }
332
+
333
+ /* SVG icons within primary backgrounds - force color inheritance */
334
+ [data-custom-colors='true'] .bg-primary svg,
335
+ [data-custom-colors='true'] button.bg-primary svg,
336
+ [data-custom-colors='true'] a.bg-primary svg,
337
+ [data-custom-colors='true'] div.bg-primary svg {
338
+ color: hsl(var(--custom-primary-text)) !important;
339
+ --svg-color: hsl(var(--custom-primary-text)) !important;
340
+ }
341
+
342
+ /* Force SVG stroke color for Lucide icons (which use stroke, not fill) */
343
+ [data-custom-colors='true'] .bg-primary svg,
344
+ [data-custom-colors='true'] .bg-primary svg *,
345
+ [data-custom-colors='true'] button.bg-primary svg,
346
+ [data-custom-colors='true'] button.bg-primary svg * {
347
+ stroke: hsl(var(--custom-primary-text)) !important;
348
+ }
349
+
350
+ /* Text elements explicitly marked as primary-foreground */
351
+ [data-custom-colors='true'] .text-primary-foreground,
352
+ [data-custom-colors='true'] .text-primary-foreground * {
353
+ color: hsl(var(--custom-primary-text)) !important;
354
+ }
355
+
356
+ /* Ensure text-primary-foreground SVG icons also adapt */
357
+ [data-custom-colors='true'] .text-primary-foreground svg,
358
+ [data-custom-colors='true'] .text-primary-foreground svg * {
359
+ color: hsl(var(--custom-primary-text)) !important;
360
+ stroke: hsl(var(--custom-primary-text)) !important;
361
+ }
362
+
363
+ /* ========================================
364
+ READABLE PRIMARY ACCENT COLOR
365
+ ======================================== */
366
+ /* Override standalone text-primary (accent text/icons on page background) to use
367
+ the readable version that guarantees 3:1 contrast against the background.
368
+ This does NOT affect bg-primary (backgrounds keep the user's chosen color).
369
+ --custom-primary-readable is auto-calculated in ThemeContext. */
370
+ [data-custom-colors='true'] .text-primary {
371
+ color: hsl(var(--custom-primary-readable)) !important;
372
+ }
373
+
374
+ [data-custom-colors='true'] .text-primary svg,
375
+ [data-custom-colors='true'] svg.text-primary {
376
+ color: hsl(var(--custom-primary-readable)) !important;
377
+ stroke: hsl(var(--custom-primary-readable)) !important;
378
+ }
379
+
380
+ /* ========================================
381
+ TOGGLE BUTTON STYLING
382
+ ======================================== */
383
+ /* Toggle track borders for clear definition (following Radix UI, shadcn/ui patterns) */
384
+ button[role='switch'],
385
+ button[aria-label*='Toggle'],
386
+ button.toggle-checked,
387
+ .toggle-checked {
388
+ border: 2px solid var(--color-border);
389
+ }
390
+
391
+ /* Toggle track - On state gets primary border */
392
+ .toggle-checked,
393
+ button.toggle-checked,
394
+ button[role='switch'][aria-checked='true'] {
395
+ border-color: hsl(var(--color-primary));
396
+ }
397
+
398
+ /* Custom colors: toggle borders adapt with proper contrast */
399
+ [data-custom-colors='true'] button[role='switch'],
400
+ [data-custom-colors='true'] button[aria-label*='Toggle'] {
401
+ border: 2px solid color-mix(in srgb, hsl(var(--custom-foreground)) 50%, transparent) !important;
402
+ }
403
+
404
+ [data-custom-colors='true'] .toggle-checked,
405
+ [data-custom-colors='true'] button[aria-label*='Toggle'].toggle-checked,
406
+ [data-custom-colors='true'] button[role='switch'][aria-checked='true'] {
407
+ border: 2px solid hsl(var(--custom-primary)) !important;
408
+ }
409
+
410
+ /* Toggle knob - subtle border for definition against track (catches both span and motion.span) */
411
+ /* Fixed vertical alignment: top-0 for perfect centering (track is 24px, border 4px, knob 20px) */
412
+ button[role='switch'] > span,
413
+ button[aria-label*='Toggle'] > span {
414
+ top: 0 !important;
415
+ border: 1px solid rgba(0, 0, 0, 0.1) !important;
416
+ box-shadow:
417
+ 0 1px 3px rgba(0, 0, 0, 0.12),
418
+ 0 1px 2px rgba(0, 0, 0, 0.08) !important;
419
+ }
420
+
421
+ /* Dark mode: lighter knob border */
422
+ .dark button[role='switch'] > span,
423
+ .dark button[aria-label*='Toggle'] > span {
424
+ border-color: rgba(255, 255, 255, 0.15) !important;
425
+ box-shadow:
426
+ 0 1px 3px rgba(0, 0, 0, 0.3),
427
+ 0 1px 2px rgba(0, 0, 0, 0.24) !important;
428
+ }
429
+
430
+ /* ========================================
431
+ DENSITY MODES
432
+ ======================================== */
433
+ [data-density='minimal'] {
434
+ --spacing-unit: 0.5;
435
+ --content-max-width: 100%;
436
+ font-size: 13px;
437
+ }
438
+
439
+ [data-density='compact'] {
440
+ --spacing-unit: 0.75;
441
+ --content-max-width: 100%;
442
+ font-size: 14px;
443
+ }
444
+
445
+ [data-density='comfortable'] {
446
+ --spacing-unit: 1;
447
+ --content-max-width: 100%;
448
+ font-size: 15px;
449
+ }
450
+
451
+ /* Apply density to common elements */
452
+ [data-density] .p-2 {
453
+ padding: calc(0.5rem * var(--spacing-unit));
454
+ }
455
+
456
+ [data-density] .p-3 {
457
+ padding: calc(0.75rem * var(--spacing-unit));
458
+ }
459
+
460
+ [data-density] .p-4 {
461
+ padding: calc(1rem * var(--spacing-unit));
462
+ }
463
+
464
+ [data-density] .p-6 {
465
+ padding: calc(1.5rem * var(--spacing-unit));
466
+ }
467
+
468
+ [data-density] .gap-2 {
469
+ gap: calc(0.5rem * var(--spacing-unit));
470
+ }
471
+
472
+ [data-density] .gap-3 {
473
+ gap: calc(0.75rem * var(--spacing-unit));
474
+ }
475
+
476
+ [data-density] .gap-4 {
477
+ gap: calc(1rem * var(--spacing-unit));
478
+ }
479
+
480
+ /* Fix layout issues in compact/minimal modes */
481
+ [data-density='compact'] main,
482
+ [data-density='minimal'] main {
483
+ max-width: var(--content-max-width);
484
+ width: 100%;
485
+ margin: 0;
486
+ }
487
+
488
+ /* Adjust sidebar spacing in density modes */
489
+ [data-density='minimal'] .sidebar-bg {
490
+ padding: calc(0.5rem * var(--spacing-unit));
491
+ }
492
+
493
+ [data-density='compact'] .sidebar-bg {
494
+ padding: calc(0.75rem * var(--spacing-unit));
495
+ }
496
+
497
+ /* Fix header spacing */
498
+ [data-density='minimal'] .header-bg,
499
+ [data-density='compact'] .header-bg {
500
+ padding-left: calc(1.5rem * var(--spacing-unit));
501
+ padding-right: calc(1.5rem * var(--spacing-unit));
502
+ }
503
+
504
+ /* Ensure proper content alignment */
505
+ [data-density] .max-w-7xl {
506
+ max-width: 100%;
507
+ }
508
+
509
+ [data-density='minimal'] .px-6,
510
+ [data-density='compact'] .px-6 {
511
+ padding-left: calc(1.5rem * var(--spacing-unit));
512
+ padding-right: calc(1.5rem * var(--spacing-unit));
513
+ }
514
+
515
+ /* ========================================
516
+ BASE STYLES
517
+ ======================================== */
518
+ * {
519
+ border-color: var(--color-border);
520
+ }
521
+
522
+ body {
523
+ background-color: var(--color-background);
524
+ color: var(--color-foreground);
525
+ font-feature-settings:
526
+ 'rlig' 1,
527
+ 'calt' 1;
528
+ -webkit-font-smoothing: antialiased;
529
+ -moz-osx-font-smoothing: grayscale;
530
+ font-size: var(--custom-font-size, 15px);
531
+ font-family: var(--custom-font-family, system-ui);
532
+ font-weight: var(--custom-font-weight, 400);
533
+ font-style: var(--custom-font-style, normal);
534
+ letter-spacing: var(--custom-letter-spacing, 0);
535
+ line-height: var(--custom-line-height, 1.5);
536
+ }
537
+
538
+ html {
539
+ scroll-behavior: smooth;
540
+ }
541
+
542
+ /* ========================================
543
+ ANIMATIONS & EFFECTS
544
+ ======================================== */
545
+
546
+ /* Disable animations */
547
+ .no-animations * {
548
+ animation: none !important;
549
+ transition: none !important;
550
+ }
551
+
552
+ /* Disable blur effects */
553
+ .no-blur .glass,
554
+ .no-blur .backdrop-blur-xl,
555
+ .no-blur .backdrop-blur-md {
556
+ backdrop-filter: none !important;
557
+ background: var(--color-background) !important;
558
+ }
559
+
560
+ /* Reduce motion - accessibility option */
561
+ .reduce-motion *,
562
+ .reduce-motion *::before,
563
+ .reduce-motion *::after {
564
+ animation-duration: 0.01ms !important;
565
+ animation-iteration-count: 1 !important;
566
+ transition-duration: 0.01ms !important;
567
+ scroll-behavior: auto !important;
568
+ }
569
+
570
+ /* Also respect system preference for reduced motion */
571
+ @media (prefers-reduced-motion: reduce) {
572
+ *,
573
+ *::before,
574
+ *::after {
575
+ animation-duration: 0.01ms !important;
576
+ animation-iteration-count: 1 !important;
577
+ transition-duration: 0.01ms !important;
578
+ scroll-behavior: auto !important;
579
+ }
580
+ }
581
+
582
+ /* Scrollbar Styling */
583
+ ::-webkit-scrollbar {
584
+ width: 10px;
585
+ height: 10px;
586
+ }
587
+
588
+ ::-webkit-scrollbar-track {
589
+ background-color: var(--color-muted);
590
+ }
591
+
592
+ ::-webkit-scrollbar-thumb {
593
+ background-color: color-mix(in srgb, var(--color-muted-foreground) 20%, transparent);
594
+ border-radius: 0.375rem;
595
+ transition: background-color 0.2s;
596
+ }
597
+
598
+ ::-webkit-scrollbar-thumb:hover {
599
+ background-color: color-mix(in srgb, var(--color-muted-foreground) 30%, transparent);
600
+ }
601
+
602
+ /* Custom theme scrollbar colors */
603
+ [data-custom-colors='true'] ::-webkit-scrollbar-track {
604
+ background-color: color-mix(
605
+ in srgb,
606
+ hsl(var(--custom-background)) 90%,
607
+ hsl(var(--custom-foreground)) 10%
608
+ );
609
+ }
610
+
611
+ [data-custom-colors='true'] ::-webkit-scrollbar-thumb {
612
+ background-color: color-mix(in srgb, hsl(var(--custom-foreground)) 20%, transparent);
613
+ }
614
+
615
+ [data-custom-colors='true'] ::-webkit-scrollbar-thumb:hover {
616
+ background-color: color-mix(in srgb, hsl(var(--custom-foreground)) 30%, transparent);
617
+ }
618
+
619
+ /* Selection */
620
+ ::selection {
621
+ background-color: color-mix(in srgb, var(--color-primary) 20%, transparent);
622
+ color: var(--color-primary-foreground);
623
+ }
624
+
625
+ /* Electron Window Controls */
626
+ .drag-region {
627
+ -webkit-app-region: drag;
628
+ }
629
+
630
+ .no-drag {
631
+ -webkit-app-region: no-drag;
632
+ }
633
+
634
+ /* Hide Search Cancel Button */
635
+ input[type='search']::-webkit-search-cancel-button {
636
+ display: none;
637
+ }
638
+
639
+ /* Skeleton Loading Animation */
640
+ @keyframes shimmer {
641
+ 0% {
642
+ transform: translateX(-100%);
643
+ }
644
+ 100% {
645
+ transform: translateX(100%);
646
+ }
647
+ }
648
+
649
+ .skeleton {
650
+ position: relative;
651
+ overflow: hidden;
652
+ background-color: var(--color-muted);
653
+ }
654
+
655
+ .skeleton::after {
656
+ content: '';
657
+ position: absolute;
658
+ inset: 0;
659
+ transform: translateX(-100%);
660
+ background: linear-gradient(
661
+ 90deg,
662
+ transparent,
663
+ color-mix(in srgb, var(--color-muted-foreground) 8%, transparent),
664
+ transparent
665
+ );
666
+ animation: shimmer 1.5s infinite;
667
+ }
668
+
669
+ /* ========================================
670
+ GLASS MORPHISM EFFECTS
671
+ ======================================== */
672
+ .glass {
673
+ background-color: color-mix(in srgb, var(--color-background) 60%, transparent);
674
+ -webkit-backdrop-filter: blur(12px);
675
+ backdrop-filter: blur(12px);
676
+ }
677
+
678
+ .glass-heavy {
679
+ background-color: color-mix(in srgb, var(--color-background) 30%, transparent);
680
+ -webkit-backdrop-filter: blur(24px);
681
+ backdrop-filter: blur(24px);
682
+ background-image: linear-gradient(
683
+ to bottom right,
684
+ rgba(255, 255, 255, 0.1),
685
+ rgba(255, 255, 255, 0.05)
686
+ );
687
+ }
688
+
689
+ .glass-light {
690
+ background-color: color-mix(in srgb, var(--color-background) 80%, transparent);
691
+ -webkit-backdrop-filter: blur(4px);
692
+ backdrop-filter: blur(4px);
693
+ }
694
+
695
+ @supports not (backdrop-filter: blur(10px)) {
696
+ .glass,
697
+ .glass-heavy,
698
+ .glass-light {
699
+ background-color: color-mix(in srgb, var(--color-background) 95%, transparent);
700
+ }
701
+ }
702
+
703
+ /* ========================================
704
+ DARK MODE SPECIFIC EFFECTS
705
+ ======================================== */
706
+ .dark .glow {
707
+ filter: drop-shadow(0 0 20px rgba(59, 130, 246, 0.5));
708
+ }
709
+
710
+ .dark .glow-primary {
711
+ filter: drop-shadow(0 0 20px color-mix(in srgb, var(--color-primary) 50%, transparent));
712
+ }
713
+
714
+ /* ========================================
715
+ INTERACTIVE EFFECTS
716
+ ======================================== */
717
+ .interactive-hover {
718
+ position: relative;
719
+ overflow: hidden;
720
+ }
721
+
722
+ .interactive-hover::before {
723
+ content: '';
724
+ position: absolute;
725
+ top: var(--mouse-y, 50%);
726
+ left: var(--mouse-x, 50%);
727
+ transform: translate(-50%, -50%);
728
+ width: 0;
729
+ height: 0;
730
+ border-radius: 50%;
731
+ background: radial-gradient(circle, rgba(255, 255, 255, 0.1), transparent 70%);
732
+ transition:
733
+ width 0.3s,
734
+ height 0.3s;
735
+ pointer-events: none;
736
+ }
737
+
738
+ .interactive-hover:hover::before {
739
+ width: 200%;
740
+ height: 200%;
741
+ }
742
+
743
+ /* Bento Grid Item */
744
+ .bento-item {
745
+ border-radius: 0.5rem;
746
+ border: 1px solid var(--color-border);
747
+ padding: 1rem;
748
+ transition: all 0.15s cubic-bezier(0.4, 0, 0.2, 1);
749
+ }
750
+
751
+ .bento-item:hover {
752
+ box-shadow:
753
+ 0 10px 15px -3px rgba(0, 0, 0, 0.1),
754
+ 0 4px 6px -4px rgba(0, 0, 0, 0.1);
755
+ }
756
+
757
+ /* Bento Grid Layout */
758
+ .bento-grid {
759
+ display: grid;
760
+ gap: 1rem;
761
+ grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
762
+ }
763
+
764
+ /* Progressive Blur */
765
+ .progressive-blur {
766
+ mask-image: linear-gradient(to bottom, black 60%, transparent);
767
+ }
768
+ }
769
+
770
+ /* ========================================
771
+ UTILITY CLASSES
772
+ ======================================== */
773
+
774
+ /* Scrollbar Hide Utility */
775
+ .scrollbar-hide {
776
+ -ms-overflow-style: none; /* IE and Edge */
777
+ scrollbar-width: none; /* Firefox */
778
+ }
779
+
780
+ .scrollbar-hide::-webkit-scrollbar {
781
+ display: none; /* Chrome, Safari, Opera */
782
+ }