ui: emerald accent, better layout, cleaner cards
This commit is contained in:
parent
f66a105ea1
commit
fccfb07fc0
6 changed files with 69 additions and 41 deletions
|
|
@ -3,11 +3,19 @@
|
||||||
:root {
|
:root {
|
||||||
--background: #000000;
|
--background: #000000;
|
||||||
--foreground: #e5e5e5;
|
--foreground: #e5e5e5;
|
||||||
|
--accent: #10b981;
|
||||||
|
--accent-dim: #065f46;
|
||||||
|
--surface: #0a0a0a;
|
||||||
|
--surface-hover: #111111;
|
||||||
|
--border: #1a1a1a;
|
||||||
|
--border-hover: #2a2a2a;
|
||||||
|
--muted: #525252;
|
||||||
}
|
}
|
||||||
|
|
||||||
@theme inline {
|
@theme inline {
|
||||||
--color-background: var(--background);
|
--color-background: var(--background);
|
||||||
--color-foreground: var(--foreground);
|
--color-foreground: var(--foreground);
|
||||||
|
--color-accent: var(--accent);
|
||||||
--font-sans: var(--font-geist-sans);
|
--font-sans: var(--font-geist-sans);
|
||||||
--font-mono: var(--font-geist-mono);
|
--font-mono: var(--font-geist-mono);
|
||||||
}
|
}
|
||||||
|
|
@ -18,11 +26,11 @@ body {
|
||||||
font-family: var(--font-sans), Arial, Helvetica, sans-serif;
|
font-family: var(--font-sans), Arial, Helvetica, sans-serif;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* AdSense placeholder styling — sharp theme */
|
/* Ad placeholders */
|
||||||
.ad-container ins.adsbygoogle {
|
.ad-container ins.adsbygoogle {
|
||||||
min-height: 90px;
|
min-height: 90px;
|
||||||
background: #050505;
|
background: var(--surface);
|
||||||
border: 1px solid rgba(255, 255, 255, 0.04);
|
border: 1px solid var(--border);
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
|
|
@ -32,10 +40,11 @@ body {
|
||||||
.ad-container ins.adsbygoogle::after {
|
.ad-container ins.adsbygoogle::after {
|
||||||
content: "Ad";
|
content: "Ad";
|
||||||
font-size: 0.6rem;
|
font-size: 0.6rem;
|
||||||
color: rgba(255, 255, 255, 0.1);
|
color: var(--muted);
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
letter-spacing: 0.1em;
|
letter-spacing: 0.15em;
|
||||||
font-family: monospace;
|
font-family: monospace;
|
||||||
|
text-transform: uppercase;
|
||||||
}
|
}
|
||||||
|
|
||||||
.ad-side ins.adsbygoogle {
|
.ad-side ins.adsbygoogle {
|
||||||
|
|
|
||||||
|
|
@ -15,15 +15,18 @@ export default function Home() {
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Main content */}
|
{/* Main content */}
|
||||||
<div className="flex-1 min-w-0 max-w-4xl mx-auto px-4 py-6">
|
<div className="flex-1 min-w-0 max-w-4xl mx-auto px-4 py-8">
|
||||||
<AdSlot slot="homepage-top" format="horizontal" />
|
<AdSlot slot="homepage-top" format="horizontal" />
|
||||||
|
|
||||||
{Object.entries(toolsByCategory).map(([category, categoryTools]) => (
|
{Object.entries(toolsByCategory).map(([category, categoryTools]) => (
|
||||||
<section key={category} className="mb-6">
|
<section key={category} className="mb-8">
|
||||||
<h2 className="mb-2 text-xs font-semibold uppercase tracking-wider text-gray-500">
|
<div className="flex items-center gap-2 mb-3">
|
||||||
{category}
|
<div className="h-px w-4 bg-emerald-900"></div>
|
||||||
</h2>
|
<h2 className="text-xs font-medium uppercase tracking-widest text-[#525252]">
|
||||||
<div className="grid grid-cols-1 gap-px sm:grid-cols-2 lg:grid-cols-3 border border-gray-900">
|
{category}
|
||||||
|
</h2>
|
||||||
|
</div>
|
||||||
|
<div className="grid grid-cols-1 gap-2 sm:grid-cols-2 lg:grid-cols-3">
|
||||||
{categoryTools.map((tool) => (
|
{categoryTools.map((tool) => (
|
||||||
<ToolCard key={tool.slug} tool={tool} />
|
<ToolCard key={tool.slug} tool={tool} />
|
||||||
))}
|
))}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
export default function Footer() {
|
export default function Footer() {
|
||||||
return (
|
return (
|
||||||
<footer className="mt-auto border-t border-gray-900 px-4 py-4 text-center text-xs text-gray-600 bg-black">
|
<footer className="mt-auto border-t border-[#1a1a1a] px-4 py-5 text-center text-xs text-[#525252] bg-black">
|
||||||
© {new Date().getFullYear()} DevToolbox
|
Free, private, browser-based developer tools.
|
||||||
</footer>
|
</footer>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -17,35 +17,43 @@ export default function Header() {
|
||||||
: [];
|
: [];
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<header className="border-b border-gray-900 bg-black">
|
<header className="border-b border-[#1a1a1a] bg-black">
|
||||||
<div className="mx-auto max-w-5xl px-4 py-2.5 relative">
|
<div className="mx-auto max-w-5xl px-4 py-3 relative">
|
||||||
<input
|
<div className="relative">
|
||||||
type="text"
|
<svg className="absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-[#525252]" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||||
placeholder="Search tools..."
|
<path strokeLinecap="square" strokeLinejoin="miter" strokeWidth={2} d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" />
|
||||||
value={query}
|
</svg>
|
||||||
onChange={(e) => {
|
<input
|
||||||
setQuery(e.target.value);
|
type="text"
|
||||||
setShowResults(true);
|
placeholder="Search 30 tools..."
|
||||||
}}
|
value={query}
|
||||||
onFocus={() => setShowResults(true)}
|
onChange={(e) => {
|
||||||
onBlur={() => setTimeout(() => setShowResults(false), 150)}
|
setQuery(e.target.value);
|
||||||
className="w-full border border-gray-800 bg-black px-3 py-2 text-sm text-gray-200 placeholder-gray-600 outline-none focus:border-gray-600 font-mono"
|
setShowResults(true);
|
||||||
/>
|
}}
|
||||||
|
onFocus={() => setShowResults(true)}
|
||||||
|
onBlur={() => setTimeout(() => setShowResults(false), 150)}
|
||||||
|
className="w-full border border-[#1a1a1a] bg-[#0a0a0a] pl-10 pr-3 py-2 text-sm text-gray-300 placeholder-[#525252] outline-none focus:border-emerald-900 transition-colors"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
{showResults && filtered.length > 0 && (
|
{showResults && filtered.length > 0 && (
|
||||||
<div className="absolute left-4 right-4 top-full z-50 mt-0 max-h-64 overflow-y-auto border border-gray-800 border-t-0 bg-black shadow-2xl">
|
<div className="absolute left-4 right-4 top-full z-50 max-h-72 overflow-y-auto border border-[#1a1a1a] border-t-0 bg-[#0a0a0a] shadow-2xl shadow-black/50">
|
||||||
{filtered.map((tool) => (
|
{filtered.map((tool) => (
|
||||||
<Link
|
<Link
|
||||||
key={tool.slug}
|
key={tool.slug}
|
||||||
href={`/tools/${tool.slug}`}
|
href={`/tools/${tool.slug}`}
|
||||||
className="block border-b border-gray-900 px-3 py-2 text-sm text-gray-300 hover:bg-gray-950"
|
className="flex items-center gap-3 border-b border-[#111] px-4 py-2.5 text-sm text-gray-400 hover:bg-[#111] hover:text-emerald-400 transition-colors"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
setQuery("");
|
setQuery("");
|
||||||
setShowResults(false);
|
setShowResults(false);
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{tool.icon} {tool.name}
|
<span className="text-base">{tool.icon}</span>
|
||||||
<span className="ml-2 text-xs text-gray-600">{tool.description}</span>
|
<div>
|
||||||
|
<span className="text-gray-200">{tool.name}</span>
|
||||||
|
<span className="ml-2 text-xs text-[#525252]">{tool.description}</span>
|
||||||
|
</div>
|
||||||
</Link>
|
</Link>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -5,12 +5,15 @@ export default function ToolCard({ tool }: { tool: Tool }) {
|
||||||
return (
|
return (
|
||||||
<Link
|
<Link
|
||||||
href={`/tools/${tool.slug}`}
|
href={`/tools/${tool.slug}`}
|
||||||
className="block border border-gray-900 px-4 py-3 transition-colors hover:border-gray-600 hover:bg-gray-950 bg-black"
|
className="group flex items-start gap-3 border border-[#1a1a1a] bg-[#0a0a0a] px-4 py-4 transition-all hover:bg-[#111] hover:border-[#2a2a2a]"
|
||||||
>
|
>
|
||||||
<div className="text-sm font-medium text-gray-200">
|
<span className="text-lg mt-0.5 grayscale group-hover:grayscale-0 transition-all">{tool.icon}</span>
|
||||||
{tool.icon} {tool.name}
|
<div>
|
||||||
|
<div className="text-sm font-medium text-gray-300 group-hover:text-emerald-400 transition-colors">
|
||||||
|
{tool.name}
|
||||||
|
</div>
|
||||||
|
<div className="mt-0.5 text-xs text-[#525252] leading-relaxed">{tool.description}</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="mt-0.5 text-xs text-gray-600">{tool.description}</div>
|
|
||||||
</Link>
|
</Link>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ interface ToolLayoutProps {
|
||||||
export default function ToolLayout({ title, description, children }: ToolLayoutProps) {
|
export default function ToolLayout({ title, description, children }: ToolLayoutProps) {
|
||||||
return (
|
return (
|
||||||
<div className="flex w-full">
|
<div className="flex w-full">
|
||||||
{/* Left side ad — flush to edge */}
|
{/* Left side ad */}
|
||||||
<div className="ad-side hidden xl:flex w-[200px] shrink-0 justify-center pt-6 pl-2">
|
<div className="ad-side hidden xl:flex w-[200px] shrink-0 justify-center pt-6 pl-2">
|
||||||
<div className="sticky top-16">
|
<div className="sticky top-16">
|
||||||
<AdSlot slot="left-sidebar" format="vertical" />
|
<AdSlot slot="left-sidebar" format="vertical" />
|
||||||
|
|
@ -17,18 +17,23 @@ export default function ToolLayout({ title, description, children }: ToolLayoutP
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Main content */}
|
{/* Main content */}
|
||||||
<div className="flex-1 min-w-0 max-w-4xl mx-auto px-4 py-6">
|
<div className="flex-1 min-w-0 max-w-4xl mx-auto px-4 py-8">
|
||||||
<AdSlot slot="1234567890" format="horizontal" />
|
<AdSlot slot="1234567890" format="horizontal" />
|
||||||
|
|
||||||
<h1 className="mb-1 text-lg font-semibold text-white">{title}</h1>
|
<div className="flex items-center gap-2 mb-1">
|
||||||
<p className="mb-4 text-sm text-gray-500">{description}</p>
|
<div className="h-px w-4 bg-emerald-900"></div>
|
||||||
|
<h1 className="text-lg font-semibold text-white">{title}</h1>
|
||||||
|
</div>
|
||||||
|
<p className="mb-5 text-sm text-[#525252] ml-6">{description}</p>
|
||||||
|
|
||||||
{children}
|
<div className="border border-[#1a1a1a] bg-[#0a0a0a] p-5">
|
||||||
|
{children}
|
||||||
|
</div>
|
||||||
|
|
||||||
<AdSlot slot="0987654321" format="horizontal" className="mt-6" />
|
<AdSlot slot="0987654321" format="horizontal" className="mt-6" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Right side ad — flush to edge */}
|
{/* Right side ad */}
|
||||||
<div className="ad-side hidden xl:flex w-[200px] shrink-0 justify-center pt-6 pr-2">
|
<div className="ad-side hidden xl:flex w-[200px] shrink-0 justify-center pt-6 pr-2">
|
||||||
<div className="sticky top-16">
|
<div className="sticky top-16">
|
||||||
<AdSlot slot="right-sidebar" format="vertical" />
|
<AdSlot slot="right-sidebar" format="vertical" />
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue