+ {/* Loading overlay — keeps old content visible while fetching next */}
+ {loading && (
+
+
+
+ )}
- {detail && (
+ {error && (
+
+ )}
+
+ {!error && detail && (
<>
{/* Metadata bar */}
-
+
navigator.clipboard.writeText(detail.hash)}
@@ -81,26 +134,33 @@ export function GitCommitDrawer({ hash, onClose }: Props) {
{detail.date}
-
- +{detail.files.reduce((a, f) => a + f.additions, 0)}
+ {totalAdds > 0 && (
+ +{totalAdds}
+ )}
+ {totalDels > 0 && (
+ -{totalDels}
+ )}
+
+ {detail.files.length} file{detail.files.length !== 1 ? 's' : ''}
-
- -{detail.files.reduce((a, f) => a + f.deletions, 0)}
-
- {detail.files.length} file{detail.files.length !== 1 ? 's' : ''}
- {/* Commit body if multiline */}
+ {/* Extended commit message */}
{detail.body.trim() !== detail.subject.trim() && (
{detail.body.trim()}
)}
- {/* Diff */}
- {diffHtml
- ?
- :
- }
+ {/* Per-file diffs */}
+ {detail.files.length === 0 ? (
+
+ ) : (
+
+ {detail.files.map(f => (
+
+ ))}
+
+ )}
>
)}
@@ -109,7 +169,8 @@ export function GitCommitDrawer({ hash, onClose }: Props) {
)}
+ {/* Footer — sticky at bottom */}
+
diff --git a/clarity.controlplane/src/index.css b/clarity.controlplane/src/index.css
index 310f67a..9ac0cbc 100644
--- a/clarity.controlplane/src/index.css
+++ b/clarity.controlplane/src/index.css
@@ -817,10 +817,50 @@ body {
}
/* ── Git Commit Drawer ──────────────────────────────────────────────────────── */
-.git-commit-drawer .bp5-drawer-header {
+
+/* Drawer shell: full-height flex column */
+.git-commit-drawer.bp6-drawer {
+ display: flex;
+ flex-direction: column;
+ height: 100%;
+ overflow: hidden;
+}
+
+.git-commit-drawer .bp6-drawer-header {
+ flex-shrink: 0;
padding: 0.75rem 1rem;
}
+/*
+ * .gcd-body is the scrollable content area.
+ * Blueprint v6 renders children directly inside .bp6-drawer — no body wrapper.
+ */
+.git-commit-drawer .gcd-body {
+ flex: 1 1 0; /* 0 basis — don't size from content, allow shrink */
+ min-height: 0; /* flex children won't shrink past content without this */
+ overflow-y: auto;
+ overflow-x: hidden;
+ padding: 1rem;
+ display: flex;
+ flex-direction: column;
+ gap: 1rem;
+ position: relative; /* loading overlay anchor */
+}
+
+/* Children of the scroll container must NOT shrink — if they do, content
+ * never overflows and the scrollbar never appears. */
+.git-commit-drawer .gcd-body > * {
+ flex-shrink: 0;
+}
+
+/* Footer rendered as last child — sits below the scroll area */
+.git-commit-drawer .gcd-footer {
+ flex-shrink: 0;
+ padding: 0.5rem 1rem;
+ display: flex;
+ justify-content: flex-end;
+}
+
.git-drawer-title {
display: flex;
align-items: center;
@@ -838,6 +878,95 @@ body {
font-family: 'JetBrains Mono', 'Fira Code', monospace;
}
+/* Loading overlay — keeps old diff visible while fetching next commit */
+.gcd-loading-overlay {
+ position: absolute;
+ inset: 0;
+ background: rgba(255, 255, 255, 0.7);
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ z-index: 10;
+ pointer-events: none;
+}
+
+/* Per-file accordion */
+.gcd-files-list {
+ display: flex;
+ flex-direction: column;
+ gap: 0;
+ border: 1px solid #dce0e6;
+ border-radius: 6px;
+ overflow: hidden;
+ margin: 0.75rem 0;
+}
+
+.gcd-file-section {
+ border-bottom: 1px solid #dce0e6;
+}
+
+.gcd-file-section:last-child {
+ border-bottom: none;
+}
+
+.gcd-file-header {
+ all: unset;
+ box-sizing: border-box;
+ display: flex;
+ align-items: center;
+ gap: 0.5rem;
+ width: 100%;
+ padding: 0.45rem 0.75rem;
+ background: #f6f8fa;
+ cursor: pointer;
+ user-select: none;
+ transition: background 0.1s;
+ font-family: 'JetBrains Mono', 'Fira Code', monospace;
+ font-size: 0.78rem;
+ color: #1c2127;
+}
+
+.gcd-file-header:hover,
+.gcd-file-header--open {
+ background: #edf2f7;
+}
+
+.gcd-file-chevron {
+ flex-shrink: 0;
+ color: #738091;
+}
+
+.gcd-file-status-icon {
+ flex-shrink: 0;
+}
+
+.gcd-file-path {
+ flex: 1;
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ min-width: 0;
+}
+
+.gcd-file-stats {
+ display: flex;
+ gap: 0.4rem;
+ flex-shrink: 0;
+ font-size: 0.73rem;
+ font-family: 'JetBrains Mono', 'Fira Code', monospace;
+}
+
+.gcd-adds { color: #1a7f37; font-weight: 600; }
+.gcd-dels { color: #cf222e; font-weight: 600; }
+
+.gcd-no-diff {
+ padding: 0.6rem 1rem;
+ font-size: 0.8rem;
+ color: #738091;
+ font-style: italic;
+ background: #fafafa;
+}
+
.git-drawer-subject {
font-size: 0.92rem;
font-weight: 600;
@@ -847,21 +976,6 @@ body {
color: #1c2127;
}
-.git-drawer-body {
- flex: 1;
- overflow-y: auto;
- padding: 1rem;
- display: flex;
- flex-direction: column;
- gap: 1rem;
-}
-
-.git-drawer-footer {
- padding: 0.75rem 1rem;
- border-top: 1px solid #d3d8de;
- display: flex;
- justify-content: flex-end;
-}
.git-commit-meta-bar {
display: flex;
@@ -928,7 +1042,8 @@ body {
font-size: 0.78rem;
line-height: 1.45;
border-radius: 6px;
- overflow: hidden;
+ overflow-x: auto; /* horizontal scroll for wide diffs, not clip */
+ overflow-y: visible;
border: 1px solid #d0d7de;
}
diff --git a/clarity.controlplane/src/opc/OpcPage.tsx b/clarity.controlplane/src/opc/OpcPage.tsx
index 67d2366..920f4f9 100644
--- a/clarity.controlplane/src/opc/OpcPage.tsx
+++ b/clarity.controlplane/src/opc/OpcPage.tsx
@@ -76,7 +76,7 @@ const SDLC_STAGES: { branch: string; label: string; intent: Intent }[] = [
{ branch: 'develop', label: 'Dev', intent: Intent.PRIMARY },
{ branch: 'staging', label: 'Staging', intent: Intent.WARNING },
{ branch: 'uat', label: 'UAT', intent: Intent.DANGER },
- { branch: 'master', label: 'Production', intent: Intent.SUCCESS },
+ { branch: 'main', label: 'Production', intent: Intent.SUCCESS },
];
function deriveSdlcSummary(coverage: BranchCoverage[]): { label: string; intent: Intent } | null {