@@ -424,7 +424,7 @@ export function CodeCaptcha({
// (panel-centered) sat above it.
What is:
-
+
{mathProblem} = ?
diff --git a/packages/web/src/components/GuestModeDialog.tsx b/packages/web/src/components/GuestModeDialog.tsx
index 599af899..d1c8b6ca 100644
--- a/packages/web/src/components/GuestModeDialog.tsx
+++ b/packages/web/src/components/GuestModeDialog.tsx
@@ -31,7 +31,7 @@ export function GuestModeDialog({ isOpen, onClose, onConfirm }: GuestModeDialogP
onClick={onClose}
>
e.stopPropagation()}
>
diff --git a/packages/web/src/components/InteractiveGraphVisualization.tsx b/packages/web/src/components/InteractiveGraphVisualization.tsx
index 26435cd8..c18e7236 100644
--- a/packages/web/src/components/InteractiveGraphVisualization.tsx
+++ b/packages/web/src/components/InteractiveGraphVisualization.tsx
@@ -3671,6 +3671,13 @@ export function InteractiveGraphVisualization({ onResetLayout, onNodeSelected }:
if (obstacles) {
placedLabels.push({ x: placement.x, y: placement.y, width: labelW + 8, height: labelH + 8 });
}
+ // edgeLabelPlacement keeps text upright by stripping 180° when the edge
+ // points "backward" — which leaves the directional label icon pointing
+ // the wrong way after a flip. Carry that lost 180° on the icon so its
+ // arrow tracks the real edge direction (and flips when the edge flips).
+ const trueAngle = (Math.atan2(target.y - source.y, target.x - source.x) * 180) / Math.PI;
+ const iconFlipped = trueAngle > 90 || trueAngle < -90;
+ d3.select(this).select('.edge-label-icon').attr('transform', iconFlipped ? 'rotate(180)' : null);
return `translate(${placement.x},${placement.y}) rotate(${placement.rotation})`;
});
};
diff --git a/packages/web/src/pages/Workspace.tsx b/packages/web/src/pages/Workspace.tsx
index ced7c1c6..e9826c85 100644
--- a/packages/web/src/pages/Workspace.tsx
+++ b/packages/web/src/pages/Workspace.tsx
@@ -221,21 +221,22 @@ export function Workspace() {
- {/* Right Section: Status and Actions */}
-
- {/* Neo4j Status Indicator */}
+ {/* Right Section: Status and Actions — hidden on mobile (the hamburger
+ handles nav there); these chips otherwise eat the small-screen width. */}
+
+ {/* Graph store status (provider-agnostic — core is Neo4j-optional) */}
- {health?.services?.neo4j?.status === 'healthy' ? 'Neo4j GraphDB' : 'Neo4j GraphDB Offline'}
+ {health?.services?.neo4j?.status === 'healthy' ? 'Graph DB' : 'Graph DB Offline'}