diff --git a/ui/src/auth/LoginPage.module.css b/ui/src/auth/LoginPage.module.css index 97422397..f42f1da6 100644 --- a/ui/src/auth/LoginPage.module.css +++ b/ui/src/auth/LoginPage.module.css @@ -3,7 +3,7 @@ align-items: center; justify-content: center; min-height: 100vh; - background: var(--bg-base); + background: var(--bg-body); } .card { diff --git a/ui/src/auth/OidcCallback.module.css b/ui/src/auth/OidcCallback.module.css new file mode 100644 index 00000000..50eebd7d --- /dev/null +++ b/ui/src/auth/OidcCallback.module.css @@ -0,0 +1,21 @@ +.page { + display: flex; + align-items: center; + justify-content: center; + min-height: 100vh; + background: var(--bg-body); +} + +.card { + padding: 2rem; + text-align: center; + min-width: 320px; +} + +.heading { + margin-bottom: 1rem; +} + +.backButton { + margin-top: 16px; +} diff --git a/ui/src/auth/OidcCallback.tsx b/ui/src/auth/OidcCallback.tsx index a1987625..9cca67bb 100644 --- a/ui/src/auth/OidcCallback.tsx +++ b/ui/src/auth/OidcCallback.tsx @@ -4,6 +4,7 @@ import { useAuthStore } from './auth-store'; import { api } from '../api/client'; import { Card, Spinner, Alert, Button } from '@cameleer/design-system'; import { config } from '../config'; +import styles from './OidcCallback.module.css'; export function OidcCallback() { const { isAuthenticated, loading, error, loginWithOidcCode } = useAuthStore(); @@ -67,15 +68,15 @@ export function OidcCallback() { if (isAuthenticated) return ; return ( -
+
-
-

cameleer3

+
+

cameleer3

{loading && } {error && ( <> {error} - diff --git a/ui/src/components/ContentTabs.module.css b/ui/src/components/ContentTabs.module.css index e934a9ae..b62d3c00 100644 --- a/ui/src/components/ContentTabs.module.css +++ b/ui/src/components/ContentTabs.module.css @@ -5,6 +5,6 @@ padding: 0 1.5rem; padding-top: 0.375rem; border-bottom: 1px solid var(--border); - background: var(--surface); + background: var(--bg-surface); gap: 1rem; } diff --git a/ui/src/components/DeploymentProgress.module.css b/ui/src/components/DeploymentProgress.module.css index 7ffa9e3b..3e40b4f7 100644 --- a/ui/src/components/DeploymentProgress.module.css +++ b/ui/src/components/DeploymentProgress.module.css @@ -45,7 +45,7 @@ height: 10px; border-radius: 50%; border: 2px solid var(--border-subtle); - background: var(--surface, #1a1a1a); + background: var(--bg-surface); display: flex; align-items: center; justify-content: center; @@ -56,7 +56,7 @@ .dot.completed { background: var(--amber); border-color: var(--amber); - color: var(--surface, #1a1a1a); + color: var(--bg-surface); } .dot.active { diff --git a/ui/src/components/EnvironmentSelector.module.css b/ui/src/components/EnvironmentSelector.module.css index 104831d1..99c4fd7a 100644 --- a/ui/src/components/EnvironmentSelector.module.css +++ b/ui/src/components/EnvironmentSelector.module.css @@ -18,7 +18,7 @@ } .select:focus-visible { - outline: 1px solid var(--accent); + outline: 1px solid var(--amber); outline-offset: 2px; border-radius: 2px; } diff --git a/ui/src/components/ExecutionDiagram/ExecutionDiagram.module.css b/ui/src/components/ExecutionDiagram/ExecutionDiagram.module.css index 35edba6b..ca495bab 100644 --- a/ui/src/components/ExecutionDiagram/ExecutionDiagram.module.css +++ b/ui/src/components/ExecutionDiagram/ExecutionDiagram.module.css @@ -15,37 +15,37 @@ align-items: center; gap: 12px; padding: 8px 14px; - background: var(--bg-surface, #FFFFFF); - border-bottom: 1px solid var(--border, #E4DFD8); + background: var(--bg-surface); + border-bottom: 1px solid var(--border); font-size: 12px; - color: var(--text-secondary, #5C5347); + color: var(--text-secondary); flex-shrink: 0; } .exchangeLabel { font-weight: 600; - color: var(--text-primary, #1A1612); + color: var(--text-primary); } .exchangeId { font-size: 12px; - background: var(--bg-hover, #F5F0EA); + background: var(--bg-hover); padding: 2px 6px; border-radius: 3px; - color: var(--text-primary, #1A1612); + color: var(--text-primary); } .exchangeMeta { - color: var(--text-muted, #9C9184); + color: var(--text-muted); } .jumpToError { margin-left: auto; font-size: 12px; padding: 3px 10px; - border: 1px solid var(--error, #C0392B); - background: #FDF2F0; - color: var(--error, #C0392B); + border: 1px solid var(--error); + background: var(--error-bg); + color: var(--error); border-radius: 4px; cursor: pointer; font-weight: 500; @@ -53,7 +53,7 @@ } .jumpToError:hover { - background: #F9E0DC; + background: color-mix(in srgb, var(--error) 15%, var(--bg-surface)); } .diagramArea { @@ -67,12 +67,12 @@ right: 8px; z-index: 10; font-size: 12px; - font-family: var(--font-mono, monospace); + font-family: var(--font-mono); padding: 3px 8px; - border: 1px solid var(--border, #E4DFD8); + border: 1px solid var(--border); border-radius: 4px; - background: var(--bg-surface, #FFFFFF); - color: var(--text-secondary, #5C5347); + background: var(--bg-surface); + color: var(--text-secondary); cursor: pointer; opacity: 0.7; transition: opacity 0.15s, background 0.15s; @@ -80,18 +80,18 @@ .downloadBtn:hover { opacity: 1; - background: var(--bg-hover, #F5F0EA); + background: var(--bg-hover); } .splitter { height: 4px; - background: var(--border, #E4DFD8); + background: var(--border); cursor: row-resize; flex-shrink: 0; } .splitter:hover { - background: var(--amber, #C6820E); + background: var(--amber); } .detailArea { @@ -106,7 +106,7 @@ align-items: center; justify-content: center; flex: 1; - color: var(--text-muted, #9C9184); + color: var(--text-muted); font-size: 13px; } @@ -115,13 +115,13 @@ align-items: center; justify-content: center; flex: 1; - color: var(--error, #C0392B); + color: var(--error); font-size: 13px; } .statusRunning { - color: var(--amber, #C6820E); - background: #FFF8F0; + color: var(--amber); + background: var(--amber-bg); } /* ========================================================================== @@ -131,8 +131,8 @@ display: flex; flex-direction: column; overflow: hidden; - background: var(--bg-surface, #FFFFFF); - border-top: 1px solid var(--border, #E4DFD8); + background: var(--bg-surface); + border-top: 1px solid var(--border); flex: 1; min-height: 0; } @@ -143,27 +143,27 @@ align-items: center; gap: 10px; padding: 6px 14px; - border-bottom: 1px solid var(--border, #E4DFD8); - background: #FAFAF8; + border-bottom: 1px solid var(--border); + background: var(--bg-raised); min-height: 32px; } .processorName { font-size: 12px; font-weight: 600; - color: var(--text-primary, #1A1612); + color: var(--text-primary); } .processorId { font-size: 12px; - font-family: var(--font-mono, monospace); - color: var(--text-muted, #9C9184); + font-family: var(--font-mono); + color: var(--text-muted); } .processorDuration { font-size: 12px; - font-family: var(--font-mono, monospace); - color: var(--text-secondary, #5C5347); + font-family: var(--font-mono); + color: var(--text-secondary); margin-left: auto; } @@ -180,13 +180,13 @@ } .statusCompleted { - color: var(--success, #3D7C47); - background: #F0F9F1; + color: var(--success); + background: var(--success-bg); } .statusFailed { - color: var(--error, #C0392B); - background: #FDF2F0; + color: var(--error); + background: var(--error-bg); } /* ========================================================================== @@ -195,18 +195,18 @@ .tabBar { display: flex; flex-direction: row; - border-bottom: 1px solid var(--border, #E4DFD8); + border-bottom: 1px solid var(--border); padding: 0 14px; - background: #FAFAF8; + background: var(--bg-raised); gap: 0; } .tab { padding: 6px 12px; font-size: 12px; - font-family: var(--font-body, inherit); + font-family: var(--font-body); cursor: pointer; - color: var(--text-muted, #9C9184); + color: var(--text-muted); border: none; background: none; border-bottom: 2px solid transparent; @@ -215,12 +215,12 @@ } .tab:hover { - color: var(--text-secondary, #5C5347); + color: var(--text-secondary); } .tabActive { - color: var(--amber, #C6820E); - border-bottom: 2px solid var(--amber, #C6820E); + color: var(--amber); + border-bottom: 2px solid var(--amber); font-weight: 600; } @@ -230,15 +230,15 @@ } .tabDisabled:hover { - color: var(--text-muted, #9C9184); + color: var(--text-muted); } .tabError { - color: var(--error, #C0392B); + color: var(--error); } .tabError:hover { - color: var(--error, #C0392B); + color: var(--error); } /* ========================================================================== @@ -262,7 +262,7 @@ .fieldLabel { font-size: 12px; - color: var(--text-muted, #9C9184); + color: var(--text-muted); text-transform: uppercase; letter-spacing: 0.5px; margin-bottom: 2px; @@ -270,14 +270,14 @@ .fieldValue { font-size: 12px; - color: var(--text-primary, #1A1612); + color: var(--text-primary); word-break: break-all; } .fieldValueMono { font-size: 12px; - color: var(--text-primary, #1A1612); - font-family: var(--font-mono, monospace); + color: var(--text-primary); + font-family: var(--font-mono); word-break: break-all; } @@ -287,12 +287,12 @@ .attributesSection { margin-top: 14px; padding-top: 10px; - border-top: 1px solid var(--border, #E4DFD8); + border-top: 1px solid var(--border); } .attributesLabel { font-size: 12px; - color: var(--text-muted, #9C9184); + color: var(--text-muted); text-transform: uppercase; letter-spacing: 0.5px; margin-bottom: 6px; @@ -307,10 +307,10 @@ .attributePill { font-size: 12px; padding: 2px 8px; - background: var(--bg-hover, #F5F0EA); + background: var(--bg-hover); border-radius: 10px; - color: var(--text-secondary, #5C5347); - font-family: var(--font-mono, monospace); + color: var(--text-secondary); + font-family: var(--font-mono); } /* ========================================================================== @@ -330,7 +330,7 @@ } .headersColumn + .headersColumn { - border-left: 1px solid var(--border, #E4DFD8); + border-left: 1px solid var(--border); padding-left: 14px; margin-left: 14px; } @@ -338,7 +338,7 @@ .headersColumnLabel { font-size: 12px; font-weight: 600; - color: var(--text-muted, #9C9184); + color: var(--text-muted); text-transform: uppercase; letter-spacing: 0.5px; margin-bottom: 6px; @@ -352,7 +352,7 @@ .headersTable td { padding: 3px 0; - border-bottom: 1px solid var(--border, #E4DFD8); + border-bottom: 1px solid var(--border); vertical-align: top; } @@ -361,9 +361,9 @@ } .headerKey { - font-family: var(--font-mono, monospace); + font-family: var(--font-mono); font-weight: 600; - color: var(--text-muted, #9C9184); + color: var(--text-muted); white-space: nowrap; padding-right: 12px; width: 140px; @@ -373,8 +373,8 @@ } .headerVal { - font-family: var(--font-mono, monospace); - color: var(--text-primary, #1A1612); + font-family: var(--font-mono); + color: var(--text-primary); word-break: break-all; } @@ -391,39 +391,41 @@ .codeFormat { font-size: 12px; font-weight: 600; - color: var(--text-muted, #9C9184); + color: var(--text-muted); text-transform: uppercase; letter-spacing: 0.5px; } .codeSize { font-size: 12px; - color: var(--text-muted, #9C9184); - font-family: var(--font-mono, monospace); + color: var(--text-muted); + font-family: var(--font-mono); } .codeCopyBtn { margin-left: auto; font-size: 12px; - font-family: var(--font-body, inherit); + font-family: var(--font-body); padding: 2px 8px; - border: 1px solid var(--border, #E4DFD8); + border: 1px solid var(--border); border-radius: 4px; - background: var(--bg-surface, #FFFFFF); - color: var(--text-secondary, #5C5347); + background: var(--bg-surface); + color: var(--text-secondary); cursor: pointer; } .codeCopyBtn:hover { - background: var(--bg-hover, #F5F0EA); + background: var(--bg-hover); } .codeBlock { - background: #1A1612; - color: #E4DFD8; + --code-bg: var(--bg-inset); + --code-fg: var(--text-primary); + background: var(--code-bg); + color: var(--code-fg); padding: 12px; border-radius: 6px; - font-family: var(--font-mono, monospace); + font-family: var(--font-mono); font-size: 12px; line-height: 1.5; overflow-x: auto; @@ -439,15 +441,15 @@ .errorType { font-size: 13px; font-weight: 600; - color: var(--error, #C0392B); + color: var(--error); margin-bottom: 8px; } .errorMessage { font-size: 12px; - color: var(--text-primary, #1A1612); - background: #FDF2F0; - border: 1px solid #F5D5D0; + color: var(--text-primary); + background: var(--error-bg); + border: 1px solid var(--error-border); border-radius: 6px; padding: 10px 12px; margin-bottom: 12px; @@ -456,11 +458,13 @@ } .errorStackTrace { - background: #1A1612; - color: #E4DFD8; + --code-bg: var(--bg-inset); + --code-fg: var(--text-primary); + background: var(--code-bg); + color: var(--code-fg); padding: 12px; border-radius: 6px; - font-family: var(--font-mono, monospace); + font-family: var(--font-mono); font-size: 12px; line-height: 1.5; overflow-x: auto; @@ -477,7 +481,7 @@ .errorStackLabel { font-size: 12px; font-weight: 600; - color: var(--text-muted, #9C9184); + color: var(--text-muted); text-transform: uppercase; letter-spacing: 0.5px; margin-bottom: 6px; @@ -505,22 +509,22 @@ } .ganttRow:hover { - background: var(--bg-hover, #F5F0EA); + background: var(--bg-hover); } .ganttSelected { - background: #FFF8F0; + background: var(--amber-bg); } .ganttSelected:hover { - background: #FFF8F0; + background: var(--amber-bg); } .ganttLabel { width: 100px; min-width: 100px; font-size: 12px; - color: var(--text-secondary, #5C5347); + color: var(--text-secondary); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; @@ -529,7 +533,7 @@ .ganttBar { flex: 1; height: 16px; - background: var(--bg-hover, #F5F0EA); + background: var(--bg-hover); border-radius: 2px; position: relative; min-width: 0; @@ -543,19 +547,19 @@ } .ganttFillCompleted { - background: var(--success, #3D7C47); + background: var(--success); } .ganttFillFailed { - background: var(--error, #C0392B); + background: var(--error); } .ganttDuration { width: 50px; min-width: 50px; font-size: 12px; - font-family: var(--font-mono, monospace); - color: var(--text-muted, #9C9184); + font-family: var(--font-mono); + color: var(--text-muted); text-align: right; } @@ -564,7 +568,7 @@ ========================================================================== */ .emptyState { text-align: center; - color: var(--text-muted, #9C9184); + color: var(--text-muted); font-size: 12px; padding: 20px; } diff --git a/ui/src/components/LayoutShell.module.css b/ui/src/components/LayoutShell.module.css index 390d76bf..2c09aa76 100644 --- a/ui/src/components/LayoutShell.module.css +++ b/ui/src/components/LayoutShell.module.css @@ -14,3 +14,39 @@ margin-left: 4px; font-size: 12px; } + +.starredList { + padding: 4px 0; +} + +.starredIconWrap { + display: flex; + align-items: center; + color: var(--sidebar-muted); +} + +.starredLabel { + flex: 1; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +.starredRemoveBtn { + background: none; + border: none; + padding: 2px; + cursor: pointer; + color: var(--sidebar-muted); + display: flex; + align-items: center; + opacity: 0.6; +} + +.mainContent { + flex: 1; + display: flex; + flex-direction: column; + overflow: hidden; + min-height: 0; +} diff --git a/ui/src/components/LayoutShell.tsx b/ui/src/components/LayoutShell.tsx index 3348ca8f..d5110a0d 100644 --- a/ui/src/components/LayoutShell.tsx +++ b/ui/src/components/LayoutShell.tsx @@ -232,7 +232,7 @@ function collectStarredItems(apps: SidebarApp[], starredIds: Set): Starr function StarredList({ items, onNavigate, onRemove }: { items: StarredItem[]; onNavigate: (path: string) => void; onRemove: (key: string) => void }) { if (items.length === 0) return null; return ( -
+
{items.map((item) => (
{ if (e.key === 'Enter' || e.key === ' ') onNavigate(item.path); }} > - {item.icon && {item.icon}} - + {item.icon && {item.icon}} + {item.label} {item.parentApp && {item.parentApp}} diff --git a/ui/src/components/ProcessDiagram/ProcessDiagram.module.css b/ui/src/components/ProcessDiagram/ProcessDiagram.module.css index 6ebaa1f0..23f4fbda 100644 --- a/ui/src/components/ProcessDiagram/ProcessDiagram.module.css +++ b/ui/src/components/ProcessDiagram/ProcessDiagram.module.css @@ -4,9 +4,9 @@ height: 100%; min-height: 300px; overflow: hidden; - background: var(--bg-surface, #FFFFFF); - border: 1px solid var(--border, #E4DFD8); - border-radius: var(--radius-md, 8px); + background: var(--bg-surface); + border: 1px solid var(--border); + border-radius: var(--radius-md); } .svg { @@ -25,7 +25,7 @@ width: 100%; height: 100%; min-height: 300px; - color: var(--text-muted, #9C9184); + color: var(--text-muted); font-size: 14px; } @@ -36,7 +36,7 @@ width: 100%; height: 100%; min-height: 300px; - color: var(--error, #C0392B); + color: var(--error); font-size: 14px; } @@ -47,11 +47,11 @@ display: flex; align-items: center; gap: 4px; - background: var(--bg-surface, #FFFFFF); - border: 1px solid var(--border, #E4DFD8); - border-radius: var(--radius-sm, 5px); + background: var(--bg-surface); + border: 1px solid var(--border); + border-radius: var(--radius-sm); padding: 4px; - box-shadow: var(--shadow-md, 0 2px 8px rgba(44, 37, 32, 0.08)); + box-shadow: var(--shadow-md); } .zoomBtn { @@ -62,19 +62,19 @@ height: 28px; border: none; background: transparent; - color: var(--text-primary, #1A1612); + color: var(--text-primary); font-size: 16px; cursor: pointer; - border-radius: var(--radius-sm, 5px); + border-radius: var(--radius-sm); } .zoomBtn:hover { - background: var(--bg-hover, #F5F0EA); + background: var(--bg-hover); } .zoomLevel { font-size: 12px; - color: var(--text-muted, #9C9184); + color: var(--text-muted); min-width: 36px; text-align: center; font-variant-numeric: tabular-nums; @@ -87,10 +87,10 @@ display: flex; align-items: center; padding: 4px 10px; - background: var(--bg-surface, #FFFFFF); - border: 1px solid var(--border, #E4DFD8); - border-radius: var(--radius-sm, 5px); - box-shadow: var(--shadow-sm, 0 1px 2px rgba(44, 37, 32, 0.06)); + background: var(--bg-surface); + border: 1px solid var(--border); + border-radius: var(--radius-sm); + box-shadow: var(--shadow-sm); z-index: 10; font-size: 12px; } @@ -102,13 +102,13 @@ .breadcrumbSep { margin: 0 6px; - color: var(--text-muted, #9C9184); + color: var(--text-muted); } .breadcrumbLink { background: none; border: none; - color: var(--running, #1A7F8E); + color: var(--running); cursor: pointer; padding: 0; font-size: 12px; @@ -120,7 +120,7 @@ } .breadcrumbCurrent { - color: var(--text-primary, #1A1612); + color: var(--text-primary); font-weight: 600; } @@ -128,9 +128,9 @@ position: absolute; bottom: 52px; right: 12px; - border: 1px solid var(--border, #E4DFD8); - border-radius: var(--radius-sm, 5px); - box-shadow: var(--shadow-md, 0 2px 8px rgba(44, 37, 32, 0.08)); + border: 1px solid var(--border); + border-radius: var(--radius-sm); + box-shadow: var(--shadow-md); overflow: hidden; z-index: 5; } @@ -141,10 +141,10 @@ align-items: center; gap: 2px; padding: 3px 4px; - background: var(--bg-surface, #FFFFFF); - border: 1px solid var(--border, #E4DFD8); - border-radius: var(--radius-sm, 5px); - box-shadow: var(--shadow-lg, 0 4px 16px rgba(44, 37, 32, 0.10)); + background: var(--bg-surface); + border: 1px solid var(--border); + border-radius: var(--radius-sm); + box-shadow: var(--shadow-lg); transform: translate(-50%, -100%); margin-top: -6px; z-index: 10; @@ -159,31 +159,31 @@ height: 26px; border: none; background: transparent; - color: var(--text-secondary, #5C5347); + color: var(--text-secondary); font-size: 12px; cursor: pointer; - border-radius: var(--radius-sm, 5px); + border-radius: var(--radius-sm); padding: 0; } .nodeToolbarBtn:hover { - background: var(--bg-hover, #F5F0EA); - color: var(--text-primary, #1A1612); + background: var(--bg-hover); + color: var(--text-primary); } .nodeToolbarBtnActive { - background: var(--bg-hover, #F5F0EA); + background: var(--bg-hover); } .iterationStepper { display: flex; align-items: center; gap: 2px; - background: rgba(255, 255, 255, 0.15); + background: color-mix(in srgb, var(--bg-surface) 15%, transparent); border-radius: 3px; padding: 1px 3px; font-size: 12px; - color: white; + color: var(--text-primary); font-family: inherit; } @@ -191,8 +191,8 @@ width: 16px; height: 16px; border: none; - background: rgba(255, 255, 255, 0.2); - color: white; + background: color-mix(in srgb, var(--bg-surface) 20%, transparent); + color: var(--text-primary); border-radius: 2px; cursor: pointer; font-size: 12px; diff --git a/ui/src/components/ProcessDiagram/ProcessDiagram.tsx b/ui/src/components/ProcessDiagram/ProcessDiagram.tsx index 917650ab..f1414ce3 100644 --- a/ui/src/components/ProcessDiagram/ProcessDiagram.tsx +++ b/ui/src/components/ProcessDiagram/ProcessDiagram.tsx @@ -294,7 +294,7 @@ export function ProcessDiagram({ refY="3" orient="auto" > - + - + diff --git a/ui/src/pages/Admin/AdminLayout.module.css b/ui/src/pages/Admin/AdminLayout.module.css new file mode 100644 index 00000000..207f7601 --- /dev/null +++ b/ui/src/pages/Admin/AdminLayout.module.css @@ -0,0 +1,6 @@ +.content { + flex: 1; + overflow: auto; + min-height: 0; + padding: 20px 24px 40px; +} diff --git a/ui/src/pages/Admin/AdminLayout.tsx b/ui/src/pages/Admin/AdminLayout.tsx index 5a36b3c7..c72d205a 100644 --- a/ui/src/pages/Admin/AdminLayout.tsx +++ b/ui/src/pages/Admin/AdminLayout.tsx @@ -1,8 +1,9 @@ import { Outlet } from 'react-router'; +import styles from './AdminLayout.module.css'; export default function AdminLayout() { return ( -
+
); diff --git a/ui/src/pages/Admin/AppConfigDetailPage.module.css b/ui/src/pages/Admin/AppConfigDetailPage.module.css index b0ebd187..76a07f66 100644 --- a/ui/src/pages/Admin/AppConfigDetailPage.module.css +++ b/ui/src/pages/Admin/AppConfigDetailPage.module.css @@ -103,18 +103,6 @@ color: var(--text-muted); } -.section { - margin-bottom: 16px; - display: flex; - flex-direction: column; - gap: 12px; - background: var(--bg-surface); - border: 1px solid var(--border-subtle); - border-radius: var(--radius-lg); - box-shadow: var(--shadow-card); - padding: 16px 20px; -} - .sectionSummary { font-size: 12px; color: var(--text-muted); diff --git a/ui/src/pages/Admin/AppConfigDetailPage.tsx b/ui/src/pages/Admin/AppConfigDetailPage.tsx index 238c30c0..7b0f2529 100644 --- a/ui/src/pages/Admin/AppConfigDetailPage.tsx +++ b/ui/src/pages/Admin/AppConfigDetailPage.tsx @@ -11,6 +11,7 @@ import { useCatalog } from '../../api/queries/catalog'; import type { CatalogApp, CatalogRoute } from '../../api/queries/catalog'; import { applyTracedProcessorUpdate, applyRouteRecordingUpdate } from '../../utils/config-draft-utils'; import styles from './AppConfigDetailPage.module.css'; +import sectionStyles from '../../styles/section-card.module.css'; type BadgeColor = 'primary' | 'success' | 'warning' | 'error' | 'running' | 'auto'; @@ -325,7 +326,7 @@ export default function AppConfigDetailPage() {
{/* ── Settings ──────────────────────────────────────────────────── */} -
+
Settings
@@ -424,7 +425,7 @@ export default function AppConfigDetailPage() {
{/* ── Traces & Taps ─────────────────────────────────────────────── */} -
+
Traces & Taps {tracedCount} traced · {tapCount} taps · manage taps on route pages @@ -440,7 +441,7 @@ export default function AppConfigDetailPage() {
{/* ── Route Recording ───────────────────────────────────────────── */} -
+
Route Recording {recordingCount} of {routeRecordingRows.length} routes recording diff --git a/ui/src/pages/Admin/AuditLogPage.module.css b/ui/src/pages/Admin/AuditLogPage.module.css index 57a4ac86..96374779 100644 --- a/ui/src/pages/Admin/AuditLogPage.module.css +++ b/ui/src/pages/Admin/AuditLogPage.module.css @@ -13,39 +13,6 @@ width: 160px; } -.tableSection { - background: var(--bg-surface); - border: 1px solid var(--border-subtle); - border-radius: var(--radius-lg); - box-shadow: var(--shadow-card); - overflow: hidden; -} - -.tableHeader { - display: flex; - align-items: center; - justify-content: space-between; - padding: 12px 16px; - border-bottom: 1px solid var(--border-subtle); -} - -.tableTitle { - font-size: 13px; - font-weight: 600; - color: var(--text-primary); -} - -.tableRight { - display: flex; - align-items: center; - gap: 10px; -} - -.tableMeta { - font-size: 12px; - color: var(--text-muted); -} - .target { display: inline-block; max-width: 220px; diff --git a/ui/src/pages/Admin/AuditLogPage.tsx b/ui/src/pages/Admin/AuditLogPage.tsx index 841748bf..2c1ca4f5 100644 --- a/ui/src/pages/Admin/AuditLogPage.tsx +++ b/ui/src/pages/Admin/AuditLogPage.tsx @@ -5,6 +5,7 @@ import { import type { Column } from '@cameleer/design-system'; import { useAuditLog, type AuditEvent } from '../../api/queries/admin/audit'; import styles from './AuditLogPage.module.css'; +import tableStyles from '../../styles/table-section.module.css'; const CATEGORIES = [ { value: '', label: 'All categories' }, @@ -117,11 +118,11 @@ export default function AuditLogPage() { />
-
-
- Audit Log -
- +
+
+ Audit Log +
+ {totalCount} events diff --git a/ui/src/pages/Admin/ClickHouseAdminPage.module.css b/ui/src/pages/Admin/ClickHouseAdminPage.module.css index 1c9ca34d..6123c7d3 100644 --- a/ui/src/pages/Admin/ClickHouseAdminPage.module.css +++ b/ui/src/pages/Admin/ClickHouseAdminPage.module.css @@ -34,32 +34,7 @@ } .tableSection { - background: var(--bg-surface); - border: 1px solid var(--border-subtle); - border-radius: var(--radius-lg); - box-shadow: var(--shadow-card); margin-bottom: 16px; - overflow: hidden; -} - -.tableHeader { - display: flex; - align-items: center; - justify-content: space-between; - padding: 12px 16px; - border-bottom: 1px solid var(--border-subtle); -} - -.tableTitle { - font-size: 13px; - font-weight: 600; - color: var(--text-primary); -} - -.tableMeta { - font-size: 12px; - color: var(--text-muted); - font-family: var(--font-mono); } .queryText { diff --git a/ui/src/pages/Admin/ClickHouseAdminPage.tsx b/ui/src/pages/Admin/ClickHouseAdminPage.tsx index 0bc3b4a1..34e22dd0 100644 --- a/ui/src/pages/Admin/ClickHouseAdminPage.tsx +++ b/ui/src/pages/Admin/ClickHouseAdminPage.tsx @@ -2,6 +2,7 @@ import { StatCard, DataTable, ProgressBar } from '@cameleer/design-system'; import type { Column } from '@cameleer/design-system'; import { useClickHouseStatus, useClickHouseTables, useClickHousePerformance, useClickHouseQueries, useIndexerPipeline } from '../../api/queries/admin/clickhouse'; import styles from './ClickHouseAdminPage.module.css'; +import tableStyles from '../../styles/table-section.module.css'; export default function ClickHouseAdminPage() { const { data: status, isError: statusError } = useClickHouseStatus(); @@ -65,10 +66,10 @@ export default function ClickHouseAdminPage() { )} {/* Tables */} -
-
- Tables ({(tables || []).length}) - {totalSizeLabel && {totalSizeLabel} total} +
+
+ Tables ({(tables || []).length}) + {totalSizeLabel && {totalSizeLabel} total}
{/* Active Queries */} -
-
- Active Queries ({(queries || []).length}) +
+
+ Active Queries ({(queries || []).length})
`${v}s` }, { key: 'state', header: 'State', render: (v) => }, - { key: 'query', header: 'Query', render: (v) => {String(v).slice(0, 80)} }, + { key: 'query', header: 'Query', render: (v) => {String(v).slice(0, 80)} }, { key: 'pid', header: '', width: '80px', render: (v) => , @@ -32,19 +33,19 @@ export default function DatabaseAdminPage() { return (
-

Database Administration

+
Database Administration
-
+
{pool && ( -
-

Connection Pool

+
+
Connection Pool
-
+
Active: {pool.activeConnections} Idle: {pool.idleConnections} Max: {pool.maximumPoolSize} @@ -53,13 +54,13 @@ export default function DatabaseAdminPage() { )} -
-

Tables

+
+
Tables
({ ...t, id: t.tableName }))} sortable pageSize={20} />
-
-

Active Queries

+
+
Active Queries
({ ...q, id: String(q.pid) }))} />
diff --git a/ui/src/pages/Admin/OidcConfigPage.module.css b/ui/src/pages/Admin/OidcConfigPage.module.css index a66d9751..868433c5 100644 --- a/ui/src/pages/Admin/OidcConfigPage.module.css +++ b/ui/src/pages/Admin/OidcConfigPage.module.css @@ -10,18 +10,6 @@ margin-bottom: 20px; } -.section { - margin-bottom: 16px; - display: flex; - flex-direction: column; - gap: 12px; - background: var(--bg-surface); - border: 1px solid var(--border-subtle); - border-radius: var(--radius-lg); - box-shadow: var(--shadow-card); - padding: 16px 20px; -} - .toggleRow { display: flex; align-items: center; diff --git a/ui/src/pages/Admin/OidcConfigPage.tsx b/ui/src/pages/Admin/OidcConfigPage.tsx index 56a5b0b7..e8eb357c 100644 --- a/ui/src/pages/Admin/OidcConfigPage.tsx +++ b/ui/src/pages/Admin/OidcConfigPage.tsx @@ -5,6 +5,7 @@ import { import { useToast } from '@cameleer/design-system'; import { adminFetch } from '../../api/queries/admin/admin-api'; import styles from './OidcConfigPage.module.css'; +import sectionStyles from '../../styles/section-card.module.css'; interface OidcFormData { enabled: boolean; @@ -137,7 +138,7 @@ export default function OidcConfigPage() { {error &&
{error}
} -
+
Behavior
-
+
Provider Settings
-
+
Claim Mapping
-
+
Default Roles
{(form.defaultRoles || []).map((role) => ( @@ -249,7 +250,7 @@ export default function OidcConfigPage() {
-
+
Danger Zone -
-
-
+
+
setLogSearch(e.target.value)} @@ -534,7 +535,7 @@ export default function AgentHealth() { {logSearch && (
{logLevels.size > 0 && ( - )} @@ -552,7 +553,7 @@ export default function AgentHealth() { {filteredLogs.length > 0 ? ( ) : ( -
+
{logSearch || logLevels.size > 0 ? 'No matching log entries' : 'No log entries available'}
)} @@ -561,12 +562,12 @@ export default function AgentHealth() {
Timeline -
+
{feedEvents.length} events - -
@@ -574,7 +575,7 @@ export default function AgentHealth() { {feedEvents.length > 0 ? ( ) : ( -
No events in the selected time range.
+
No events in the selected time range.
)}
diff --git a/ui/src/pages/AgentInstance/AgentInstance.module.css b/ui/src/pages/AgentInstance/AgentInstance.module.css index fa661907..f7198378 100644 --- a/ui/src/pages/AgentInstance/AgentInstance.module.css +++ b/ui/src/pages/AgentInstance/AgentInstance.module.css @@ -90,15 +90,6 @@ margin-bottom: 20px; } -.chartCard { - background: var(--bg-surface); - border: 1px solid var(--border-subtle); - border-radius: var(--radius-lg); - box-shadow: var(--shadow-card); - padding: 16px; - overflow: hidden; -} - .chartHeader { display: flex; align-items: center; @@ -125,121 +116,6 @@ gap: 14px; } -/* Log viewer */ -.logCard { - background: var(--bg-surface); - border: 1px solid var(--border-subtle); - border-radius: var(--radius-lg); - box-shadow: var(--shadow-card); - overflow: hidden; - display: flex; - flex-direction: column; - max-height: 420px; -} - -.logHeader { - display: flex; - align-items: center; - justify-content: space-between; - padding: 12px 16px; - border-bottom: 1px solid var(--border-subtle); -} - -.headerActions { - display: flex; - align-items: center; - gap: 6px; -} - -.sortBtn, -.refreshBtn { - background: none; - border: 1px solid var(--border-subtle); - border-radius: var(--radius-sm); - color: var(--text-muted); - cursor: pointer; - font-size: 13px; - padding: 2px 6px; - line-height: 1; -} - -.sortBtn:hover, -.refreshBtn:hover { - color: var(--text-primary); - border-color: var(--amber); -} - -.logToolbar { - display: flex; - align-items: center; - gap: 8px; - padding: 8px 12px; - border-bottom: 1px solid var(--border-subtle); - background: var(--bg-surface); -} - -.logSearchWrap { - position: relative; - flex: 1; - min-width: 0; -} - -.logSearchInput { - width: 100%; - padding: 5px 28px 5px 10px; - border: 1px solid var(--border-subtle); - border-radius: var(--radius-sm); - background: var(--bg-body); - color: var(--text-primary); - font-size: 12px; - font-family: var(--font-body); - outline: none; -} - -.logSearchInput:focus { - border-color: var(--amber); -} - -.logSearchInput::placeholder { - color: var(--text-faint); -} - -.logSearchClear { - position: absolute; - right: 4px; - top: 50%; - transform: translateY(-50%); - background: none; - border: none; - color: var(--text-muted); - cursor: pointer; - font-size: 14px; - padding: 0 4px; - line-height: 1; -} - -.logClearFilters { - background: none; - border: none; - color: var(--text-muted); - font-size: 12px; - cursor: pointer; - padding: 2px 6px; - white-space: nowrap; -} - -.logClearFilters:hover { - color: var(--text-primary); -} - -/* Empty state (shared) */ -.logEmpty { - padding: 24px; - text-align: center; - color: var(--text-faint); - font-size: 12px; -} - /* Timeline card */ .timelineCard { background: var(--bg-surface); diff --git a/ui/src/pages/AgentInstance/AgentInstance.tsx b/ui/src/pages/AgentInstance/AgentInstance.tsx index 592639ec..6d7e7a8b 100644 --- a/ui/src/pages/AgentInstance/AgentInstance.tsx +++ b/ui/src/pages/AgentInstance/AgentInstance.tsx @@ -8,6 +8,8 @@ import { } from '@cameleer/design-system'; import type { FeedEvent, LogEntry, ButtonGroupItem } from '@cameleer/design-system'; import styles from './AgentInstance.module.css'; +import logStyles from '../../styles/log-panel.module.css'; +import chartCardStyles from '../../styles/chart-card.module.css'; import { useAgents, useAgentEvents } from '../../api/queries/agents'; import { useApplicationLogs } from '../../api/queries/logs'; import { useStatsTimeseries } from '../../api/queries/executions'; @@ -290,7 +292,7 @@ export default function AgentInstance() { {/* Charts grid — 3x2 */}
-
+
CPU Usage @@ -309,7 +311,7 @@ export default function AgentInstance() { )}
-
+
Memory (Heap) @@ -325,7 +327,7 @@ export default function AgentInstance() { )}
-
+
Throughput @@ -339,7 +341,7 @@ export default function AgentInstance() { )}
-
+
Error Rate @@ -353,7 +355,7 @@ export default function AgentInstance() { )}
-
+
Thread Count @@ -369,7 +371,7 @@ export default function AgentInstance() { )}
-
+
GC Pauses @@ -384,24 +386,24 @@ export default function AgentInstance() { {/* Log + Timeline side by side */}
-
-
+
+
Application Log -
+
{logEntries.length} entries - -
-
-
+
+
setLogSearch(e.target.value)} @@ -410,7 +412,7 @@ export default function AgentInstance() { {logSearch && (
{logLevels.size > 0 && ( - )} @@ -428,7 +430,7 @@ export default function AgentInstance() { {filteredLogs.length > 0 ? ( ) : ( -
+
{logSearch || logLevels.size > 0 ? 'No matching log entries' : 'No log entries available'}
)} @@ -437,12 +439,12 @@ export default function AgentInstance() {
Timeline -
+
{feedEvents.length} events - -
@@ -450,7 +452,7 @@ export default function AgentInstance() { {feedEvents.length > 0 ? ( ) : ( -
No events in the selected time range.
+
No events in the selected time range.
)}
diff --git a/ui/src/pages/AppsTab/AppsTab.module.css b/ui/src/pages/AppsTab/AppsTab.module.css index 33e48e55..b928786b 100644 --- a/ui/src/pages/AppsTab/AppsTab.module.css +++ b/ui/src/pages/AppsTab/AppsTab.module.css @@ -57,7 +57,7 @@ .stepIndicator { font-size: 12px; - color: var(--accent, #6c7aff); + color: var(--amber); font-style: italic; } @@ -143,8 +143,8 @@ } .subTabActive { - color: var(--accent, #6c7aff); - border-bottom-color: var(--accent, #6c7aff); + color: var(--amber); + border-bottom-color: var(--amber); } /* Table */ @@ -230,7 +230,7 @@ .editBannerActive { border-color: var(--warning); - background: rgba(251, 191, 36, 0.06); + background: color-mix(in srgb, var(--amber) 6%, transparent); } .editBannerText { @@ -432,3 +432,44 @@ .removeBtn:hover { color: var(--error); } + +/* Visually hidden file inputs */ +.visuallyHidden { + position: absolute; + width: 1px; + height: 1px; + padding: 0; + margin: -1px; + overflow: hidden; + clip: rect(0, 0, 0, 0); + white-space: nowrap; + border: 0; +} + +/* Fixed-width inputs */ +.inputXs { + width: 50px; +} + +.inputSm { + width: 60px; +} + +.inputMd { + width: 70px; +} + +.inputLg { + width: 80px; +} + +.inputXl { + width: 90px; +} + +/* Table cell flex layout */ +.cellFlex { + display: flex; + align-items: center; + gap: 4px; +} diff --git a/ui/src/pages/AppsTab/AppsTab.tsx b/ui/src/pages/AppsTab/AppsTab.tsx index 3363085e..fe8cec96 100644 --- a/ui/src/pages/AppsTab/AppsTab.tsx +++ b/ui/src/pages/AppsTab/AppsTab.tsx @@ -301,7 +301,7 @@ function CreateAppView({ environments, selectedEnv }: { environments: Environmen Application JAR
setFile(e.target.files?.[0] ?? null)} /> @@ -636,7 +636,7 @@ function OverviewSubTab({ app, deployments, versions, environments, envMap, sele - + @@ -962,8 +962,8 @@ function ConfigSubTab({ app, environment }: { app: App; environment?: Environmen Max Payload Size
- setPayloadSize(e.target.value)} style={{ width: 70 }} /> - setPayloadSize(e.target.value)} className={styles.inputMd} /> + setMetricsInterval(e.target.value)} style={{ width: 50 }} /> + setMetricsInterval(e.target.value)} className={styles.inputXs} /> s
Sampling Rate - setSamplingRate(e.target.value)} style={{ width: 80 }} /> + setSamplingRate(e.target.value)} className={styles.inputLg} /> Compress Success
@@ -1032,25 +1032,25 @@ function ConfigSubTab({ app, environment }: { app: App; environment?: Environmen
Memory Limit
- setMemoryLimit(e.target.value)} style={{ width: 80 }} /> + setMemoryLimit(e.target.value)} className={styles.inputLg} /> MB
Memory Reserve
- setMemoryReserve(e.target.value)} placeholder="---" style={{ width: 80 }} /> + setMemoryReserve(e.target.value)} placeholder="---" className={styles.inputLg} /> MB
{!isProd && Available in production environments only}
CPU Request - setCpuRequest(e.target.value)} style={{ width: 80 }} /> + setCpuRequest(e.target.value)} className={styles.inputLg} /> CPU Limit
- setCpuLimit(e.target.value)} placeholder="e.g. 1000" style={{ width: 80 }} /> + setCpuLimit(e.target.value)} placeholder="e.g. 1000" className={styles.inputLg} /> millicores
@@ -1069,10 +1069,10 @@ function ConfigSubTab({ app, environment }: { app: App; environment?: Environmen
App Port - setAppPort(e.target.value)} style={{ width: 80 }} /> + setAppPort(e.target.value)} className={styles.inputLg} /> Replicas - setReplicas(e.target.value)} style={{ width: 60 }} type="number" /> + setReplicas(e.target.value)} className={styles.inputSm} type="number" /> Deploy Strategy 0 ? recentExchangeOptions : [{ value: '', label: 'No recent exchanges' }]} value={testExchangeId} @@ -942,7 +946,7 @@ export default function RouteDetail() { )} {testTab === 'custom' && ( -
+