fix: restore minimal header, original layout with ad rails, and optimize scroll performance

This commit is contained in:
katR 2026-09-15 23:46:46 +05:30
parent d9e0672f4a
commit 1b958afce0
6 changed files with 56 additions and 105 deletions

View file

@ -1,40 +1,37 @@
@import "tailwindcss"; @import "tailwindcss";
* { *, *::before, *::after {
box-sizing: border-box; box-sizing: border-box;
margin: 0; border-radius: 0 !important; /* Square minimal aesthetic */
padding: 0;
border-radius: 0 !important; /* Square everything out */
} }
:root { :root {
--background: #0b0b0b; --background: #070707;
--foreground: #e5e5e5; --foreground: #e5e5e5;
--accent: #ffffff; --surface: #0c0c0c;
--accent-hover: #e5e5e5; --border: #181818;
--accent-dim: #262626;
--surface: #111111;
--surface-hover: #161616;
--border: #1f1f1f;
--border-hover: #383838;
--muted: #666666;
} }
@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-mono: var(--font-mono); --font-mono: var(--font-mono);
} }
body { body {
background: #0b0b0b; background-color: #070707;
color: #e5e5e5; color: #e5e5e5;
font-family: var(--font-mono), 'JetBrains Mono', ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace; font-family: var(--font-mono), 'JetBrains Mono', ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
min-height: 100vh; min-height: 100vh;
-webkit-font-smoothing: antialiased; -webkit-font-smoothing: antialiased;
} }
/* Performant subtle dot background without laggy fixed masks */
.dot-bg-fade {
background-image: radial-gradient(circle, rgba(255, 255, 255, 0.035) 1px, transparent 1px);
background-size: 24px 24px;
}
/* Minimal Monospace Form Controls */ /* Minimal Monospace Form Controls */
input, textarea, select { input, textarea, select {
font-family: inherit; font-family: inherit;
@ -49,8 +46,8 @@ input[type="email"],
input[type="url"], input[type="url"],
textarea, textarea,
select { select {
background-color: #0d0d0d; background-color: #0c0c0c;
border: 1px solid #222222; border: 1px solid #1c1c1c;
color: #e5e5e5; color: #e5e5e5;
outline: none; outline: none;
transition: border-color 0.15s ease; transition: border-color 0.15s ease;
@ -64,7 +61,7 @@ input[type="email"]:focus,
input[type="url"]:focus, input[type="url"]:focus,
textarea:focus, textarea:focus,
select:focus { select:focus {
border-color: #555555; border-color: #444444;
} }
/* Minimal Square Buttons */ /* Minimal Square Buttons */
@ -80,13 +77,13 @@ button {
height: 6px; height: 6px;
} }
::-webkit-scrollbar-track { ::-webkit-scrollbar-track {
background: #0b0b0b; background: #070707;
} }
::-webkit-scrollbar-thumb { ::-webkit-scrollbar-thumb {
background: #222222; background: #1c1c1c;
} }
::-webkit-scrollbar-thumb:hover { ::-webkit-scrollbar-thumb:hover {
background: #383838; background: #333333;
} }
/* Selection */ /* Selection */
@ -95,23 +92,6 @@ button {
color: #ffffff; color: #ffffff;
} }
/* Dot pattern background */
.dot-bg-fade {
position: relative;
}
.dot-bg-fade::before {
content: "";
position: fixed;
inset: 0;
background-image: radial-gradient(circle, rgba(255, 255, 255, 0.035) 1px, transparent 1px);
background-size: 20px 20px;
pointer-events: none;
mask-image: radial-gradient(ellipse 85% 75% at 50% 50%, black 40%, transparent 100%);
-webkit-mask-image: radial-gradient(ellipse 85% 75% at 50% 50%, black 40%, transparent 100%);
z-index: 0;
}
/* Minimal Monochrome Overrides for Kat Aesthetic */ /* Minimal Monochrome Overrides for Kat Aesthetic */
.bg-blue-600 { .bg-blue-600 {
background-color: #e5e5e5 !important; background-color: #e5e5e5 !important;
@ -128,14 +108,6 @@ button {
background-color: #cccccc !important; background-color: #cccccc !important;
color: #000000 !important; color: #000000 !important;
} }
.bg-blue-700,
.bg-blue-800,
.bg-blue-900,
.bg-blue-900\/20,
.bg-blue-900\/60,
.bg-blue-950\/20 {
background-color: #222222 !important;
}
.text-blue-100, .text-blue-100,
.text-blue-200, .text-blue-200,
.text-blue-400, .text-blue-400,
@ -152,13 +124,13 @@ button {
.border-blue-700, .border-blue-700,
.border-blue-900, .border-blue-900,
.hover\:border-blue-900:hover { .hover\:border-blue-900:hover {
border-color: #383838 !important; border-color: #2a2a2a !important;
} }
.ring-blue-500\/30, .ring-blue-500\/30,
.ring-blue-500\/40, .ring-blue-500\/40,
.ring-blue-900, .ring-blue-900,
.ring-blue-900\/20 { .ring-blue-900\/20 {
--tw-ring-color: #444444 !important; --tw-ring-color: #333333 !important;
} }
.accent-blue-600 { .accent-blue-600 {
accent-color: #e5e5e5 !important; accent-color: #e5e5e5 !important;

View file

@ -72,7 +72,7 @@ export default function RootLayout({ children }: { children: React.ReactNode })
dangerouslySetInnerHTML={{ __html: "" }} dangerouslySetInnerHTML={{ __html: "" }}
/> />
</head> </head>
<body className="dot-bg-fade flex min-h-full flex-col bg-[#0b0b0b] text-[#e5e5e5] font-mono"> <body className="dot-bg-fade flex min-h-full flex-col bg-[#070707] text-[#e5e5e5] font-mono">
<Header /> <Header />
<main className="flex-1">{children}</main> <main className="flex-1">{children}</main>
<Footer /> <Footer />

View file

@ -8,7 +8,7 @@ export default function Home() {
const featuredTools = tools.filter((t) => t.featured); const featuredTools = tools.filter((t) => t.featured);
return ( return (
<div className="relative z-10 mx-auto max-w-7xl px-4 py-6 font-mono"> <div className="relative z-10 mx-auto max-w-7xl px-4 py-8">
<div className="flex justify-center items-start gap-6"> <div className="flex justify-center items-start gap-6">
{/* Left Side Rail (Ultra-wide) */} {/* Left Side Rail (Ultra-wide) */}
<div className="hidden 2xl:block sticky top-20 shrink-0"> <div className="hidden 2xl:block sticky top-20 shrink-0">
@ -18,32 +18,29 @@ export default function Home() {
{/* Main Content */} {/* Main Content */}
<div className="flex-1 max-w-5xl min-w-0"> <div className="flex-1 max-w-5xl min-w-0">
{/* Header intro */} {/* Header intro */}
<div className="mb-8 border border-[#1e1e1e] bg-[#0e0e0e] p-6"> <div className="mb-8 border border-[#1a1a1a] bg-[#090909] p-6">
<div className="text-[11px] font-mono text-[#666] mb-1.5 flex items-center gap-2"> <div className="text-xs font-mono text-[#666] mb-1">
<span className="inline-block w-1.5 h-1.5 bg-[#4ade80]" /> Local execution • No uploads
<span>client-side execution</span>
<span>•</span>
<span>zero server uploads</span>
</div> </div>
<h1 className="text-lg font-bold text-white tracking-tight"> <h1 className="text-xl font-semibold text-white tracking-tight">
browser-based file &amp; developer utilities Browser-based file and developer utilities
</h1> </h1>
<p className="mt-1.5 text-xs text-[#888] max-w-2xl leading-relaxed"> <p className="mt-1 text-xs text-gray-400 max-w-2xl leading-relaxed">
Fast, privacy-focused utilities for image resizing, EXIF metadata scrubbing, PDF manipulation, hashing, formatting, and standard developer conversions. All processing runs entirely in client memory. Utilities for image resizing, metadata stripping, PDF manipulation, and standard developer conversions. All tasks execute locally in your browser.
</p> </p>
{/* Quick access row */} {/* Quick access row */}
<div className="mt-5 grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-2"> <div className="mt-4 grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-2">
{featuredTools.map((t) => ( {featuredTools.map((t) => (
<Link <Link
key={t.slug} key={t.slug}
href={`/tools/${t.slug}`} href={`/tools/${t.slug}`}
className="group block border border-[#1f1f1f] bg-[#080808] hover:border-[#383838] hover:bg-[#141414] p-3 transition-colors" className="group block border border-[#1c1c1c] bg-[#060606] hover:border-[#333] hover:bg-[#0c0c0c] p-3 transition-colors"
> >
<div className="text-xs font-medium text-gray-200 group-hover:text-white transition-colors"> <div className="text-xs font-medium text-gray-200 group-hover:text-white transition-colors">
{t.name} {t.name}
</div> </div>
<p className="mt-1 text-[11px] text-[#666] line-clamp-2 leading-snug group-hover:text-[#888]"> <p className="mt-1 text-[11px] text-[#555] line-clamp-2 leading-snug group-hover:text-[#777]">
{t.description} {t.description}
</p> </p>
</Link> </Link>
@ -54,12 +51,12 @@ export default function Home() {
{/* Categorized tools */} {/* Categorized tools */}
{Object.entries(toolsByCategory).map(([category, categoryTools]) => ( {Object.entries(toolsByCategory).map(([category, categoryTools]) => (
<section key={category} className="mb-8"> <section key={category} className="mb-8">
<div className="flex items-center gap-2.5 mb-3"> <div className="flex items-center gap-2 mb-3">
<h2 className="text-xs font-mono uppercase tracking-wider text-gray-300 font-semibold"> <div className="h-px w-3 bg-blue-900"></div>
<h2 className="text-xs font-mono uppercase tracking-wider text-[#666]">
{category} {category}
</h2> </h2>
<span className="text-[10px] text-[#555] font-mono">[{categoryTools.length}]</span> <span className="text-[10px] text-[#444] font-mono">({categoryTools.length})</span>
<div className="h-px flex-1 bg-[#1a1a1a]" />
</div> </div>
<div className="grid grid-cols-1 gap-2 sm:grid-cols-2 lg:grid-cols-3"> <div className="grid grid-cols-1 gap-2 sm:grid-cols-2 lg:grid-cols-3">
{categoryTools.map((tool) => ( {categoryTools.map((tool) => (

View file

@ -2,7 +2,7 @@ import Link from "next/link";
export default function Footer() { export default function Footer() {
return ( return (
<footer className="relative z-10 mt-auto border-t border-[#1f1f1f] px-6 py-4 flex flex-wrap items-center justify-between gap-4 text-xs font-mono text-[#555] bg-[#0b0b0b]/90 backdrop-blur-sm max-w-7xl mx-auto w-full"> <footer className="relative z-10 mt-auto border-t border-[#141414] px-6 py-4 flex flex-wrap items-center justify-between gap-4 text-xs font-mono text-[#555] bg-[#070707] max-w-7xl mx-auto w-full">
<span>kattoolbox // zero-knowledge client execution</span> <span>kattoolbox // zero-knowledge client execution</span>
<div className="flex items-center gap-4"> <div className="flex items-center gap-4">
<Link href="/privacy" className="hover:text-gray-300 transition-colors"> <Link href="/privacy" className="hover:text-gray-300 transition-colors">

View file

@ -18,22 +18,21 @@ export default function Header() {
: []; : [];
return ( return (
<header className="relative z-20 border-b border-[#1f1f1f] bg-[#0b0b0b]/90 backdrop-blur-md sticky top-0 font-mono"> <header className="relative z-20 border-b border-[#141414] bg-[#070707] sticky top-0 font-mono">
<div className="mx-auto max-w-7xl px-4 py-3 flex items-center justify-between gap-4"> <div className="mx-auto max-w-7xl px-4 py-3 flex items-center justify-between gap-4">
{/* Brand & Local Status */} {/* Corner Client-Side indicator linking home */}
<Link <Link
href="/" href="/"
className="flex items-center gap-2 text-xs font-bold tracking-tight text-white hover:text-gray-300 transition-colors shrink-0 select-none" className="text-[10px] font-mono uppercase tracking-widest text-[#444] hover:text-[#777] transition-colors shrink-0 select-none"
title="kattoolbox - client-side utilities" title="Return to index"
> >
<span>kattoolbox</span> client-side
<span className="inline-block w-1.5 h-1.5 bg-[#4ade80]" title="local execution" />
</Link> </Link>
{/* Centered Search Bar */} {/* Centered Search Bar */}
<div className="relative flex-1 max-w-md mx-auto"> <div className="relative flex-1 max-w-lg mx-auto">
<svg <svg
className="absolute left-3 top-1/2 -translate-y-1/2 h-3.5 w-3.5 text-[#555]" className="absolute left-3 top-1/2 -translate-y-1/2 h-3.5 w-3.5 text-[#444]"
fill="none" fill="none"
stroke="currentColor" stroke="currentColor"
viewBox="0 0 24 24" viewBox="0 0 24 24"
@ -50,41 +49,31 @@ export default function Header() {
}} }}
onFocus={() => setShowResults(true)} onFocus={() => setShowResults(true)}
onBlur={() => setTimeout(() => setShowResults(false), 200)} onBlur={() => setTimeout(() => setShowResults(false), 200)}
className="w-full border border-[#222] bg-[#0d0d0d] pl-8 pr-3 py-1.5 text-xs text-gray-200 placeholder-[#555] outline-none focus:border-[#555] transition-colors font-mono" className="w-full border border-[#1c1c1c] bg-[#0d0d0d] pl-9 pr-3 py-1.5 text-xs text-gray-200 placeholder-[#444] outline-none focus:border-[#444] transition-colors font-mono"
/> />
{showResults && filtered.length > 0 && ( {showResults && filtered.length > 0 && (
<div className="absolute left-0 right-0 top-full mt-1 max-h-80 overflow-y-auto border border-[#262626] bg-[#0e0e0e] shadow-2xl z-50 divide-y divide-[#171717]"> <div className="absolute left-0 right-0 top-full mt-1 max-h-80 overflow-y-auto border border-[#1f1f1f] bg-[#090909] shadow-2xl z-50 divide-y divide-[#141414]">
{filtered.map((tool) => ( {filtered.map((tool) => (
<Link <Link
key={tool.slug} key={tool.slug}
href={`/tools/${tool.slug}`} href={`/tools/${tool.slug}`}
className="flex items-center justify-between px-3.5 py-2 text-xs text-gray-300 hover:bg-[#181818] hover:text-white transition-colors" className="flex items-center justify-between px-3.5 py-2 text-xs text-gray-300 hover:bg-[#141414] hover:text-white transition-colors"
onClick={() => { onClick={() => {
setQuery(""); setQuery("");
setShowResults(false); setShowResults(false);
}} }}
> >
<span className="font-medium text-gray-200">{tool.name}</span> <span className="font-medium text-gray-200">{tool.name}</span>
<span className="text-[11px] text-[#666] truncate ml-3">{tool.description}</span> <span className="text-[11px] text-[#555] truncate ml-3">{tool.description}</span>
</Link> </Link>
))} ))}
</div> </div>
)} )}
</div> </div>
{/* Right Info */} {/* Balancer spacing for desktop layout */}
<div className="flex items-center gap-3 shrink-0"> <div className="w-[70px] hidden sm:block shrink-0" />
<span className="text-[11px] font-mono text-[#555] hidden sm:inline">{tools.length} tools</span>
<a
href="https://github.com/oiupoyt/kattoolbox"
target="_blank"
rel="noopener noreferrer"
className="text-xs font-mono text-[#666] hover:text-gray-300 transition-colors"
>
github
</a>
</div>
</div> </div>
</header> </header>
); );

View file

@ -1,4 +1,3 @@
import Link from "next/link";
import SidebarAd from "@/components/SidebarAd"; import SidebarAd from "@/components/SidebarAd";
interface ToolLayoutProps { interface ToolLayoutProps {
@ -10,7 +9,7 @@ interface ToolLayoutProps {
export default function ToolLayout({ title, description, children, showSideAds = true }: ToolLayoutProps) { export default function ToolLayout({ title, description, children, showSideAds = true }: ToolLayoutProps) {
return ( return (
<div className="relative z-10 mx-auto max-w-7xl px-4 py-6"> <div className="relative z-10 mx-auto max-w-7xl px-4 py-8">
<div className="flex justify-center items-start gap-6"> <div className="flex justify-center items-start gap-6">
{/* Left Side Ad (Ultra-wide screens) */} {/* Left Side Ad (Ultra-wide screens) */}
{showSideAds && ( {showSideAds && (
@ -21,19 +20,13 @@ export default function ToolLayout({ title, description, children, showSideAds =
{/* Main Tool Content */} {/* Main Tool Content */}
<div className="flex-1 max-w-5xl min-w-0"> <div className="flex-1 max-w-5xl min-w-0">
<div className="mb-4"> <div className="flex items-center gap-2 mb-1">
<div className="flex items-center gap-1.5 text-[11px] font-mono text-[#555] mb-1.5"> <div className="h-px w-4 bg-blue-900"></div>
<Link href="/" className="hover:text-gray-300 transition-colors"> <h1 className="text-lg font-semibold text-white">{title}</h1>
tools
</Link>
<span>/</span>
<span className="text-[#888]">{title.toLowerCase()}</span>
</div>
<h1 className="text-base font-semibold text-white tracking-tight">{title}</h1>
<p className="mt-1 text-xs text-[#666] leading-relaxed">{description}</p>
</div> </div>
<p className="mb-5 text-sm text-[#525252] ml-6">{description}</p>
<div className="border border-[#1e1e1e] bg-[#0e0e0e] p-5 shadow-2xl"> <div className="border border-[#1a1a1a] bg-[#0a0a0a] p-5">
{children} {children}
</div> </div>
</div> </div>