diff --git a/services/frontend/src/components/TermGlossary.tsx b/services/frontend/src/components/TermGlossary.tsx index 0b1abc68..7fa0352e 100644 --- a/services/frontend/src/components/TermGlossary.tsx +++ b/services/frontend/src/components/TermGlossary.tsx @@ -1,71 +1,130 @@ "use client"; -import { Globe } from "lucide-react"; +import { ChevronDown, Globe } from "lucide-react"; +import { useRef, useState } from "react"; import { GlassPanel } from "@/components/primitives"; import { SectionHeader } from "@/components/shared"; +import { useStaggerReveal } from "@/hooks/use-gsap-animation"; import { downloadCsv } from "@/lib/csv"; import { formatRelativeTime } from "@/lib/format"; import type { GlossaryRow } from "@/lib/types"; -export function TermGlossary({ terms }: { terms: GlossaryRow[] }) { +function GlossaryEntry({ t }: { t: GlossaryRow }) { + const [open, setOpen] = useState(false); + const bodyRef = useRef(null); + return ( - - 0 ? ( - - ) : null - } - /> - {terms.length === 0 ? ( -

- No term resolutions cached yet. -

- ) : ( -
- {terms.map((t) => ( -
-
- {t.term} - - {t.hit_count} uses · {formatRelativeTime(t.resolved_at)} - -
-

{t.definition}

- {t.source_url && ( - - - {t.source_url} - - )} -
- ))} +
+ +
+
+
+

{t.definition}

+ {t.source_url && ( + + + {t.source_url} + + )} +
- )} - +
+
+ ); +} + +export function TermGlossary({ terms }: { terms: GlossaryRow[] }) { + const listRef = useStaggerReveal(".glossary-entry", { + stagger: 0.035, + y: 10, + dependencies: [terms], + }); + + return ( +
+ {/* Tactical HUD Header Bar */} +
+
+
+ + +
+

+ TERM GLOSSARY · KB_INDEX +

+
+
+ TERMS: + {terms.length} +
+
+ + + 0 ? ( + + ) : null + } + /> + {terms.length === 0 ? ( +

+ NO TERM RESOLUTIONS CACHED YET +

+ ) : ( +
+ {terms.map((t) => ( + + ))} +
+ )} +
+
); }