diff --git a/Frontend/public/landing-logos/git.svg b/Frontend/public/landing-logos/git.svg
new file mode 100644
index 0000000..13af359
--- /dev/null
+++ b/Frontend/public/landing-logos/git.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/Frontend/public/landing-logos/githubcopilot.svg b/Frontend/public/landing-logos/githubcopilot.svg
new file mode 100644
index 0000000..f064947
--- /dev/null
+++ b/Frontend/public/landing-logos/githubcopilot.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/Frontend/public/landing-logos/gitlens-mark.svg b/Frontend/public/landing-logos/gitlens-mark.svg
new file mode 100644
index 0000000..a05137c
--- /dev/null
+++ b/Frontend/public/landing-logos/gitlens-mark.svg
@@ -0,0 +1,8 @@
+
diff --git a/Frontend/src/RootLayout.tsx b/Frontend/src/RootLayout.tsx
index 0398022..ddfba6f 100644
--- a/Frontend/src/RootLayout.tsx
+++ b/Frontend/src/RootLayout.tsx
@@ -18,7 +18,7 @@ function MainChrome() {
{hasNav && }
diff --git a/Frontend/src/components/ChatPanel.tsx b/Frontend/src/components/ChatPanel.tsx
index f662ddf..7f10c10 100644
--- a/Frontend/src/components/ChatPanel.tsx
+++ b/Frontend/src/components/ChatPanel.tsx
@@ -260,7 +260,7 @@ export function ChatPanel({ onChatComplete }: { onChatComplete?: () => void } =
}
const armorNote =
res.armorAgent && Array.isArray(res.enforcementLog)
- ? `\n\n---\n_ArmorClaw:_ ${res.enforcementLog.length} policy check(s) — ${res.enforcementLog.filter((e) => e.action === "deny").length} blocked. See **ArmorClaw enforcement** below._`
+ ? `\n\n---\n_ArmorClaw:_ ${res.enforcementLog.length} policy check(s); ${res.enforcementLog.filter((e) => e.action === "deny").length} blocked. See **ArmorClaw enforcement** below._`
: "";
setMessages((prev) => [
...prev,
@@ -414,7 +414,7 @@ export function ChatPanel({ onChatComplete }: { onChatComplete?: () => void } =
Synthesis: offline (no API key)
)}
{msg.synthesis === "fallback_error" && (
- Synthesis: Gemini error — raw matches shown
+ Synthesis: Gemini error; raw matches shown
)}
)}
diff --git a/Frontend/src/components/EnforcementLog.tsx b/Frontend/src/components/EnforcementLog.tsx
index 035bc02..fad01e9 100644
--- a/Frontend/src/components/EnforcementLog.tsx
+++ b/Frontend/src/components/EnforcementLog.tsx
@@ -76,7 +76,7 @@ export function EnforcementLog({ refreshKey = 0 }: Props) {
typeof parsed !== "object" ||
Array.isArray(parsed)
) {
- setTestResult("Params must be a JSON object, e.g. {} or {\"path\":\"README.md\"} — not an array or null.");
+ setTestResult("Params must be a JSON object, e.g. {} or {\"path\":\"README.md\"}; not an array or null.");
return;
}
params = parsed as Record;
@@ -90,7 +90,7 @@ export function EnforcementLog({ refreshKey = 0 }: Props) {
const repo = `${target.owner}/${target.name}`;
const r = await postEnforcementTest({ tool: testTool, params, repo });
setTestResult(
- `${r.allowed ? "ALLOWED" : "BLOCKED"} — ${r.policy_rule} (${r.risk_level})\n${r.reason}`
+ `${r.allowed ? "ALLOWED" : "BLOCKED"}: ${r.policy_rule} (${r.risk_level})\n${r.reason}`
);
} catch (e) {
setTestResult(e instanceof Error ? e.message : "Test failed");
diff --git a/Frontend/src/components/IngestButton.tsx b/Frontend/src/components/IngestButton.tsx
index b34e1fd..5b77d29 100644
--- a/Frontend/src/components/IngestButton.tsx
+++ b/Frontend/src/components/IngestButton.tsx
@@ -19,7 +19,7 @@ export function IngestButton({ onComplete }: { onComplete?: () => void }) {
useEffect(() => {
if (prevStatus.current === "running" && status === "done") {
toast({
- message: `Knowledge Graph built — ${nodeCount} decision${nodeCount === 1 ? "" : "s"} found`,
+ message: `Knowledge Graph built: ${nodeCount} decision${nodeCount === 1 ? "" : "s"} found`,
type: "success",
});
}
@@ -105,7 +105,7 @@ export function IngestButton({ onComplete }: { onComplete?: () => void }) {
}
} catch (err) {
setStatus("error");
- toast({ message: "Ingest failed — check API key", type: "error" });
+ toast({ message: "Ingest failed. Check API key", type: "error" });
console.error("Ingest error:", err);
}
};
diff --git a/Frontend/src/components/KnowledgeDecisionsGraph.tsx b/Frontend/src/components/KnowledgeDecisionsGraph.tsx
index 3fbd24d..bbe25a5 100644
--- a/Frontend/src/components/KnowledgeDecisionsGraph.tsx
+++ b/Frontend/src/components/KnowledgeDecisionsGraph.tsx
@@ -161,7 +161,7 @@ function nodeShape(n: KnowledgeLayoutResponse["nodes"][0], key: string, theme: T
const accent = n.color;
const label = n.label;
const sub = n.sublabel ? `${n.sublabel.slice(0, 48)}${n.sublabel.length > 48 ? "…" : ""}` : "";
- const tooltip = [n.label, n.sublabel].filter(Boolean).join(" — ");
+ const tooltip = [n.label, n.sublabel].filter(Boolean).join(" · ");
const L = theme === "light";
const textMain = L ? "#0f172a" : "#f8fafc";
@@ -866,7 +866,7 @@ export function KnowledgeDecisionsGraph({ refreshKey = 0 }: { refreshKey?: numbe
Knowledge graph
- Ingested PR decisions, themes, issues, authors, and merge history — the same evidence the side chat uses.{" "}
+ Ingested PR decisions, themes, issues, authors, and merge history, the same evidence the side chat uses.{" "}
Drag to pan (on nodes: use Ctrl/Cmd+drag or middle-drag on empty
area). Scroll zooms toward the pointer. Green links = shared closing
issue; dotted = merge-time neighbors; violet dashed = PR → theme.
@@ -975,7 +975,7 @@ export function KnowledgeDecisionsGraph({ refreshKey = 0 }: { refreshKey?: numbe
◆ issue
◇ merge
━ shared issue
- ┅ time order — open nodes on GitHub.
+ ┅ time order: open nodes on GitHub.
- 14{" "}
- if len(self.requests[client_id]) >= self.max_requests:
-
-
- 15 return False
-
-
-
- memory: in-memory only
- @review
-
-
-
-);
+/** Decorative index cards — suggests PR graph without duplicating the interactive demo. */
+const HERO_SIGNALS = [
+ {
+ pr: "PR #847",
+ title: "Rate limiter: token bucket vs sliding window",
+ tag: "Decision",
+ },
+ {
+ pr: "PR #412",
+ title: "Pin axios after npm incident: documented exception",
+ tag: "Security",
+ },
+ {
+ pr: "PR #203",
+ title: "Reject Redis cluster: ops cost vs Memcached",
+ tag: "Architecture",
+ },
+] as const;
const HeroSection = () => {
const { user, loading } = useAuth();
const primaryCtaLabel = user ? "Go to Dashboard" : "Connect GitHub Repo";
return (
-
- {/* Local hero wash (adds depth on top of fixed backdrop) */}
-
-
+
-
-
-
-
-
+ {/* Large screens: only the two-column hero is vertically centered; live demo scrolls below */}
+
+
+
+ {/* Primary story */}
+
+
+
+
+
+
+
+
+ From merged PRs and review threads, not from guesses.
+
+
-
- Your team made 1000 decisions.
-
-
-
- None of them are searchable.
-
-
-
- Until now.
-
+
+ Your team made 1000 decisions.
+
+
+
+ None of them are
+ {" "}
+ searchable.
+
+
+ Until now.
+
-
-
- GitLore reads your entire PR history — titles, descriptions, review comments, debates — and builds a Knowledge Graph of every
+
+ GitLore reads your entire PR history (titles, descriptions, review comments, debates) and builds a Knowledge Graph of every
decision your team has ever made. Search it. Chat with it. Get cited answers in seconds.
-
-
+
-