fix: replace all hardcoded hex colors with CSS theme variables
Phase 15c — theme-consistent color system: Replaced 63 instances of hardcoded hex colors (#5e6ad2, #7170ff, #4f46e5, #6a75e0, #828fff, #94a3b8, etc.) with CSS variables from globals.css: - #5e6ad2 → var(--brand) (light: #5e6ad2, dark: #5e6ad2) - #7170ff → var(--accent) (light: #4f46e5, dark: #7170ff) - #4f46e5 → var(--accent) - #6a75e0 → var(--brand-hover) (new var, light: #6a75e0, dark: #7170ff) - #828fff → var(--accent-hover) - #868686 → var(--text-dim) - Dark-mode-specific hex in Markdown.tsx → CSS variables Added --brand-hover CSS variable (light: #6a75e0, dark: #7170ff) Added dark:prose-invert instead of prose-invert (light mode now uses default prose theme instead of forced dark) Files changed: 15 component files + globals.css
This commit is contained in:
1 parent
ea75d68b1a
commit
be923cb432
18 files changed
+149
-105
No files matched your search
@@ -116,7 +116,7 @@ export default function CommandMenu() {
|
||||
<div className="relative w-full max-w-2xl bg-[var(--bg-surface)] border border-[var(--border-color)] rounded-xl shadow-2xl overflow-hidden animate-fade-in">
|
||||
{/* Search input bar */}
|
||||
<div className="flex items-center gap-3 px-4 py-3.5 border-b border-[var(--border-color)] bg-[var(--bg-elevated)]">
|
||||
<svg className="w-5 h-5 text-[#5e6ad2] dark:text-[#7170ff] shrink-0" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<svg className="w-5 h-5 text-[var(--brand)] dark:text-[var(--accent)] shrink-0" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" />
|
||||
</svg>
|
||||
<input
|
||||
@@ -129,7 +129,7 @@ export default function CommandMenu() {
|
||||
className="w-full bg-transparent text-[var(--text-primary)] placeholder-[var(--text-dim)] text-sm focus:outline-none"
|
||||
/>
|
||||
{loading && (
|
||||
<div className="w-4 h-4 border-2 border-[#5e6ad2] border-t-transparent rounded-full animate-spin shrink-0" />
|
||||
<div className="w-4 h-4 border-2 border-[var(--brand)] border-t-transparent rounded-full animate-spin shrink-0" />
|
||||
)}
|
||||
<button
|
||||
onClick={() => setOpen(false)}
|
||||
@@ -164,22 +164,22 @@ export default function CommandMenu() {
|
||||
onMouseEnter={() => setSelectedIndex(index)}
|
||||
className={`flex items-start justify-between gap-3 px-3 py-2.5 rounded-lg cursor-pointer transition-all ${
|
||||
isSelected
|
||||
? "bg-[#5e6ad2]/15 border border-[#5e6ad2]/40 text-[var(--text-primary)]"
|
||||
? "bg-[var(--brand)]/15 border border-[var(--brand)]/40 text-[var(--text-primary)]"
|
||||
: "hover:bg-[var(--bg-elevated)] text-[var(--text-secondary)] border border-transparent"
|
||||
}`}
|
||||
>
|
||||
<div className="min-w-0 flex-1">
|
||||
<div className="flex items-center gap-2">
|
||||
<span className="text-xs px-1.5 py-0.25 bg-[var(--bg-elevated)] border border-[var(--border-color)] rounded text-[#5e6ad2] dark:text-[#7170ff] font-mono">
|
||||
<span className="text-xs px-1.5 py-0.25 bg-[var(--bg-elevated)] border border-[var(--border-color)] rounded text-[var(--brand)] dark:text-[var(--accent)] font-mono">
|
||||
{hit.section}
|
||||
</span>
|
||||
<span className={`text-sm font-medium ${isSelected ? "text-[#5e6ad2] dark:text-[#7170ff]" : "text-[var(--text-primary)]"} truncate`}>
|
||||
<span className={`text-sm font-medium ${isSelected ? "text-[var(--brand)] dark:text-[var(--accent)]" : "text-[var(--text-primary)]"} truncate`}>
|
||||
{hit.title}
|
||||
</span>
|
||||
</div>
|
||||
{hit.snippet && (
|
||||
<p
|
||||
className="text-xs text-[var(--text-muted)] mt-1 line-clamp-1 [&>mark]:bg-[#5e6ad2]/30 [&>mark]:text-[var(--text-primary)] [&>mark]:rounded [&>mark]:px-0.5"
|
||||
className="text-xs text-[var(--text-muted)] mt-1 line-clamp-1 [&>mark]:bg-[var(--brand)]/30 [&>mark]:text-[var(--text-primary)] [&>mark]:rounded [&>mark]:px-0.5"
|
||||
dangerouslySetInnerHTML={{ __html: hit.snippet }}
|
||||
/>
|
||||
)}
|
||||
@@ -200,7 +200,7 @@ export default function CommandMenu() {
|
||||
<Link
|
||||
href={`/search?q=${encodeURIComponent(query)}`}
|
||||
onClick={() => setOpen(false)}
|
||||
className="hover:text-[#5e6ad2] dark:hover:text-[#7170ff] transition-colors"
|
||||
className="hover:text-[var(--brand)] dark:hover:text-[var(--accent)] transition-colors"
|
||||
>
|
||||
Open full search page →
|
||||
</Link>
|
||||
|
||||
@@ -78,7 +78,7 @@ export default function DocActions({ slug, body, canEdit }: DocActionsProps) {
|
||||
{/* Edit Link */}
|
||||
<Link
|
||||
href={canEdit ? `/${slug}?edit=1` : `/login?redirect=/${slug}`}
|
||||
className="inline-flex items-center gap-1 px-2.5 py-1 text-xs bg-[#5e6ad2]/10 hover:bg-[#5e6ad2]/20 border border-[#5e6ad2]/30 hover:border-[#5e6ad2]/60 text-[#5e6ad2] dark:text-[#7170ff] rounded-md transition-all font-medium"
|
||||
className="inline-flex items-center gap-1 px-2.5 py-1 text-xs bg-[var(--brand)]/10 hover:bg-[var(--brand)]/20 border border-[var(--brand)]/30 hover:border-[var(--brand)]/60 text-[var(--brand)] dark:text-[var(--accent)] rounded-md transition-all font-medium"
|
||||
>
|
||||
<svg className="w-3.5 h-3.5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M11 5H6a2 2 0 00-2 2v11a2 2 0 002 2h11a2 2 0 002-2v-5m-1.414-9.414a2 2 0 112.828 2.828L11.828 15H9v-2.828l8.586-8.586z" />
|
||||
|
||||
@@ -88,7 +88,7 @@ export default function DocForm({
|
||||
const availableFolders = existingFolders?.[section] ?? [];
|
||||
|
||||
const baseInputCls =
|
||||
"w-full px-3.5 py-2 bg-[var(--bg-surface)] border border-[var(--border-color)] hover:border-[var(--brand)] rounded-lg text-sm text-[var(--text-primary)] placeholder-[var(--text-dim)] focus:outline-none focus:border-[var(--brand)] focus:ring-1 focus:ring-[#5e6ad2] transition-colors";
|
||||
"w-full px-3.5 py-2 bg-[var(--bg-surface)] border border-[var(--border-color)] hover:border-[var(--brand)] rounded-lg text-sm text-[var(--text-primary)] placeholder-[var(--text-dim)] focus:outline-none focus:border-[var(--brand)] focus:ring-1 focus:ring-[var(--brand)] transition-colors";
|
||||
|
||||
function addCustomField(key = "", value = "") {
|
||||
setCustomFields([...customFields, { key, value }]);
|
||||
@@ -314,7 +314,7 @@ export default function DocForm({
|
||||
/>
|
||||
)}
|
||||
<p className="text-[11px] text-[var(--text-dim)] mt-1 font-mono">
|
||||
Path: <span className="text-[#5e6ad2] dark:text-[#7170ff]">{effectiveSlug || section}</span>
|
||||
Path: <span className="text-[var(--brand)] dark:text-[var(--accent)]">{effectiveSlug || section}</span>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
@@ -404,7 +404,7 @@ export default function DocForm({
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => addCustomField()}
|
||||
className="text-xs text-[#5e6ad2] dark:text-[#7170ff] hover:underline px-3 py-1.5 rounded-lg border border-[#5e6ad2]/30 hover:border-[#5e6ad2]/60 bg-[#5e6ad2]/5 transition-colors font-medium"
|
||||
className="text-xs text-[var(--brand)] dark:text-[var(--accent)] hover:underline px-3 py-1.5 rounded-lg border border-[var(--brand)]/30 hover:border-[var(--brand)]/60 bg-[var(--brand)]/5 transition-colors font-medium"
|
||||
>
|
||||
+ Add Custom Field
|
||||
</button>
|
||||
@@ -421,7 +421,7 @@ export default function DocForm({
|
||||
onClick={() => setActiveTab("write")}
|
||||
className={`px-3 py-1 text-xs rounded-md font-medium transition-all ${
|
||||
activeTab === "write"
|
||||
? "bg-[#5e6ad2] text-white shadow-sm"
|
||||
? "bg-[var(--brand)] text-white shadow-sm"
|
||||
: "text-[var(--text-muted)] hover:text-[var(--text-primary)]"
|
||||
}`}
|
||||
>
|
||||
@@ -432,7 +432,7 @@ export default function DocForm({
|
||||
onClick={() => setActiveTab("preview")}
|
||||
className={`px-3 py-1 text-xs rounded-md font-medium transition-all ${
|
||||
activeTab === "preview"
|
||||
? "bg-[#5e6ad2] text-white shadow-sm"
|
||||
? "bg-[var(--brand)] text-white shadow-sm"
|
||||
: "text-[var(--text-muted)] hover:text-[var(--text-primary)]"
|
||||
}`}
|
||||
>
|
||||
@@ -521,7 +521,7 @@ export default function DocForm({
|
||||
<button
|
||||
type="submit"
|
||||
disabled={loading}
|
||||
className="px-6 py-2.5 bg-[#5e6ad2] hover:bg-[#6a75e0] text-white rounded-lg font-medium text-sm transition-all shadow-md shadow-[#5e6ad2]/20 disabled:opacity-50 flex items-center gap-2"
|
||||
className="px-6 py-2.5 bg-[var(--brand)] hover:bg-[var(--brand-hover)] text-white rounded-lg font-medium text-sm transition-all shadow-md shadow-[var(--brand)]/20 disabled:opacity-50 flex items-center gap-2"
|
||||
>
|
||||
{loading && (
|
||||
<div className="w-4 h-4 border-2 border-white border-t-transparent rounded-full animate-spin" />
|
||||
|
||||
@@ -29,7 +29,7 @@ export default function Header() {
|
||||
{/* Brand */}
|
||||
<div className="flex items-center gap-3">
|
||||
<Link href="/" className="flex items-center gap-2 group">
|
||||
<div className="w-7 h-7 rounded-lg bg-gradient-to-br from-[#5e6ad2] to-[#7170ff] flex items-center justify-center text-white font-bold text-xs shadow-md shadow-[#5e6ad2]/20 group-hover:scale-105 transition-transform">
|
||||
<div className="w-7 h-7 rounded-lg bg-gradient-to-br from-[var(--brand)] to-[var(--accent)] flex items-center justify-center text-white font-bold text-xs shadow-md shadow-[var(--brand)]/20 group-hover:scale-105 transition-transform">
|
||||
M
|
||||
</div>
|
||||
<span className="font-semibold text-[var(--text-primary)] text-base tracking-tight transition-colors">
|
||||
@@ -78,7 +78,7 @@ export default function Header() {
|
||||
|
||||
<Link
|
||||
href="/create"
|
||||
className="hidden sm:inline-flex items-center gap-1.5 px-3 py-1 bg-[#5e6ad2] hover:bg-[#7170ff] text-white text-xs font-medium rounded-lg transition-all shadow-sm"
|
||||
className="hidden sm:inline-flex items-center gap-1.5 px-3 py-1 bg-[var(--brand)] hover:bg-[var(--accent)] text-white text-xs font-medium rounded-lg transition-all shadow-sm"
|
||||
>
|
||||
<span>+</span>
|
||||
<span>New Doc</span>
|
||||
@@ -141,7 +141,7 @@ export default function Header() {
|
||||
<Link
|
||||
href="/create"
|
||||
onClick={() => setMobileMenuOpen(false)}
|
||||
className="flex-1 text-center py-2 text-xs bg-[#5e6ad2] text-white rounded-lg font-medium"
|
||||
className="flex-1 text-center py-2 text-xs bg-[var(--brand)] text-white rounded-lg font-medium"
|
||||
>
|
||||
+ Create
|
||||
</Link>
|
||||
|
||||
@@ -27,19 +27,19 @@ function CodeBlock({ children, className, ...props }: React.HTMLAttributes<HTMLE
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="relative group my-4 rounded-lg overflow-hidden border border-[#23252a] bg-[#0c0d0e]">
|
||||
<div className="relative group my-4 rounded-lg overflow-hidden border border-[var(--border-color)] bg-[var(--code-block-bg)]">
|
||||
{/* Code block header bar */}
|
||||
<div className="flex items-center justify-between px-3.5 py-1.5 bg-[#141517] border-b border-[#1f2022] text-[11px] text-[#8a8f98] font-mono">
|
||||
<div className="flex items-center justify-between px-3.5 py-1.5 bg-[var(--bg-elevated)] border-b border-[var(--border-color)] text-[11px] text-[var(--text-muted)] font-mono">
|
||||
<span>{language || "text"}</span>
|
||||
<button
|
||||
onClick={handleCopy}
|
||||
type="button"
|
||||
className="flex items-center gap-1 text-[#8a8f98] hover:text-[#f7f8f8] bg-[#1a1b1d] hover:bg-[#23252a] px-2 py-0.5 rounded border border-[#27292d] transition-all"
|
||||
className="flex items-center gap-1 text-[var(--text-muted)] hover:text-[var(--text-primary)] bg-[var(--bg-elevated-hover)] hover:bg-[var(--border-subtle)] px-2 py-0.5 rounded border border-[var(--border-color)] transition-all"
|
||||
>
|
||||
{copied ? (
|
||||
<>
|
||||
<svg className="w-3 h-3 text-emerald-400" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M5 13l4 4L19 7" />
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M5 13l4 4 L19 7" />
|
||||
</svg>
|
||||
<span className="text-emerald-400 font-sans">Copied!</span>
|
||||
</>
|
||||
@@ -54,7 +54,7 @@ function CodeBlock({ children, className, ...props }: React.HTMLAttributes<HTMLE
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<pre className="!m-0 !bg-transparent p-4 overflow-x-auto text-sm text-[#e2e4e7] font-mono leading-relaxed">
|
||||
<pre className="!m-0 !bg-transparent p-4 overflow-x-auto text-sm text-[var(--pre-text)] font-mono leading-relaxed">
|
||||
<code className={className} {...props}>
|
||||
{children}
|
||||
</code>
|
||||
@@ -66,17 +66,17 @@ function CodeBlock({ children, className, ...props }: React.HTMLAttributes<HTMLE
|
||||
export default function Markdown({ source }: { source: string }) {
|
||||
return (
|
||||
<div
|
||||
className="prose prose-invert max-w-none
|
||||
prose-headings:text-[#f7f8f8] prose-headings:font-medium prose-headings:tracking-tight
|
||||
prose-h1:text-2xl prose-h1:mb-6 prose-h1:mt-8 prose-h1:pb-2 prose-h1:border-b prose-h1:border-[#1f2022]
|
||||
className="prose max-w-none
|
||||
prose-headings:text-[var(--text-primary)] prose-headings:font-medium prose-headings:tracking-tight
|
||||
prose-h1:text-2xl prose-h1:mb-6 prose-h1:mt-8 prose-h1:pb-2 prose-h1:border-b prose-h1:border-[var(--border-color)]
|
||||
prose-h2:text-xl prose-h2:mb-4 prose-h2:mt-8
|
||||
prose-h3:text-base prose-h3:mb-3 prose-h3:mt-6
|
||||
prose-p:text-[#d0d6e0] prose-p:leading-relaxed prose-p:mb-4
|
||||
prose-a:text-[#7170ff] prose-a:no-underline hover:prose-a:underline hover:prose-a:text-[#828fff]
|
||||
prose-ul:text-[#d0d6e0] prose-ul:my-3 prose-li:my-1
|
||||
prose-ol:text-[#d0d6e0] prose-ol:my-3
|
||||
prose-strong:text-[#f7f8f8] prose-strong:font-semibold
|
||||
prose-hr:border-[#1f2022] prose-hr:my-8"
|
||||
prose-p:text-[var(--text-secondary)] prose-p:leading-relaxed prose-p:mb-4
|
||||
prose-a:text-[var(--accent)] prose-a:no-underline hover:prose-a:underline hover:prose-a:text-[var(--accent-hover)]
|
||||
prose-ul:text-[var(--text-secondary)] prose-ul:my-3 prose-li:my-1
|
||||
prose-ol:text-[var(--text-secondary)] prose-ol:my-3
|
||||
prose-strong:text-[var(--text-primary)] prose-strong:font-semibold
|
||||
prose-hr:border-[var(--border-color)] prose-hr:my-8"
|
||||
>
|
||||
<ReactMarkdown
|
||||
remarkPlugins={[remarkGfm]}
|
||||
@@ -85,13 +85,13 @@ export default function Markdown({ source }: { source: string }) {
|
||||
code: CodeBlock as any,
|
||||
pre: ({ children }) => <>{children}</>,
|
||||
table: ({ node, ...props }) => (
|
||||
<div className="overflow-x-auto my-6 border border-[#1f2022] rounded-lg">
|
||||
<div className="overflow-x-auto my-6 border border-[var(--border-color)] rounded-lg">
|
||||
<table className="w-full border-collapse" {...props} />
|
||||
</div>
|
||||
),
|
||||
blockquote: ({ children }) => {
|
||||
return (
|
||||
<blockquote className="border-l-4 border-[#5e6ad2] bg-[#141517]/60 pl-4 py-2 my-4 rounded-r text-[#a0a4a8] not-italic">
|
||||
<blockquote className="border-l-4 border-[var(--brand)] bg-[var(--bg-elevated)]/60 pl-4 py-2 my-4 rounded-r text-[var(--text-muted)] not-italic">
|
||||
{children}
|
||||
</blockquote>
|
||||
);
|
||||
|
||||
@@ -70,7 +70,7 @@ export default function McpConfigSnippet() {
|
||||
onClick={() => setActiveTab(c.id)}
|
||||
className={`px-3 py-1 text-xs rounded-md font-medium transition-all ${
|
||||
activeTab === c.id
|
||||
? "bg-[#5e6ad2] text-white shadow-sm"
|
||||
? "bg-[var(--brand)] text-white shadow-sm"
|
||||
: "text-[var(--text-muted)] hover:text-[var(--text-primary)] hover:bg-[var(--bg-surface)]"
|
||||
}`}
|
||||
>
|
||||
|
||||
@@ -106,7 +106,7 @@ function TreeNodeItem({
|
||||
<div
|
||||
className={`group flex items-center justify-between gap-1.5 text-xs py-1.5 px-2 rounded-md transition-all ${
|
||||
isActive
|
||||
? "text-[#5e6ad2] dark:text-[#7170ff] bg-[#5e6ad2]/15 font-semibold border border-[#5e6ad2]/30 shadow-sm"
|
||||
? "text-[var(--brand)] dark:text-[var(--accent)] bg-[var(--brand)]/15 font-semibold border border-[var(--brand)]/30 shadow-sm"
|
||||
: isParentOfActive
|
||||
? "text-[var(--text-primary)] bg-[var(--bg-elevated)]"
|
||||
: "text-[var(--text-muted)] hover:text-[var(--text-primary)] hover:bg-[var(--bg-elevated)]"
|
||||
@@ -263,7 +263,7 @@ export default function Sidebar() {
|
||||
href={`/${id}`}
|
||||
className={`flex items-center justify-between gap-1.5 px-1 py-1 mb-1 rounded text-xs font-semibold uppercase tracking-wider transition-colors ${
|
||||
isSectionActive
|
||||
? "text-[#5e6ad2] dark:text-[#7170ff]"
|
||||
? "text-[var(--brand)] dark:text-[var(--accent)]"
|
||||
: "text-[var(--text-muted)] hover:text-[var(--text-primary)]"
|
||||
}`}
|
||||
>
|
||||
|
||||
@@ -61,7 +61,7 @@ export default function TOC({ source }: { source: string }) {
|
||||
return (
|
||||
<nav className="text-xs">
|
||||
<div className="flex items-center gap-2 mb-3 pb-2 border-b border-[var(--border-color)]">
|
||||
<svg className="w-3.5 h-3.5 text-[#5e6ad2] dark:text-[#7170ff]" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<svg className="w-3.5 h-3.5 text-[var(--brand)] dark:text-[var(--accent)]" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M4 6h16M4 12h16M4 18h7" />
|
||||
</svg>
|
||||
<span className="font-semibold uppercase tracking-wider text-[var(--text-muted)] text-[11px]">
|
||||
@@ -92,7 +92,7 @@ export default function TOC({ source }: { source: string }) {
|
||||
}}
|
||||
className={`block py-0.5 transition-colors line-clamp-1 ${
|
||||
isActive
|
||||
? "text-[#5e6ad2] dark:text-[#7170ff] font-semibold translate-x-0.5"
|
||||
? "text-[var(--brand)] dark:text-[var(--accent)] font-semibold translate-x-0.5"
|
||||
: "text-[var(--text-muted)] hover:text-[var(--text-primary)]"
|
||||
}`}
|
||||
title={entry.text}
|
||||
|
||||
Reference in new issue
Block a user