ui: remove ads, full-width layout, dot pattern bg
This commit is contained in:
parent
fccfb07fc0
commit
634a2cddcd
7 changed files with 46 additions and 95 deletions
|
|
@ -4,7 +4,6 @@
|
|||
--background: #000000;
|
||||
--foreground: #e5e5e5;
|
||||
--accent: #10b981;
|
||||
--accent-dim: #065f46;
|
||||
--surface: #0a0a0a;
|
||||
--surface-hover: #111111;
|
||||
--border: #1a1a1a;
|
||||
|
|
@ -26,28 +25,25 @@ body {
|
|||
font-family: var(--font-sans), Arial, Helvetica, sans-serif;
|
||||
}
|
||||
|
||||
/* Ad placeholders */
|
||||
.ad-container ins.adsbygoogle {
|
||||
min-height: 90px;
|
||||
background: var(--surface);
|
||||
border: 1px solid var(--border);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 100%;
|
||||
/* Dot pattern background */
|
||||
.dot-bg {
|
||||
background-image: radial-gradient(circle, rgba(255, 255, 255, 0.035) 1px, transparent 1px);
|
||||
background-size: 20px 20px;
|
||||
}
|
||||
|
||||
.ad-container ins.adsbygoogle::after {
|
||||
content: "Ad";
|
||||
font-size: 0.6rem;
|
||||
color: var(--muted);
|
||||
font-weight: 400;
|
||||
letter-spacing: 0.15em;
|
||||
font-family: monospace;
|
||||
text-transform: uppercase;
|
||||
/* Fade the dots at top and bottom */
|
||||
.dot-bg-fade {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.ad-side ins.adsbygoogle {
|
||||
min-height: 600px;
|
||||
min-width: 160px;
|
||||
.dot-bg-fade::before {
|
||||
content: "";
|
||||
position: fixed;
|
||||
inset: 0;
|
||||
background-image: radial-gradient(circle, rgba(255, 255, 255, 0.03) 1px, transparent 1px);
|
||||
background-size: 20px 20px;
|
||||
pointer-events: none;
|
||||
mask-image: radial-gradient(ellipse 80% 70% at 50% 50%, black 40%, transparent 100%);
|
||||
-webkit-mask-image: radial-gradient(ellipse 80% 70% at 50% 50%, black 40%, transparent 100%);
|
||||
z-index: 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -64,7 +64,7 @@ export default function RootLayout({ children }: { children: React.ReactNode })
|
|||
crossOrigin="anonymous"
|
||||
/>
|
||||
</head>
|
||||
<body className="flex min-h-full flex-col bg-black text-foreground">
|
||||
<body className="dot-bg-fade flex min-h-full flex-col bg-black text-foreground">
|
||||
<Header />
|
||||
<main className="flex-1">{children}</main>
|
||||
<Footer />
|
||||
|
|
|
|||
|
|
@ -1,23 +1,11 @@
|
|||
import ToolCard from "@/components/ToolCard";
|
||||
import AdSlot from "@/components/AdSlot";
|
||||
import { getToolsByCategory } from "@/lib/tools";
|
||||
|
||||
export default function Home() {
|
||||
const toolsByCategory = getToolsByCategory();
|
||||
|
||||
return (
|
||||
<div className="flex w-full">
|
||||
{/* Left side ad */}
|
||||
<div className="ad-side hidden xl:flex w-[200px] shrink-0 justify-center pt-6 pl-2">
|
||||
<div className="sticky top-16">
|
||||
<AdSlot slot="home-left" format="vertical" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Main content */}
|
||||
<div className="flex-1 min-w-0 max-w-4xl mx-auto px-4 py-8">
|
||||
<AdSlot slot="homepage-top" format="horizontal" />
|
||||
|
||||
<div className="relative z-10 mx-auto max-w-6xl px-6 py-8">
|
||||
{Object.entries(toolsByCategory).map(([category, categoryTools]) => (
|
||||
<section key={category} className="mb-8">
|
||||
<div className="flex items-center gap-2 mb-3">
|
||||
|
|
@ -26,23 +14,13 @@ export default function Home() {
|
|||
{category}
|
||||
</h2>
|
||||
</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 xl:grid-cols-4">
|
||||
{categoryTools.map((tool) => (
|
||||
<ToolCard key={tool.slug} tool={tool} />
|
||||
))}
|
||||
</div>
|
||||
</section>
|
||||
))}
|
||||
|
||||
<AdSlot slot="homepage-bottom" format="horizontal" />
|
||||
</div>
|
||||
|
||||
{/* Right side ad */}
|
||||
<div className="ad-side hidden xl:flex w-[200px] shrink-0 justify-center pt-6 pr-2">
|
||||
<div className="sticky top-16">
|
||||
<AdSlot slot="home-right" format="vertical" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
export default function Footer() {
|
||||
return (
|
||||
<footer className="mt-auto border-t border-[#1a1a1a] px-4 py-5 text-center text-xs text-[#525252] bg-black">
|
||||
<footer className="relative z-10 mt-auto border-t border-[#1a1a1a] px-6 py-5 text-center text-xs text-[#525252] bg-black/80 backdrop-blur-sm">
|
||||
Free, private, browser-based developer tools.
|
||||
</footer>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -17,8 +17,8 @@ export default function Header() {
|
|||
: [];
|
||||
|
||||
return (
|
||||
<header className="border-b border-[#1a1a1a] bg-black">
|
||||
<div className="mx-auto max-w-5xl px-4 py-3 relative">
|
||||
<header className="relative z-10 border-b border-[#1a1a1a] bg-black/80 backdrop-blur-sm">
|
||||
<div className="mx-auto max-w-6xl px-6 py-3 relative">
|
||||
<div className="relative">
|
||||
<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">
|
||||
<path strokeLinecap="square" strokeLinejoin="miter" strokeWidth={2} d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" />
|
||||
|
|
@ -38,7 +38,7 @@ export default function Header() {
|
|||
</div>
|
||||
|
||||
{showResults && filtered.length > 0 && (
|
||||
<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">
|
||||
<div className="absolute left-6 right-6 top-full z-50 max-h-72 overflow-y-auto border border-[#1a1a1a] border-t-0 bg-black/95 backdrop-blur-md shadow-2xl shadow-black/80">
|
||||
{filtered.map((tool) => (
|
||||
<Link
|
||||
key={tool.slug}
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ export default function ToolCard({ tool }: { tool: Tool }) {
|
|||
return (
|
||||
<Link
|
||||
href={`/tools/${tool.slug}`}
|
||||
className="group flex items-start gap-3 border border-[#1a1a1a] bg-[#0a0a0a] px-4 py-4 transition-all hover:bg-[#111] hover:border-[#2a2a2a]"
|
||||
className="group flex items-start gap-3 border border-[#1a1a1a] bg-[#0a0a0a]/80 px-5 py-4 transition-all hover:bg-[#111] hover:border-[#2a2a2a]"
|
||||
>
|
||||
<span className="text-lg mt-0.5 grayscale group-hover:grayscale-0 transition-all">{tool.icon}</span>
|
||||
<div>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,3 @@
|
|||
import AdSlot from "./AdSlot";
|
||||
|
||||
interface ToolLayoutProps {
|
||||
title: string;
|
||||
description: string;
|
||||
|
|
@ -8,37 +6,16 @@ interface ToolLayoutProps {
|
|||
|
||||
export default function ToolLayout({ title, description, children }: ToolLayoutProps) {
|
||||
return (
|
||||
<div className="flex w-full">
|
||||
{/* Left side ad */}
|
||||
<div className="ad-side hidden xl:flex w-[200px] shrink-0 justify-center pt-6 pl-2">
|
||||
<div className="sticky top-16">
|
||||
<AdSlot slot="left-sidebar" format="vertical" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Main content */}
|
||||
<div className="flex-1 min-w-0 max-w-4xl mx-auto px-4 py-8">
|
||||
<AdSlot slot="1234567890" format="horizontal" />
|
||||
|
||||
<div className="relative z-10 mx-auto max-w-5xl px-6 py-8">
|
||||
<div className="flex items-center gap-2 mb-1">
|
||||
<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>
|
||||
|
||||
<div className="border border-[#1a1a1a] bg-[#0a0a0a] p-5">
|
||||
<div className="border border-[#1a1a1a] bg-[#0a0a0a]/80 p-5">
|
||||
{children}
|
||||
</div>
|
||||
|
||||
<AdSlot slot="0987654321" format="horizontal" className="mt-6" />
|
||||
</div>
|
||||
|
||||
{/* Right side ad */}
|
||||
<div className="ad-side hidden xl:flex w-[200px] shrink-0 justify-center pt-6 pr-2">
|
||||
<div className="sticky top-16">
|
||||
<AdSlot slot="right-sidebar" format="vertical" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue