@eventcatalog/core 3.0.0 → 3.2.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.
Files changed (109) hide show
  1. package/dist/analytics/analytics.cjs +1 -1
  2. package/dist/analytics/analytics.js +2 -2
  3. package/dist/analytics/log-build.cjs +1 -1
  4. package/dist/analytics/log-build.js +3 -3
  5. package/dist/{chunk-VO5WYA44.js → chunk-AA47DJ43.js} +1 -1
  6. package/dist/{chunk-EKGR533N.js → chunk-GGRXP5WM.js} +1 -1
  7. package/dist/{chunk-E5Q7TZYT.js → chunk-L3QRQT7U.js} +1 -1
  8. package/dist/{chunk-BYP43AAT.js → chunk-RWYEP5SD.js} +1 -1
  9. package/dist/{chunk-KF5PARQK.js → chunk-VPQCMMRM.js} +1 -1
  10. package/dist/constants.cjs +1 -1
  11. package/dist/constants.js +1 -1
  12. package/dist/eventcatalog.cjs +1 -1
  13. package/dist/eventcatalog.config.d.cts +7 -0
  14. package/dist/eventcatalog.config.d.ts +7 -0
  15. package/dist/eventcatalog.js +5 -5
  16. package/dist/generate.cjs +1 -1
  17. package/dist/generate.js +3 -3
  18. package/dist/utils/cli-logger.cjs +1 -1
  19. package/dist/utils/cli-logger.js +2 -2
  20. package/eventcatalog/src/components/ChatPanel/ChatPanel.tsx +520 -247
  21. package/eventcatalog/src/components/ChatPanel/ChatPanelButton.tsx +3 -3
  22. package/eventcatalog/src/components/Checkbox.astro +7 -4
  23. package/eventcatalog/src/components/CopyAsMarkdown.tsx +15 -15
  24. package/eventcatalog/src/components/EnvironmentDropdown.tsx +15 -7
  25. package/eventcatalog/src/components/FavoriteButton.tsx +1 -1
  26. package/eventcatalog/src/components/Grids/DomainGrid.tsx +72 -60
  27. package/eventcatalog/src/components/Grids/MessageGrid.tsx +68 -48
  28. package/eventcatalog/src/components/Header.astro +15 -10
  29. package/eventcatalog/src/components/Lists/OwnersList.tsx +17 -10
  30. package/eventcatalog/src/components/Lists/PillListFlat.styles.css +12 -0
  31. package/eventcatalog/src/components/Lists/PillListFlat.tsx +15 -15
  32. package/eventcatalog/src/components/Lists/VersionList.astro +15 -5
  33. package/eventcatalog/src/components/MDX/Accordion/Accordion.tsx +3 -3
  34. package/eventcatalog/src/components/MDX/Admonition.tsx +49 -9
  35. package/eventcatalog/src/components/MDX/Attachments.astro +15 -11
  36. package/eventcatalog/src/components/MDX/ChannelInformation/ChannelInformation.tsx +29 -15
  37. package/eventcatalog/src/components/MDX/EntityPropertiesTable/EntityPropertiesTable.astro +20 -13
  38. package/eventcatalog/src/components/MDX/Link/Link.astro +1 -1
  39. package/eventcatalog/src/components/MDX/MessageTable/MessageTable.client.tsx +50 -29
  40. package/eventcatalog/src/components/MDX/NodeGraph/NodeGraph.tsx +14 -12
  41. package/eventcatalog/src/components/MDX/NodeGraph/StepWalkthrough.tsx +4 -4
  42. package/eventcatalog/src/components/MDX/NodeGraph/StudioModal.tsx +4 -4
  43. package/eventcatalog/src/components/MDX/NodeGraph/VisualiserSearch.tsx +2 -2
  44. package/eventcatalog/src/components/MDX/ResourceGroupTable/ResourceGroupTable.client.tsx +54 -33
  45. package/eventcatalog/src/components/MDX/ResourceLink/ResourceLink.astro +1 -1
  46. package/eventcatalog/src/components/MDX/Steps/Step.astro +2 -2
  47. package/eventcatalog/src/components/MDX/Steps/Steps.astro +3 -3
  48. package/eventcatalog/src/components/MDX/Tabs/Tabs.astro +13 -9
  49. package/eventcatalog/src/components/MDX/Tiles/Tile.astro +25 -13
  50. package/eventcatalog/src/components/MDX/Tiles/Tiles.astro +1 -1
  51. package/eventcatalog/src/components/SchemaExplorer/ApiAccessSection.tsx +3 -3
  52. package/eventcatalog/src/components/SchemaExplorer/ApiContentViewer.tsx +3 -3
  53. package/eventcatalog/src/components/SchemaExplorer/AvroSchemaViewer.tsx +29 -25
  54. package/eventcatalog/src/components/SchemaExplorer/DiffViewer.tsx +3 -3
  55. package/eventcatalog/src/components/SchemaExplorer/JSONSchemaViewer.tsx +61 -42
  56. package/eventcatalog/src/components/SchemaExplorer/OwnersSection.tsx +13 -9
  57. package/eventcatalog/src/components/SchemaExplorer/Pagination.tsx +6 -4
  58. package/eventcatalog/src/components/SchemaExplorer/ProducersConsumersSection.tsx +17 -13
  59. package/eventcatalog/src/components/SchemaExplorer/SchemaContentViewer.tsx +35 -8
  60. package/eventcatalog/src/components/SchemaExplorer/SchemaDetailsHeader.tsx +33 -21
  61. package/eventcatalog/src/components/SchemaExplorer/SchemaDetailsPanel.tsx +1 -1
  62. package/eventcatalog/src/components/SchemaExplorer/SchemaExplorer.tsx +41 -33
  63. package/eventcatalog/src/components/SchemaExplorer/SchemaListItem.tsx +19 -7
  64. package/eventcatalog/src/components/SchemaExplorer/SchemaViewerModal.tsx +8 -8
  65. package/eventcatalog/src/components/Search/Search.astro +3 -3
  66. package/eventcatalog/src/components/Search/SearchModal.tsx +65 -36
  67. package/eventcatalog/src/components/SideNav/NestedSideBar/SearchBar.tsx +31 -21
  68. package/eventcatalog/src/components/SideNav/NestedSideBar/index.tsx +92 -59
  69. package/eventcatalog/src/components/Tables/Table.tsx +25 -24
  70. package/eventcatalog/src/components/Tables/columns/ContainersTableColumns.tsx +22 -16
  71. package/eventcatalog/src/components/Tables/columns/DomainTableColumns.tsx +14 -11
  72. package/eventcatalog/src/components/Tables/columns/FlowTableColumns.tsx +6 -6
  73. package/eventcatalog/src/components/Tables/columns/MessageTableColumns.tsx +22 -16
  74. package/eventcatalog/src/components/Tables/columns/ServiceTableColumns.tsx +22 -16
  75. package/eventcatalog/src/components/Tables/columns/SharedColumns.tsx +4 -4
  76. package/eventcatalog/src/components/Tables/columns/TeamsTableColumns.tsx +21 -13
  77. package/eventcatalog/src/components/Tables/columns/UserTableColumns.tsx +30 -19
  78. package/eventcatalog/src/components/ThemeToggle.tsx +18 -0
  79. package/eventcatalog/src/enterprise/ai/chat-api.ts +24 -3
  80. package/eventcatalog/src/enterprise/custom-documentation/components/CustomDocsNav/components/NestedItem.tsx +15 -7
  81. package/eventcatalog/src/enterprise/custom-documentation/components/CustomDocsNav/components/NoResultsFound.tsx +2 -2
  82. package/eventcatalog/src/enterprise/custom-documentation/components/CustomDocsNav/index.tsx +19 -15
  83. package/eventcatalog/src/enterprise/custom-documentation/pages/docs/custom/index.astro +50 -17
  84. package/eventcatalog/src/layouts/DirectoryLayout.astro +11 -6
  85. package/eventcatalog/src/layouts/DiscoverLayout.astro +13 -8
  86. package/eventcatalog/src/layouts/Footer.astro +6 -6
  87. package/eventcatalog/src/layouts/VerticalSideBarLayout.astro +62 -14
  88. package/eventcatalog/src/pages/_index.astro +135 -179
  89. package/eventcatalog/src/pages/architecture/[type]/[id]/[version]/index.astro +2 -2
  90. package/eventcatalog/src/pages/docs/[type]/[id]/[version]/graphql/[filename].astro +4 -4
  91. package/eventcatalog/src/pages/docs/[type]/[id]/[version]/index.astro +77 -63
  92. package/eventcatalog/src/pages/docs/[type]/[id]/language/[dictionaryId]/index.astro +23 -24
  93. package/eventcatalog/src/pages/docs/[type]/[id]/language/index.astro +66 -50
  94. package/eventcatalog/src/pages/docs/custom/index.astro +2 -2
  95. package/eventcatalog/src/pages/docs/teams/[id]/index.astro +25 -21
  96. package/eventcatalog/src/pages/docs/users/[id]/index.astro +25 -21
  97. package/eventcatalog/src/pages/schemas/explorer/index.astro +1 -1
  98. package/eventcatalog/src/pages/studio.astro +59 -31
  99. package/eventcatalog/src/remark-plugins/directives.ts +6 -6
  100. package/eventcatalog/src/remark-plugins/mermaid.ts +2 -2
  101. package/eventcatalog/src/stores/theme-store.ts +93 -0
  102. package/eventcatalog/src/styles/theme.css +255 -0
  103. package/eventcatalog/src/styles/themes/forest.css +230 -0
  104. package/eventcatalog/src/styles/themes/ocean.css +235 -0
  105. package/eventcatalog/src/styles/themes/sapphire.css +230 -0
  106. package/eventcatalog/src/styles/themes/sunset.css +230 -0
  107. package/eventcatalog/src/utils/feature.ts +4 -0
  108. package/eventcatalog/tailwind.config.mjs +6 -3
  109. package/package.json +7 -6
@@ -114,14 +114,14 @@ const AvroField = ({ field, level, expand, showRequired }: AvroFieldProps) => {
114
114
  }, [expand]);
115
115
 
116
116
  return (
117
- <div className={`avro-field-container mb-2 border-l border-gray-200 ${indentClass}`}>
117
+ <div className={`avro-field-container mb-2 border-l border-[rgb(var(--ec-page-border))] ${indentClass}`}>
118
118
  <div className="flex space-x-2">
119
119
  {/* Collapse/Expand button */}
120
120
  <div className="flex-shrink-0 w-4 pt-0.5">
121
121
  {hasNested ? (
122
122
  <button
123
123
  onClick={() => setIsExpanded(!isExpanded)}
124
- className="avro-field-toggle text-gray-500 hover:text-gray-700 w-4 text-center"
124
+ className="avro-field-toggle text-[rgb(var(--ec-page-text-muted))] hover:text-[rgb(var(--ec-page-text))] w-4 text-center"
125
125
  aria-expanded={isExpanded}
126
126
  >
127
127
  <span className="font-mono text-xs">{isExpanded ? '▼' : '▶'}</span>
@@ -132,19 +132,21 @@ const AvroField = ({ field, level, expand, showRequired }: AvroFieldProps) => {
132
132
  {/* Field details */}
133
133
  <div className="flex-grow min-w-0">
134
134
  <div className="flex flex-wrap items-baseline gap-x-1.5 gap-y-1">
135
- <span className="avro-field-name font-semibold text-gray-800 text-sm">{field.name}</span>
136
- <span className="text-purple-600 font-mono text-xs">{formatAvroType(field.type)}</span>
137
- {showRequired && isRequired && <span className="text-red-600 text-xs ml-auto flex-shrink-0">required</span>}
135
+ <span className="avro-field-name font-semibold text-[rgb(var(--ec-page-text))] text-sm">{field.name}</span>
136
+ <span className="text-[rgb(var(--ec-accent))] font-mono text-xs">{formatAvroType(field.type)}</span>
137
+ {showRequired && isRequired && (
138
+ <span className="text-red-600 dark:text-red-400 text-xs ml-auto flex-shrink-0">required</span>
139
+ )}
138
140
  </div>
139
141
 
140
- {field.doc && <p className="text-gray-600 text-xs mt-1">{field.doc}</p>}
142
+ {field.doc && <p className="text-[rgb(var(--ec-page-text-muted))] text-xs mt-1">{field.doc}</p>}
141
143
 
142
144
  {/* Show enum values if present */}
143
145
  {field.type?.type === 'enum' && field.type.symbols && (
144
- <div className="text-xs text-gray-500 mt-1">
146
+ <div className="text-xs text-[rgb(var(--ec-page-text-muted))] mt-1">
145
147
  Values:{' '}
146
148
  {field.type.symbols.map((s: string) => (
147
- <code key={s} className="bg-gray-100 px-1 rounded mx-0.5">
149
+ <code key={s} className="bg-[rgb(var(--ec-content-hover))] px-1 rounded mx-0.5 text-[rgb(var(--ec-page-text))]">
148
150
  {s}
149
151
  </code>
150
152
  ))}
@@ -303,7 +305,7 @@ export default function AvroSchemaViewer({
303
305
 
304
306
  if (!schema || schema.type !== 'record') {
305
307
  return (
306
- <div className="flex items-center justify-center p-8 text-gray-500">
308
+ <div className="flex items-center justify-center p-8 text-[rgb(var(--ec-page-text-muted))]">
307
309
  <p className="text-sm">Invalid Avro schema format</p>
308
310
  </div>
309
311
  );
@@ -318,12 +320,12 @@ export default function AvroSchemaViewer({
318
320
 
319
321
  return (
320
322
  <div
321
- className={`${heightClass} ${overflowClass} flex flex-col bg-white border border-gray-100 rounded-md shadow-sm`}
323
+ className={`${heightClass} ${overflowClass} flex flex-col bg-[rgb(var(--ec-card-bg,var(--ec-page-bg)))] border border-[rgb(var(--ec-page-border))] rounded-md shadow-sm`}
322
324
  style={containerStyle}
323
325
  >
324
326
  {/* Toolbar */}
325
327
  {searchBool && (
326
- <div className="flex-shrink-0 bg-white pt-4 px-4 pb-3 border-b border-gray-100 shadow-sm">
328
+ <div className="flex-shrink-0 bg-[rgb(var(--ec-card-bg,var(--ec-page-bg)))] pt-4 px-4 pb-3 border-b border-[rgb(var(--ec-page-border))] shadow-sm">
327
329
  <div className="flex flex-col sm:flex-row gap-3">
328
330
  <div className="flex-1 relative">
329
331
  <input
@@ -332,7 +334,7 @@ export default function AvroSchemaViewer({
332
334
  value={searchQuery}
333
335
  onChange={(e) => setSearchQuery(e.target.value)}
334
336
  placeholder="Search fields..."
335
- className="w-full px-3 py-1.5 pr-20 text-sm border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent"
337
+ className="w-full px-3 py-1.5 pr-20 text-sm border border-[rgb(var(--ec-input-border))] bg-[rgb(var(--ec-input-bg))] text-[rgb(var(--ec-input-text))] placeholder:text-[rgb(var(--ec-input-placeholder))] rounded-md focus:outline-none focus:ring-2 focus:ring-[rgb(var(--ec-accent))] focus:border-transparent"
336
338
  onKeyDown={(e) => {
337
339
  if (e.key === 'Enter') {
338
340
  e.preventDefault();
@@ -348,7 +350,7 @@ export default function AvroSchemaViewer({
348
350
  <button
349
351
  onClick={handlePrevMatch}
350
352
  disabled={currentMatches.length === 0 || currentMatchIndex <= 0}
351
- className="p-1 text-gray-400 hover:text-gray-600 disabled:opacity-30 disabled:cursor-not-allowed"
353
+ className="p-1 text-[rgb(var(--ec-icon-color))] hover:text-[rgb(var(--ec-page-text))] disabled:opacity-30 disabled:cursor-not-allowed"
352
354
  title="Previous match"
353
355
  >
354
356
  <svg className="w-3 h-3" fill="none" stroke="currentColor" viewBox="0 0 24 24">
@@ -358,7 +360,7 @@ export default function AvroSchemaViewer({
358
360
  <button
359
361
  onClick={handleNextMatch}
360
362
  disabled={currentMatches.length === 0 || currentMatchIndex >= currentMatches.length - 1}
361
- className="p-1 text-gray-400 hover:text-gray-600 disabled:opacity-30 disabled:cursor-not-allowed"
363
+ className="p-1 text-[rgb(var(--ec-icon-color))] hover:text-[rgb(var(--ec-page-text))] disabled:opacity-30 disabled:cursor-not-allowed"
362
364
  title="Next match"
363
365
  >
364
366
  <svg className="w-3 h-3" fill="none" stroke="currentColor" viewBox="0 0 24 24">
@@ -371,7 +373,7 @@ export default function AvroSchemaViewer({
371
373
  {onOpenFullscreen && (
372
374
  <button
373
375
  onClick={onOpenFullscreen}
374
- className="px-3 py-1.5 text-xs font-medium text-gray-700 bg-gray-100 rounded-md hover:bg-gray-200 focus:outline-none focus:ring-2 focus:ring-gray-500"
376
+ className="px-3 py-1.5 text-xs font-medium text-[rgb(var(--ec-page-text))] bg-[rgb(var(--ec-content-hover))] rounded-md hover:bg-[rgb(var(--ec-content-active))] focus:outline-none focus:ring-2 focus:ring-[rgb(var(--ec-accent))]"
375
377
  title="Open in fullscreen"
376
378
  >
377
379
  <svg
@@ -392,23 +394,23 @@ export default function AvroSchemaViewer({
392
394
  )}
393
395
  <button
394
396
  onClick={handleExpandAll}
395
- className="px-3 py-1.5 text-xs font-medium text-gray-700 bg-gray-100 rounded-md hover:bg-gray-200 focus:outline-none focus:ring-2 focus:ring-gray-500"
397
+ className="px-3 py-1.5 text-xs font-medium text-[rgb(var(--ec-page-text))] bg-[rgb(var(--ec-content-hover))] rounded-md hover:bg-[rgb(var(--ec-content-active))] focus:outline-none focus:ring-2 focus:ring-[rgb(var(--ec-accent))]"
396
398
  >
397
399
  Expand All
398
400
  </button>
399
401
  <button
400
402
  onClick={handleCollapseAll}
401
- className="px-3 py-1.5 text-xs font-medium text-gray-700 bg-gray-100 rounded-md hover:bg-gray-200 focus:outline-none focus:ring-2 focus:ring-gray-500"
403
+ className="px-3 py-1.5 text-xs font-medium text-[rgb(var(--ec-page-text))] bg-[rgb(var(--ec-content-hover))] rounded-md hover:bg-[rgb(var(--ec-content-active))] focus:outline-none focus:ring-2 focus:ring-[rgb(var(--ec-accent))]"
402
404
  >
403
405
  Collapse All
404
406
  </button>
405
- <div className="text-xs text-gray-500">
407
+ <div className="text-xs text-[rgb(var(--ec-page-text-muted))]">
406
408
  {totalFields} {totalFields === 1 ? 'field' : 'fields'}
407
409
  </div>
408
410
  </div>
409
411
  </div>
410
412
  {searchQuery && (
411
- <div className="mt-2 text-xs text-gray-600">
413
+ <div className="mt-2 text-xs text-[rgb(var(--ec-page-text-muted))]">
412
414
  {currentMatches.length > 0
413
415
  ? `${currentMatchIndex + 1} of ${currentMatches.length} ${currentMatches.length === 1 ? 'match' : 'matches'}`
414
416
  : 'No fields found'}
@@ -420,11 +422,13 @@ export default function AvroSchemaViewer({
420
422
  {/* Schema info */}
421
423
  <div className="px-4 pt-4">
422
424
  <div className="flex items-baseline gap-2 mb-2">
423
- <span className="text-sm font-medium text-gray-600">Record:</span>
424
- <span className="font-mono text-sm text-blue-600">{schema.name}</span>
425
- {schema.namespace && <span className="font-mono text-xs text-gray-500">({schema.namespace})</span>}
425
+ <span className="text-sm font-medium text-[rgb(var(--ec-page-text-muted))]">Record:</span>
426
+ <span className="font-mono text-sm text-blue-600 dark:text-blue-400">{schema.name}</span>
427
+ {schema.namespace && (
428
+ <span className="font-mono text-xs text-[rgb(var(--ec-page-text-muted))]">({schema.namespace})</span>
429
+ )}
426
430
  </div>
427
- {schema.doc && <p className="text-gray-600 text-xs mb-4">{schema.doc}</p>}
431
+ {schema.doc && <p className="text-[rgb(var(--ec-page-text-muted))] text-xs mb-4">{schema.doc}</p>}
428
432
  </div>
429
433
 
430
434
  {/* Fields */}
@@ -434,14 +438,14 @@ export default function AvroSchemaViewer({
434
438
  <AvroField key={field.name} field={field} level={0} expand={expandAll} showRequired={showRequiredBool} />
435
439
  ))
436
440
  ) : (
437
- <div className="text-center py-8 text-gray-400">
441
+ <div className="text-center py-8 text-[rgb(var(--ec-icon-color))]">
438
442
  <p className="text-sm">No fields defined</p>
439
443
  </div>
440
444
  )}
441
445
 
442
446
  {searchQuery && currentMatches.length === 0 && (
443
447
  <div className="text-center py-8">
444
- <div className="text-gray-400 text-sm">
448
+ <div className="text-[rgb(var(--ec-icon-color))] text-sm">
445
449
  <svg className="mx-auto h-12 w-12 mb-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
446
450
  <path
447
451
  strokeLinecap="round"
@@ -55,12 +55,12 @@ export default function DiffViewer({ diffs, onOpenFullscreen, apiAccessEnabled =
55
55
  ))}
56
56
  </div>
57
57
  ) : (
58
- <div className="bg-white border border-purple-200 rounded-lg p-8">
58
+ <div className="bg-[rgb(var(--ec-card-bg,var(--ec-page-bg)))] border border-[rgb(var(--ec-accent)/0.3)] rounded-lg p-8">
59
59
  <div className="flex flex-col items-center text-center max-w-md mx-auto">
60
60
  <div className="flex-shrink-0 mb-4">
61
61
  <svg
62
62
  xmlns="http://www.w3.org/2000/svg"
63
- className="h-16 w-16 text-purple-600"
63
+ className="h-16 w-16 text-[rgb(var(--ec-accent))]"
64
64
  fill="none"
65
65
  viewBox="0 0 24 24"
66
66
  stroke="currentColor"
@@ -82,7 +82,7 @@ export default function DiffViewer({ diffs, onOpenFullscreen, apiAccessEnabled =
82
82
  href="https://eventcatalog.cloud"
83
83
  target="_blank"
84
84
  rel="noopener noreferrer"
85
- className="inline-flex items-center gap-2 px-4 py-2 text-sm font-medium text-white bg-purple-600 rounded-md hover:bg-purple-700 transition-colors"
85
+ className="inline-flex items-center gap-2 px-4 py-2 text-sm font-medium text-white bg-[rgb(var(--ec-accent))] rounded-md hover:bg-[rgb(var(--ec-accent-hover))] transition-colors"
86
86
  >
87
87
  Start 14-day free trial
88
88
  <svg xmlns="http://www.w3.org/2000/svg" className="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="currentColor">
@@ -225,7 +225,7 @@ const SchemaProperty = ({ name, details, isRequired, level, isListItem = false,
225
225
  const indentationClass = `pl-${level * 3}`;
226
226
 
227
227
  return (
228
- <div className={`property-container mb-1.5 border-l border-gray-100 relative ${indentationClass}`}>
228
+ <div className={`property-container mb-1.5 border-l border-[rgb(var(--ec-page-border))] relative ${indentationClass}`}>
229
229
  <div className="flex items-start space-x-1.5">
230
230
  {isCollapsible ? (
231
231
  <button
@@ -233,7 +233,7 @@ const SchemaProperty = ({ name, details, isRequired, level, isListItem = false,
233
233
  aria-expanded={isExpanded}
234
234
  aria-controls={contentId}
235
235
  onClick={() => setIsExpanded(!isExpanded)}
236
- className="property-toggle text-gray-500 hover:text-gray-700 pt-0.5 focus:outline-none w-3 text-center flex-shrink-0"
236
+ className="property-toggle text-[rgb(var(--ec-page-text-muted))] hover:text-[rgb(var(--ec-page-text))] pt-0.5 focus:outline-none w-3 text-center flex-shrink-0"
237
237
  >
238
238
  <span className={`icon-collapsed font-mono text-xs ${isExpanded ? 'hidden' : ''}`}>&gt;</span>
239
239
  <span className={`icon-expanded font-mono text-xs ${!isExpanded ? 'hidden' : ''}`}>v</span>
@@ -245,13 +245,15 @@ const SchemaProperty = ({ name, details, isRequired, level, isListItem = false,
245
245
  <div className="flex-grow">
246
246
  <div className="flex justify-between items-baseline">
247
247
  <div>
248
- <span className="font-semibold text-gray-800 text-sm">{name}</span>
249
- <span className="ml-1.5 text-purple-600 font-mono text-xs">
248
+ <span className="font-semibold text-[rgb(var(--ec-page-text))] text-sm">{name}</span>
249
+ <span className="ml-1.5 text-[rgb(var(--ec-accent))] font-mono text-xs">
250
250
  {details.type}
251
251
  {details.type === 'array' && details.items?.type ? `[${details.items.type}]` : ''}
252
252
  {details.format ? `<${details.format}>` : ''}
253
- {details._refPath && <span className="text-blue-600 ml-1">→ {details._refName || details._refPath}</span>}
254
- {details._refNotFound && <span className="text-red-600 ml-1">❌ ref not found</span>}
253
+ {details._refPath && (
254
+ <span className="text-blue-600 dark:text-blue-400 ml-1">→ {details._refName || details._refPath}</span>
255
+ )}
256
+ {details._refNotFound && <span className="text-red-600 dark:text-red-400 ml-1">❌ ref not found</span>}
255
257
  {details.const !== undefined && (
256
258
  <span>
257
259
  constant: <code>{details.const}</code>
@@ -259,38 +261,53 @@ const SchemaProperty = ({ name, details, isRequired, level, isListItem = false,
259
261
  )}
260
262
  </span>
261
263
  </div>
262
- {isRequired && <span className="text-red-600 text-xs ml-3 flex-shrink-0">required</span>}
264
+ {isRequired && <span className="text-red-600 dark:text-red-400 text-xs ml-3 flex-shrink-0">required</span>}
263
265
  </div>
264
266
 
265
- {details.description && <p className="text-gray-500 text-xs mt-0.5">{details.description}</p>}
267
+ {details.description && <p className="text-[rgb(var(--ec-page-text-muted))] text-xs mt-0.5">{details.description}</p>}
266
268
  {details.title && details.title !== details.description && (
267
- <p className="text-gray-500 text-xs mt-0.5 italic">Title: {details.title}</p>
269
+ <p className="text-[rgb(var(--ec-page-text-muted))] text-xs mt-0.5 italic">Title: {details.title}</p>
268
270
  )}
269
271
 
270
- <div className="text-xs text-gray-500 mt-0.5 space-y-0">
272
+ <div className="text-xs text-[rgb(var(--ec-page-text-muted))] mt-0.5 space-y-0">
271
273
  {details.pattern && (
272
274
  <div>
273
- Match pattern: <code className="bg-gray-100 px-1 rounded text-gray-800 font-thin py-0.5">{details.pattern}</code>
275
+ Match pattern:{' '}
276
+ <code className="bg-[rgb(var(--ec-content-hover))] px-1 rounded text-[rgb(var(--ec-page-text))] font-thin py-0.5">
277
+ {details.pattern}
278
+ </code>
274
279
  </div>
275
280
  )}
276
281
  {details.minimum !== undefined && (
277
282
  <div>
278
- Minimum: <code className="bg-gray-100 px-1 rounded text-gray-800 font-thin py-0.5">{details.minimum}</code>
283
+ Minimum:{' '}
284
+ <code className="bg-[rgb(var(--ec-content-hover))] px-1 rounded text-[rgb(var(--ec-page-text))] font-thin py-0.5">
285
+ {details.minimum}
286
+ </code>
279
287
  </div>
280
288
  )}
281
289
  {details.maximum !== undefined && (
282
290
  <div>
283
- Maximum: <code className="bg-gray-100 px-1 rounded text-gray-800 font-thin py-0.5">{details.maximum}</code>
291
+ Maximum:{' '}
292
+ <code className="bg-[rgb(var(--ec-content-hover))] px-1 rounded text-[rgb(var(--ec-page-text))] font-thin py-0.5">
293
+ {details.maximum}
294
+ </code>
284
295
  </div>
285
296
  )}
286
297
  {details.minLength !== undefined && (
287
298
  <div>
288
- Min length: <code className="bg-gray-100 px-1 rounded text-gray-800 font-thin py-0.5">{details.minLength}</code>
299
+ Min length:{' '}
300
+ <code className="bg-[rgb(var(--ec-content-hover))] px-1 rounded text-[rgb(var(--ec-page-text))] font-thin py-0.5">
301
+ {details.minLength}
302
+ </code>
289
303
  </div>
290
304
  )}
291
305
  {details.maxLength !== undefined && (
292
306
  <div>
293
- Max length: <code className="bg-gray-100 px-1 rounded text-gray-800 font-thin py-0.5">{details.maxLength}</code>
307
+ Max length:{' '}
308
+ <code className="bg-[rgb(var(--ec-content-hover))] px-1 rounded text-[rgb(var(--ec-page-text))] font-thin py-0.5">
309
+ {details.maxLength}
310
+ </code>
294
311
  </div>
295
312
  )}
296
313
  {details.enum && (
@@ -299,7 +316,9 @@ const SchemaProperty = ({ name, details, isRequired, level, isListItem = false,
299
316
  {details.enum.map((val: any, idx: number) => (
300
317
  <span key={idx} className="text-xs">
301
318
  {' '}
302
- <code className="bg-gray-100 px-1 rounded text-gray-800 font-thin py-0.5">{val}</code>
319
+ <code className="bg-[rgb(var(--ec-content-hover))] px-1 rounded text-[rgb(var(--ec-page-text))] font-thin py-0.5">
320
+ {val}
321
+ </code>
303
322
  </span>
304
323
  ))}
305
324
  </div>
@@ -322,8 +341,8 @@ const SchemaProperty = ({ name, details, isRequired, level, isListItem = false,
322
341
  ))}
323
342
 
324
343
  {hasArrayItemProperties && (
325
- <div className="mt-1 border-l border-dashed border-gray-400 pl-3 ml-1.5">
326
- <span className="text-xs italic text-gray-500 block mb-1">Item Details:</span>
344
+ <div className="mt-1 border-l border-dashed border-[rgb(var(--ec-page-border))] pl-3 ml-1.5">
345
+ <span className="text-xs italic text-[rgb(var(--ec-page-text-muted))] block mb-1">Item Details:</span>
327
346
  {details.items.properties &&
328
347
  Object.entries(details.items.properties).map(([itemPropName, itemPropDetails]: [string, any]) => (
329
348
  <SchemaProperty
@@ -337,7 +356,7 @@ const SchemaProperty = ({ name, details, isRequired, level, isListItem = false,
337
356
  />
338
357
  ))}
339
358
  {(details.items.allOf || details.items.oneOf || details.items.$ref) && !details.items.properties && (
340
- <div className="text-xs text-gray-500 mt-1">
359
+ <div className="text-xs text-[rgb(var(--ec-page-text-muted))] mt-1">
341
360
  Complex array item schema detected. The properties should be processed by the parent SchemaViewer.
342
361
  </div>
343
362
  )}
@@ -514,7 +533,7 @@ export default function JSONSchemaViewer({
514
533
 
515
534
  if (!schema) {
516
535
  return (
517
- <div className="flex items-center justify-center h-full text-gray-500 p-8">
536
+ <div className="flex items-center justify-center h-full text-[rgb(var(--ec-page-text-muted))] p-8">
518
537
  <p className="text-sm">Unable to parse JSON schema</p>
519
538
  </div>
520
539
  );
@@ -534,12 +553,12 @@ export default function JSONSchemaViewer({
534
553
  return (
535
554
  <div
536
555
  id={id}
537
- className={`${heightClass} ${overflowClass} flex flex-col bg-white border border-gray-100 rounded-md shadow-sm`}
556
+ className={`${heightClass} ${overflowClass} flex flex-col bg-[rgb(var(--ec-card-bg,var(--ec-page-bg)))] border border-[rgb(var(--ec-page-border))] rounded-md shadow-sm`}
538
557
  style={containerStyle}
539
558
  >
540
559
  {/* Toolbar */}
541
560
  {searchBool && (
542
- <div className="flex-shrink-0 bg-white pt-4 px-4 mb-4 pb-3 border-b border-gray-100 shadow-sm">
561
+ <div className="flex-shrink-0 bg-[rgb(var(--ec-card-bg,var(--ec-page-bg)))] pt-4 px-4 mb-4 pb-3 border-b border-[rgb(var(--ec-page-border))] shadow-sm">
543
562
  <div className="flex flex-col sm:flex-row gap-3">
544
563
  <div className="flex-1 relative">
545
564
  <input
@@ -548,7 +567,7 @@ export default function JSONSchemaViewer({
548
567
  value={searchQuery}
549
568
  onChange={(e) => setSearchQuery(e.target.value)}
550
569
  placeholder="Search properties..."
551
- className="w-full px-3 py-1.5 pr-20 text-sm border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent"
570
+ className="w-full px-3 py-1.5 pr-20 text-sm border border-[rgb(var(--ec-input-border))] rounded-md bg-[rgb(var(--ec-input-bg))] text-[rgb(var(--ec-input-text))] placeholder:text-[rgb(var(--ec-input-placeholder))] focus:outline-none focus:ring-2 focus:ring-[rgb(var(--ec-accent))] focus:border-transparent"
552
571
  onKeyDown={(e) => {
553
572
  if (e.key === 'Enter') {
554
573
  e.preventDefault();
@@ -564,7 +583,7 @@ export default function JSONSchemaViewer({
564
583
  <button
565
584
  onClick={handlePrevMatch}
566
585
  disabled={currentMatches.length === 0 || currentMatchIndex <= 0}
567
- className="p-1 text-gray-400 hover:text-gray-600 disabled:opacity-30 disabled:cursor-not-allowed"
586
+ className="p-1 text-[rgb(var(--ec-icon-color))] hover:text-[rgb(var(--ec-page-text))] disabled:opacity-30 disabled:cursor-not-allowed"
568
587
  title="Previous match"
569
588
  >
570
589
  <svg className="w-3 h-3" fill="none" stroke="currentColor" viewBox="0 0 24 24">
@@ -574,7 +593,7 @@ export default function JSONSchemaViewer({
574
593
  <button
575
594
  onClick={handleNextMatch}
576
595
  disabled={currentMatches.length === 0 || currentMatchIndex >= currentMatches.length - 1}
577
- className="p-1 text-gray-400 hover:text-gray-600 disabled:opacity-30 disabled:cursor-not-allowed"
596
+ className="p-1 text-[rgb(var(--ec-icon-color))] hover:text-[rgb(var(--ec-page-text))] disabled:opacity-30 disabled:cursor-not-allowed"
578
597
  title="Next match"
579
598
  >
580
599
  <svg className="w-3 h-3" fill="none" stroke="currentColor" viewBox="0 0 24 24">
@@ -587,7 +606,7 @@ export default function JSONSchemaViewer({
587
606
  {onOpenFullscreen && (
588
607
  <button
589
608
  onClick={onOpenFullscreen}
590
- className="px-3 py-1.5 text-xs font-medium text-gray-700 bg-gray-100 rounded-md hover:bg-gray-200 focus:outline-none focus:ring-2 focus:ring-gray-500"
609
+ className="px-3 py-1.5 text-xs font-medium text-[rgb(var(--ec-page-text))] bg-[rgb(var(--ec-content-hover))] rounded-md hover:bg-[rgb(var(--ec-content-active))] focus:outline-none focus:ring-2 focus:ring-[rgb(var(--ec-accent))]"
591
610
  title="Open in fullscreen"
592
611
  >
593
612
  <svg
@@ -608,23 +627,23 @@ export default function JSONSchemaViewer({
608
627
  )}
609
628
  <button
610
629
  onClick={handleExpandAll}
611
- className="px-3 py-1.5 text-xs font-medium text-gray-700 bg-gray-100 rounded-md hover:bg-gray-200 focus:outline-none focus:ring-2 focus:ring-gray-500"
630
+ className="px-3 py-1.5 text-xs font-medium text-[rgb(var(--ec-page-text))] bg-[rgb(var(--ec-content-hover))] rounded-md hover:bg-[rgb(var(--ec-content-active))] focus:outline-none focus:ring-2 focus:ring-[rgb(var(--ec-accent))]"
612
631
  >
613
632
  Expand All
614
633
  </button>
615
634
  <button
616
635
  onClick={handleCollapseAll}
617
- className="px-3 py-1.5 text-xs font-medium text-gray-700 bg-gray-100 rounded-md hover:bg-gray-200 focus:outline-none focus:ring-2 focus:ring-gray-500"
636
+ className="px-3 py-1.5 text-xs font-medium text-[rgb(var(--ec-page-text))] bg-[rgb(var(--ec-content-hover))] rounded-md hover:bg-[rgb(var(--ec-content-active))] focus:outline-none focus:ring-2 focus:ring-[rgb(var(--ec-accent))]"
618
637
  >
619
638
  Collapse All
620
639
  </button>
621
- <div className="text-xs text-gray-500">
640
+ <div className="text-xs text-[rgb(var(--ec-page-text-muted))]">
622
641
  {totalProperties} {totalProperties === 1 ? 'property' : 'properties'}
623
642
  </div>
624
643
  </div>
625
644
  </div>
626
645
  {searchQuery && (
627
- <div className="mt-2 text-xs text-gray-600">
646
+ <div className="mt-2 text-xs text-[rgb(var(--ec-page-text-muted))]">
628
647
  {currentMatches.length > 0
629
648
  ? `${currentMatchIndex + 1} of ${currentMatches.length} ${currentMatches.length === 1 ? 'match' : 'matches'}`
630
649
  : 'No properties found'}
@@ -636,26 +655,26 @@ export default function JSONSchemaViewer({
636
655
  {/* Content */}
637
656
  <div className="flex-1 px-4 pb-4 overflow-auto">
638
657
  {isRootArray && (
639
- <div className="mb-4 p-3 bg-blue-50 border border-blue-200 rounded-md">
658
+ <div className="mb-4 p-3 bg-blue-50 dark:bg-blue-950/50 border border-blue-200 dark:border-blue-800 rounded-md">
640
659
  <div className="flex items-center space-x-2">
641
- <span className="text-blue-600 font-medium text-sm">Array Schema</span>
642
- <span className="text-blue-500 font-mono text-xs">array[object]</span>
660
+ <span className="text-blue-600 dark:text-blue-400 font-medium text-sm">Array Schema</span>
661
+ <span className="text-blue-500 dark:text-blue-400 font-mono text-xs">array[object]</span>
643
662
  </div>
644
- <p className="text-blue-700 text-xs mt-1">
663
+ <p className="text-blue-700 dark:text-blue-300 text-xs mt-1">
645
664
  This schema defines an array of objects. Each item in the array has the properties shown below.
646
665
  </p>
647
666
  </div>
648
667
  )}
649
- {description && <p className="text-gray-600 text-xs mb-5">{description}</p>}
668
+ {description && <p className="text-[rgb(var(--ec-page-text-muted))] text-xs mb-5">{description}</p>}
650
669
 
651
670
  {variants && (
652
671
  <div className="mb-4">
653
672
  <div className="flex items-center space-x-2">
654
- <span className="text-sm text-gray-600">(one of)</span>
673
+ <span className="text-sm text-[rgb(var(--ec-page-text-muted))]">(one of)</span>
655
674
  <select
656
675
  value={selectedVariantIndex}
657
676
  onChange={(e) => setSelectedVariantIndex(parseInt(e.target.value))}
658
- className="form-select text-sm border-gray-300 rounded-md shadow-sm focus:border-indigo-300 focus:ring focus:ring-indigo-200 focus:ring-opacity-50"
677
+ className="form-select text-sm border-[rgb(var(--ec-input-border))] bg-[rgb(var(--ec-input-bg))] text-[rgb(var(--ec-input-text))] rounded-md shadow-sm focus:border-[rgb(var(--ec-accent))] focus:ring focus:ring-[rgb(var(--ec-accent)/0.2)]"
659
678
  >
660
679
  {variants.map((variant: any, index: number) => (
661
680
  <option key={index} value={index}>
@@ -683,16 +702,16 @@ export default function JSONSchemaViewer({
683
702
  ))}
684
703
  </div>
685
704
  ) : !isRootArray ? (
686
- <p className="text-gray-500 text-sm">Schema does not contain any properties.</p>
705
+ <p className="text-[rgb(var(--ec-page-text-muted))] text-sm">Schema does not contain any properties.</p>
687
706
  ) : (
688
707
  <div className="text-center py-8">
689
- <div className="text-gray-500 text-sm">
708
+ <div className="text-[rgb(var(--ec-page-text-muted))] text-sm">
690
709
  <p>
691
710
  This array contains items of type:{' '}
692
- <span className="font-mono text-blue-600">{processedSchema.items?.type || 'unknown'}</span>
711
+ <span className="font-mono text-blue-600 dark:text-blue-400">{processedSchema.items?.type || 'unknown'}</span>
693
712
  </p>
694
713
  {processedSchema.items?.description && (
695
- <p className="text-xs mt-2 text-gray-600">{processedSchema.items.description}</p>
714
+ <p className="text-xs mt-2 text-[rgb(var(--ec-page-text-muted))]">{processedSchema.items.description}</p>
696
715
  )}
697
716
  </div>
698
717
  </div>
@@ -700,7 +719,7 @@ export default function JSONSchemaViewer({
700
719
 
701
720
  {searchQuery && currentMatches.length === 0 && (
702
721
  <div className="text-center py-8">
703
- <div className="text-gray-400 text-sm">
722
+ <div className="text-[rgb(var(--ec-page-text-muted))] text-sm">
704
723
  <svg className="mx-auto h-12 w-12 mb-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
705
724
  <path
706
725
  strokeLinecap="round"
@@ -14,23 +14,27 @@ export default function OwnersSection({ message, isExpanded, onToggle }: OwnersS
14
14
  if (owners.length === 0) return null;
15
15
 
16
16
  return (
17
- <div className="flex-shrink-0 border-b border-gray-200">
17
+ <div className="flex-shrink-0 border-b border-[rgb(var(--ec-page-border))]">
18
18
  <button
19
19
  onClick={onToggle}
20
- className="w-full flex items-center justify-between px-4 py-1.5 text-left hover:bg-gray-50 transition-colors"
20
+ className="w-full flex items-center justify-between px-4 py-1.5 text-left hover:bg-[rgb(var(--ec-content-hover))] transition-colors"
21
21
  >
22
22
  <div className="flex items-center gap-2">
23
- <UserIcon className="h-4 w-4 text-gray-600" />
24
- <span className="text-xs font-semibold text-gray-900">Owners</span>
25
- <span className="inline-flex items-center rounded-full bg-gray-100 px-2 py-0.5 text-xs font-medium text-gray-700">
23
+ <UserIcon className="h-4 w-4 text-[rgb(var(--ec-page-text-muted))]" />
24
+ <span className="text-xs font-semibold text-[rgb(var(--ec-page-text))]">Owners</span>
25
+ <span className="inline-flex items-center rounded-full bg-[rgb(var(--ec-content-hover))] px-2 py-0.5 text-xs font-medium text-[rgb(var(--ec-page-text-muted))]">
26
26
  {owners.length}
27
27
  </span>
28
28
  </div>
29
- {isExpanded ? <ChevronUpIcon className="h-4 w-4 text-gray-600" /> : <ChevronDownIcon className="h-4 w-4 text-gray-600" />}
29
+ {isExpanded ? (
30
+ <ChevronUpIcon className="h-4 w-4 text-[rgb(var(--ec-page-text-muted))]" />
31
+ ) : (
32
+ <ChevronDownIcon className="h-4 w-4 text-[rgb(var(--ec-page-text-muted))]" />
33
+ )}
30
34
  </button>
31
35
 
32
36
  {isExpanded && (
33
- <div className="px-4 pb-2 bg-gray-50">
37
+ <div className="px-4 pb-2 bg-[rgb(var(--ec-content-hover))]">
34
38
  <div className="flex flex-wrap gap-2">
35
39
  {owners.map((owner: Owner, idx: number) => {
36
40
  const Icon = owner.type === 'users' ? UserIcon : UserGroupIcon;
@@ -38,10 +42,10 @@ export default function OwnersSection({ message, isExpanded, onToggle }: OwnersS
38
42
  <a
39
43
  key={`${owner.id}-${idx}`}
40
44
  href={owner.href}
41
- className="inline-flex items-center gap-1.5 pl-1 pr-3 py-1 text-xs font-medium text-gray-700 bg-white border border-gray-200 rounded-full hover:border-gray-300 hover:shadow-sm transition-all"
45
+ className="inline-flex items-center gap-1.5 pl-1 pr-3 py-1 text-xs font-medium text-[rgb(var(--ec-page-text))] bg-[rgb(var(--ec-card-bg,var(--ec-page-bg)))] border border-[rgb(var(--ec-page-border))] rounded-full hover:border-[rgb(var(--ec-accent))] hover:shadow-sm transition-all"
42
46
  title={owner.name}
43
47
  >
44
- <div className="flex items-center justify-center w-5 h-5 bg-gradient-to-b from-purple-500 to-purple-600 rounded-full">
48
+ <div className="flex items-center justify-center w-5 h-5 bg-gradient-to-b from-[rgb(var(--ec-accent-gradient-from))] to-[rgb(var(--ec-accent-gradient-to))] rounded-full">
45
49
  <Icon className="h-3 w-3 text-white" />
46
50
  </div>
47
51
  <span className="font-medium">{owner.name}</span>
@@ -10,12 +10,12 @@ export default function Pagination({ currentPage, totalPages, onPageChange }: Pa
10
10
  if (totalPages <= 1) return null;
11
11
 
12
12
  return (
13
- <div className="flex-shrink-0 border-t border-gray-100 px-3 py-1.5 bg-gray-50/50">
13
+ <div className="flex-shrink-0 border-t border-[rgb(var(--ec-page-border))] px-3 py-1.5 bg-[rgb(var(--ec-content-hover))]">
14
14
  <div className="flex items-center justify-between">
15
15
  <button
16
16
  onClick={() => onPageChange(Math.max(1, currentPage - 1))}
17
17
  disabled={currentPage === 1}
18
- className="inline-flex items-center gap-0.5 px-1.5 py-1 text-xs font-medium text-gray-500 hover:text-gray-700 disabled:opacity-30 disabled:cursor-not-allowed transition-colors"
18
+ className="inline-flex items-center gap-0.5 px-1.5 py-1 text-xs font-medium text-[rgb(var(--ec-page-text-muted))] hover:text-[rgb(var(--ec-page-text))] disabled:opacity-30 disabled:cursor-not-allowed transition-colors"
19
19
  >
20
20
  <ChevronLeftIcon className="h-3.5 w-3.5" />
21
21
  Prev
@@ -37,7 +37,9 @@ export default function Pagination({ currentPage, totalPages, onPageChange }: Pa
37
37
  key={pageNum}
38
38
  onClick={() => onPageChange(pageNum)}
39
39
  className={`w-6 h-6 text-[11px] font-medium rounded transition-all tabular-nums ${
40
- currentPage === pageNum ? 'bg-gray-900 text-white' : 'text-gray-500 hover:bg-gray-100 hover:text-gray-700'
40
+ currentPage === pageNum
41
+ ? 'bg-[rgb(var(--ec-accent))] text-white'
42
+ : 'text-[rgb(var(--ec-page-text-muted))] hover:bg-[rgb(var(--ec-content-hover))] hover:text-[rgb(var(--ec-page-text))]'
41
43
  }`}
42
44
  >
43
45
  {pageNum}
@@ -48,7 +50,7 @@ export default function Pagination({ currentPage, totalPages, onPageChange }: Pa
48
50
  <button
49
51
  onClick={() => onPageChange(Math.min(totalPages, currentPage + 1))}
50
52
  disabled={currentPage === totalPages}
51
- className="inline-flex items-center gap-0.5 px-1.5 py-1 text-xs font-medium text-gray-500 hover:text-gray-700 disabled:opacity-30 disabled:cursor-not-allowed transition-colors"
53
+ className="inline-flex items-center gap-0.5 px-1.5 py-1 text-xs font-medium text-[rgb(var(--ec-page-text-muted))] hover:text-[rgb(var(--ec-page-text))] disabled:opacity-30 disabled:cursor-not-allowed transition-colors"
52
54
  >
53
55
  Next
54
56
  <ChevronRightIcon className="h-3.5 w-3.5" />