diff --git a/BRANDING.md b/BRANDING.md index 10cb47fe..0f0e84c4 100644 --- a/BRANDING.md +++ b/BRANDING.md @@ -37,7 +37,7 @@ All SDK colors are expressed as `--dc-*` CSS custom properties. Host application | Token | Light | Dark | Usage | |-------|-------|------|-------| -| `--dc-verified` | `#16a34a` | `#22c55e` | Verified citation | +| `--dc-verified` | `#10b981` | `#34d399` | Verified citation (emerald-500 / emerald-400) | | `--dc-partial` | `#f59e0b` | `#fbbf24` | Partial match | | `--dc-destructive` | `#ef4444` | `#f87171` | Not found / error | | `--dc-pending` | `#a1a1aa` | `#71717a` | Pending / loading | diff --git a/docs/_sass/custom/custom.scss b/docs/_sass/custom/custom.scss index e84b6309..1e78d9a0 100644 --- a/docs/_sass/custom/custom.scss +++ b/docs/_sass/custom/custom.scss @@ -679,6 +679,10 @@ pre { border: 1px solid var(--border-color); } +.search-result-doc .search-result-icon { + color: var(--link-color); +} + // ----------------------------------------------------- // Tables - Clean single thin borders (no double borders) // border-collapse eliminates double borders between cells diff --git a/docs/agents/branding.md b/docs/agents/branding.md index 462a0bd3..1c83b852 100644 --- a/docs/agents/branding.md +++ b/docs/agents/branding.md @@ -41,7 +41,7 @@ The Tailwind classes `bg-dc-*`, `text-dc-*`, `border-dc-*` are registered via `@ | Token | Light Default | Dark Default | Usage | |-------|--------------|--------------|-------| -| `--dc-verified` | `#16a34a` | `#22c55e` | Verified/success indicator | +| `--dc-verified` | `#10b981` | `#34d399` | Verified/success indicator (emerald-500 / emerald-400) | | `--dc-partial` | `#f59e0b` | `#fbbf24` | Partial match / warning indicator | | `--dc-destructive` | `#ef4444` | `#f87171` | Error/not-found indicator | | `--dc-pending` | `#a1a1aa` | `#71717a` | Pending/loading indicator | diff --git a/docs/styling.md b/docs/styling.md index e4c785e2..e07d2965 100644 --- a/docs/styling.md +++ b/docs/styling.md @@ -25,10 +25,10 @@ Override these CSS variables to theme all DeepCitation components at once: ```css :root { /* Status indicator colors */ - --dc-verified-color: #16a34a; /* Green - verified/exact match (default: green-600) */ - --dc-partial-color: #f59e0b; /* Amber - partial match (default: amber-500) */ - --dc-error-color: #ef4444; /* Red - not found/hallucination (default: red-500) */ - --dc-pending-color: #9ca3af; /* Gray - loading/pending (default: gray-400) */ + --dc-verified: #10b981; /* Emerald - verified/exact match (default: emerald-500) */ + --dc-partial: #f59e0b; /* Amber - partial match (default: amber-500) */ + --dc-destructive: #ef4444; /* Red - not found/hallucination (default: red-500) */ + --dc-pending: #9ca3af; /* Gray - loading/pending (default: gray-400) */ /* Wavy underline for "not found" status (non-linter variants) */ --dc-wavy-underline-color: #ef4444; /* Default: red-500 */ @@ -53,10 +53,10 @@ Override these CSS variables to theme all DeepCitation components at once: ```css @media (prefers-color-scheme: dark) { :root { - --dc-verified-color: #4ade80; /* green-400 */ - --dc-partial-color: #fbbf24; /* amber-400 */ - --dc-error-color: #f87171; /* red-400 */ - --dc-pending-color: #6b7280; /* gray-500 */ + --dc-verified: #34d399; /* emerald-400 */ + --dc-partial: #fbbf24; /* amber-400 */ + --dc-destructive: #f87171; /* red-400 */ + --dc-pending: #6b7280; /* gray-500 */ --dc-linter-success: #6aab85; --dc-linter-warning: #fbbf24; --dc-linter-error: #d47d7c; @@ -68,10 +68,10 @@ Override these CSS variables to theme all DeepCitation components at once: /* Or with a class-based approach (Tailwind dark mode) */ .dark { - --dc-verified-color: #4ade80; - --dc-partial-color: #fbbf24; - --dc-error-color: #f87171; - --dc-pending-color: #6b7280; + --dc-verified: #34d399; + --dc-partial: #fbbf24; + --dc-destructive: #f87171; + --dc-pending: #6b7280; --dc-document-canvas-bg-light: #f3f4f6; --dc-document-canvas-bg-dark: #1f2937; } @@ -165,22 +165,22 @@ Target specific citation elements using data attributes and selectors: /* Verified citations - specific styling */ [data-dc-indicator="verified"] { - color: var(--dc-verified-color); + color: var(--dc-verified); } /* Partial match citations */ [data-dc-indicator="partial"] { - color: var(--dc-partial-color); + color: var(--dc-partial); } /* Not found / hallucination citations */ [data-dc-indicator="error"] { - color: var(--dc-error-color); + color: var(--dc-destructive); } /* Pending / loading citations */ [data-dc-indicator="pending"] { - color: var(--dc-pending-color); + color: var(--dc-pending); } /* Citation trigger element */ diff --git a/src/__tests__/CitationContentDisplay.test.tsx b/src/__tests__/CitationContentDisplay.test.tsx index aa4e6e81..4c036b93 100644 --- a/src/__tests__/CitationContentDisplay.test.tsx +++ b/src/__tests__/CitationContentDisplay.test.tsx @@ -73,7 +73,7 @@ describe("CitationContentDisplay — footnote variant", () => { />, ); const sup = container.querySelector("sup"); - expect(sup?.className).toContain("text-green-600"); + expect(sup?.className).toContain("text-dc-verified"); }); it("renders amber for partial match status", () => { @@ -89,7 +89,7 @@ describe("CitationContentDisplay — footnote variant", () => { />, ); const sup = container.querySelector("sup"); - expect(sup?.className).toContain("text-amber-500"); + expect(sup?.className).toContain("text-dc-partial"); }); it("renders red for miss status", () => { @@ -105,7 +105,7 @@ describe("CitationContentDisplay — footnote variant", () => { />, ); const sup = container.querySelector("sup"); - expect(sup?.className).toContain("text-red-500"); + expect(sup?.className).toContain("text-dc-destructive"); }); it("applies wavy underline style for miss state", () => { diff --git a/src/__tests__/UrlCitationComponent.test.tsx b/src/__tests__/UrlCitationComponent.test.tsx index 04160f5d..907106d4 100644 --- a/src/__tests__/UrlCitationComponent.test.tsx +++ b/src/__tests__/UrlCitationComponent.test.tsx @@ -50,9 +50,8 @@ describe("UrlCitationComponent", () => { const checkIcon = container.querySelector("svg"); expect(checkIcon).toBeInTheDocument(); - // The wrapper should have green color class - const statusWrapper = container.querySelector(".text-green-600"); - expect(statusWrapper).toBeInTheDocument(); + // The check icon uses the --dc-verified CSS custom property so host themes can override it + expect(checkIcon).toHaveStyle({ color: "var(--dc-verified, #10b981)" }); }); it("shows lock icon when blocked", () => { diff --git a/src/__tests__/caretIndicator.test.tsx b/src/__tests__/caretIndicator.test.tsx index fdd44a98..03572393 100644 --- a/src/__tests__/caretIndicator.test.tsx +++ b/src/__tests__/caretIndicator.test.tsx @@ -85,16 +85,16 @@ describe("Caret Indicator Variant", () => { }); // ========================================================================== - // ACTIVE DARKENING + // COLOR STAYS GRAY REGARDLESS OF OPEN STATE (no inverted active style) // ========================================================================== - it("uses inverted text color (text-white) when open", () => { + it("uses gray text when open (no inverted active style)", () => { const { container } = render(); const pill = container.querySelector("[data-dc-indicator='caret']") as HTMLElement; - expect(pill.classList.contains("text-white")).toBe(true); + expect(pill.classList.contains("text-slate-500")).toBe(true); }); - it("uses lighter gray (text-slate-500) when closed", () => { + it("uses gray text when closed", () => { const { container } = render(); const pill = container.querySelector("[data-dc-indicator='caret']") as HTMLElement; expect(pill.classList.contains("text-slate-500")).toBe(true); diff --git a/src/__tests__/rendering/htmlRenderer.test.ts b/src/__tests__/rendering/htmlRenderer.test.ts index 16862a48..d817f752 100644 --- a/src/__tests__/rendering/htmlRenderer.test.ts +++ b/src/__tests__/rendering/htmlRenderer.test.ts @@ -106,7 +106,7 @@ describe("renderCitationsAsHtml", () => { it("generates dark theme styles", () => { const output = renderCitationsAsHtml(simpleInput, { theme: "dark" }); - expect(output.styles).toContain("#4ade80"); // dark mode green + expect(output.styles).toContain("#34d399"); // dark mode emerald-400 }); it("generates auto theme styles with media query", () => { diff --git a/src/drawing/citationDrawing.ts b/src/drawing/citationDrawing.ts index 10a0c322..929eb065 100644 --- a/src/drawing/citationDrawing.ts +++ b/src/drawing/citationDrawing.ts @@ -15,11 +15,12 @@ import { safeSplit } from "../utils/regexSafety.js"; /** * Highlight color category for citation annotations. - * - 'blue': exact / full-phrase match + * - 'green': exact / full-phrase match (VERIFIED) * - 'amber': partial match (anchorText-only or value-only) * - 'red': not-found (AI claimed location overlay) + * - 'blue': legacy alias for 'green' — kept for backward compatibility */ -export type HighlightColor = "blue" | "amber" | "red"; +export type HighlightColor = "green" | "blue" | "amber" | "red"; // ============================================================================= // Color Constants @@ -28,9 +29,14 @@ export type HighlightColor = "blue" | "amber" | "red"; /** Border width for citation bracket outlines (px). */ export const CITATION_LINE_BORDER_WIDTH = 2; -/** Blue bracket color for exact/full-phrase matches. */ +/** Green bracket color for verified / exact-match citations (BRANDING.md VERIFIED, emerald-500). */ +export const SIGNAL_GREEN = "#10b981"; +/** Lighter green for dark-mode contexts (BRANDING.md VERIFIED luminous, emerald-400). */ +export const SIGNAL_GREEN_DARK = "#34d399"; + +/** @deprecated Use SIGNAL_GREEN. Kept for any external consumers still referencing blue brackets. */ export const SIGNAL_BLUE = "#005595"; -/** Lighter blue for dark-mode contexts. */ +/** @deprecated Use SIGNAL_GREEN_DARK. */ export const SIGNAL_BLUE_DARK = "#77bff6"; /** Amber bracket color for partial matches (Tailwind amber-400). */ @@ -88,12 +94,14 @@ export function getBracketWidth(height: number): number { /** * Returns the bracket stroke color for a given highlight category. - * Blue for exact matches, amber for partial matches, red for not-found. + * Green for verified/exact matches, amber for partial matches, red for not-found. + * "blue" is a legacy alias that resolves to the deprecated SIGNAL_BLUE value. */ -export function getBracketColor(highlightColor: HighlightColor = "blue"): string { +export function getBracketColor(highlightColor: HighlightColor = "green"): string { if (highlightColor === "amber") return SIGNAL_AMBER; if (highlightColor === "red") return SIGNAL_RED; - return SIGNAL_BLUE; + if (highlightColor === "blue") return SIGNAL_BLUE; // legacy + return SIGNAL_GREEN; } // ============================================================================= diff --git a/src/drawing/index.ts b/src/drawing/index.ts index 7bc9197e..71b44408 100644 --- a/src/drawing/index.ts +++ b/src/drawing/index.ts @@ -21,6 +21,8 @@ export { SIGNAL_AMBER, SIGNAL_BLUE, SIGNAL_BLUE_DARK, + SIGNAL_GREEN, + SIGNAL_GREEN_DARK, SIGNAL_RED, SPOTLIGHT_BORDER_RADIUS, SPOTLIGHT_PADDING, diff --git a/src/react/Citation.tsx b/src/react/Citation.tsx index 2f5bb124..96f55827 100644 --- a/src/react/Citation.tsx +++ b/src/react/Citation.tsx @@ -25,6 +25,7 @@ import { SPINNER_TIMEOUT_MS, TAP_SLOP_PX, TOUCH_CLICK_DEBOUNCE_MS, + VERIFIED_COLOR_STYLE, } from "./constants.js"; import { DefaultPopoverContent, type PopoverViewState } from "./DefaultPopoverContent.js"; import { resolveEvidenceSrc, resolveExpandedImage } from "./EvidenceTray.js"; @@ -1490,12 +1491,12 @@ const PendingDot = () => ( ); /** - * Green verified checkmark indicator. - * Uses green-600 color to match DOT_COLORS.green for visual consistency. + * Verified checkmark indicator. + * Color tracks --dc-verified so it stays in sync with the status dot and quote border. */ const VerifiedCheck = () => ( -