gemini_watermark_cleaner/public/index.html

277 lines
13 KiB
HTML

<!DOCTYPE html>
<html lang="zh-CN" class="light">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Gemini Watermark Cleaner</title>
<meta name="description" content="Free Gemini watermark remover tool. Safe, private, and 100% browser-based.">
<link rel="icon" href="data:image/svg+xml,%3Csvg class='h-10 w-10 text-indigo-500' xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%236366f1' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M12 3l-1.9 5.8-5.8 1.9 5.8 1.9 1.9 5.8 1.9-5.8 5.8-1.9-5.8-1.9z'/%3E%3C/svg%3E">
<script src="https://cdn.tailwindcss.com"></script>
<script>
tailwind.config = {
darkMode: 'class',
theme: {
extend: {
colors: {
background: 'var(--background)',
surface: 'var(--surface)',
card: 'var(--card)',
border: 'var(--border)',
primary: 'var(--primary)',
secondary: 'var(--secondary)',
accent: '#3B82F6',
},
fontFamily: {
sans: ['Inter', 'sans-serif'],
mono: ['JetBrains Mono', 'monospace'],
}
}
}
}
</script>
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600&family=JetBrains+Mono:wght@400;500&display=swap" rel="stylesheet">
<style>
:root {
--background: #ffffff;
--surface: #f9fafb;
--card: #ffffff;
--border: #e5e7eb;
--primary: #111827;
--secondary: #6b7280;
}
.dark {
--background: #050505;
--surface: #0A0A0A;
--card: #111111;
--border: #262626;
--primary: #EDEDED;
--secondary: #888888;
}
body {
font-family: 'Inter', sans-serif;
background-color: var(--background);
color: var(--primary);
}
.noise-layer {
position: fixed;
top: 0; left: 0; width: 100%; height: 100%;
pointer-events: none;
z-index: 0;
opacity: 0.04;
background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 200 200' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='noiseFilter'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.65' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23noiseFilter)'/%3E%3C/svg%3E");
}
.glass-nav {
backdrop-filter: blur(12px);
}
.dark .glass-nav {
background: rgba(5, 5, 5, 0.8);
border-bottom: 1px solid #262626;
}
.light .glass-nav {
background: rgba(255, 255, 255, 0.8);
border-bottom: 1px solid #e5e7eb;
}
.spotlight-wrapper {
position: relative;
background: rgba(255, 255, 255, 0.08);
border-radius: 12px;
padding: 1px;
box-shadow: 0 0 0 1px rgba(0,0,0,1), 0 20px 40px -20px rgba(0,0,0,0.5);
overflow: hidden;
}
.light .spotlight-wrapper {
background: rgba(0, 0, 0, 0.05);
box-shadow: 0 0 0 1px rgba(0,0,0,0.05), 0 20px 40px -20px rgba(0,0,0,0.1);
}
.drop-zone {
position: relative;
}
.dark .drop-zone {
background: #0A0A0A;
background-image: linear-gradient(#262626 1px, transparent 1px), linear-gradient(90deg, #262626 1px, transparent 1px);
background-size: 40px 40px;
}
.light .drop-zone {
background: #ffffff;
background-image: linear-gradient(#f3f4f6 1px, transparent 1px), linear-gradient(90deg, #f3f4f6 1px, transparent 1px);
background-size: 40px 40px;
}
.dark .drop-zone::after {
content: '';
position: absolute;
inset: 0;
background: radial-gradient(circle at center, transparent 20%, #0A0A0A 100%);
pointer-events: none;
}
.light .drop-zone::after {
content: '';
position: absolute;
inset: 0;
background: radial-gradient(circle at center, transparent 20%, #ffffff 100%);
pointer-events: none;
}
.preview-bg {
background-size: 20px 20px;
}
.dark .preview-bg {
background-color: #111;
background-image: radial-gradient(#333 1px, transparent 1px);
}
.light .preview-bg {
background-color: #f9fafb;
background-image: radial-gradient(#e5e7eb 1px, transparent 1px);
}
/* Ensure zoom preview is on top of everything */
.medium-zoom-overlay,
.medium-zoom-image--opened {
z-index: 9999 !important;
}
</style>
</head>
<body class="min-h-screen flex flex-col relative overflow-x-hidden bg-background text-primary dark:bg-background dark:text-primary">
<div class="noise-layer"></div>
<header class="glass-nav sticky top-0 z-50 h-16 flex items-center justify-between px-6 lg:px-12">
<div class="flex items-center gap-3">
<div class="w-2 h-2 bg-primary rounded-sm"></div>
<h1 class="font-mono text-sm font-medium tracking-tight">GEMINI WATERMARK CLEANER</h1>
</div>
<nav class="flex items-center gap-6 text-xs md:text-sm font-medium text-secondary">
<button id="themeToggle" class="p-2 border border-border rounded hover:bg-surface text-primary transition-colors">
<svg id="themeIcon" class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path id="themeIconPath" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M20.354 15.354A9 9 0 018.646 3.646 9.003 9.003 0 0012 21a9.003 9.003 0 008.354-5.646z"></path>
</svg>
</button>
<a href="http://git.unissense.tech/mula/gemini_watermark_cleaner" target="_blank" class="hover:text-primary transition-colors">GitHub</a>
<button id="langSwitch" class="px-3 py-1 border border-border rounded hover:bg-surface text-primary transition-colors">EN</button>
</nav>
</header>
<main class="flex-grow container mx-auto px-4 py-12 md:py-20 z-10 relative max-w-5xl">
<!-- Hero Section -->
<section class="text-center mb-16 space-y-6">
<h2 class="text-4xl md:text-6xl font-medium tracking-tight bg-clip-text text-transparent bg-gradient-to-b from-primary to-secondary" data-i18n="main.title">
Restore Clarity.
</h2>
<p class="text-secondary text-base md:text-lg max-w-2xl mx-auto font-light" data-i18n="main.subtitle">
Remove Gemini & NotebookLM watermarks instantly. Local processing, privacy-first.
</p>
</section>
<!-- Upload Area -->
<section class="mb-20">
<div class="spotlight-wrapper max-w-2xl mx-auto group">
<div id="uploadArea" class="drop-zone h-64 md:h-80 rounded-xl flex flex-col items-center justify-center cursor-pointer transition-colors hover:border-accent/50">
<div class="z-10 flex flex-col items-center gap-4 transition-transform group-hover:-translate-y-1 duration-300">
<div class="w-12 h-12 rounded-xl bg-card border border-border flex items-center justify-center text-secondary">
<svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-8l-4-4m0 0L8 8m4-4v12"></path></svg>
</div>
<div class="text-center">
<p class="text-primary font-medium mb-1" data-i18n="upload.text">Drop files here or click to upload</p>
<p class="text-secondary text-xs font-mono bg-surface px-2 py-1 rounded" data-i18n="upload.hint">JPG, PNG, WEBP, PDF</p>
</div>
</div>
<input type="file" id="fileInput" accept="image/jpeg,image/png,image/webp,application/pdf" multiple class="hidden" />
</div>
</div>
</section>
<!-- Previews -->
<section id="singlePreview" class="hidden mb-20 space-y-8 animate-in fade-in slide-in-from-bottom-4 duration-500">
<div class="grid lg:grid-cols-2 gap-6">
<!-- Original -->
<div class="bg-card border border-border rounded-xl overflow-hidden">
<div class="px-4 py-3 border-b border-border flex justify-between items-center bg-surface">
<span class="text-xs font-mono text-secondary" data-i18n="preview.original">ORIGINAL</span>
<span id="originalInfo" class="text-[10px] font-mono text-secondary/50"></span>
</div>
<div class="h-64 md:h-96 preview-bg flex items-center justify-center p-4">
<img id="originalImage" class="max-w-full max-h-full rounded shadow-lg" data-zoomable />
</div>
</div>
<!-- Result -->
<div id="processedSection" class="bg-card border border-border rounded-xl overflow-hidden hidden">
<div class="px-4 py-3 border-b border-border flex justify-between items-center bg-surface">
<span class="text-xs font-mono text-accent" data-i18n="preview.result">CLEANED</span>
<span id="processedInfo" class="text-[10px] font-mono text-secondary/50"></span>
</div>
<div class="h-64 md:h-96 preview-bg flex items-center justify-center p-4 relative">
<img id="processedImage" class="max-w-full max-h-full rounded shadow-lg" data-zoomable />
</div>
</div>
</div>
<!-- Actions -->
<div class="flex flex-col sm:flex-row justify-center gap-4 pt-4">
<button id="resetBtn" class="px-6 py-2.5 rounded-lg border border-border text-secondary hover:text-primary hover:border-secondary transition-all text-sm font-medium" data-i18n="btn.reset">
Reset
</button>
<button id="downloadBtn" class="px-6 py-2.5 rounded-lg bg-primary text-background hover:opacity-90 transition-all text-sm font-medium flex items-center justify-center gap-2 hidden" data-i18n="btn.download">
Download Result
</button>
</div>
<div id="statusMessage" class="text-center text-xs font-mono text-secondary h-4"></div>
</section>
<!-- Multi Preview -->
<section id="multiPreview" class="hidden mb-20">
<div class="flex justify-between items-end mb-6 border-b border-border pb-4">
<span id="progressText" class="font-mono text-sm text-secondary">QUEUE</span>
<button id="downloadAllBtn" class="text-xs font-mono bg-primary text-background px-4 py-2 rounded hover:opacity-90 transition-colors hidden" data-i18n="btn.downloadAll">DOWNLOAD ALL</button>
</div>
<div id="imageList" class="grid grid-cols-1 md:grid-cols-2 gap-4"></div>
</section>
<!-- Features -->
<section class="grid grid-cols-1 md:grid-cols-3 gap-6 pt-12 border-t border-border">
<div class="p-6 rounded-xl bg-card border border-border hover:border-secondary transition-colors">
<div class="w-8 h-8 text-primary mb-4">
<svg fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M13 10V3L4 14h7v7l9-11h-7z"></path></svg>
</div>
<h3 class="font-medium mb-2 text-sm text-primary" data-i18n="feature.speed.title">Local Processing</h3>
<p class="text-xs text-secondary leading-relaxed" data-i18n="feature.speed.desc">Runs entirely in your browser. No data leaves your device.</p>
</div>
<div class="p-6 rounded-xl bg-card border border-border hover:border-secondary transition-colors">
<div class="w-8 h-8 text-primary mb-4">
<svg fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M9 12l2 2 4-4m5.618-4.016A11.955 11.955 0 0112 2.944a11.955 11.955 0 01-8.618 3.04A12.02 12.02 0 003 9c0 5.591 3.824 10.29 9 11.622 5.176-1.332 9-6.03 9-11.622 0-1.042-.133-2.052-.382-3.016z"></path></svg>
</div>
<h3 class="font-medium mb-2 text-sm text-primary" data-i18n="feature.privacy.title">Privacy First</h3>
<p class="text-xs text-secondary leading-relaxed" data-i18n="feature.privacy.desc">Zero server uploads. Your intellectual property stays yours.</p>
</div>
<div class="p-6 rounded-xl bg-card border border-border hover:border-secondary transition-colors">
<div class="w-8 h-8 text-primary mb-4">
<svg fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z"></path></svg>
</div>
<h3 class="font-medium mb-2 text-sm text-primary" data-i18n="feature.free.title">Forever Free</h3>
<p class="text-xs text-secondary leading-relaxed" data-i18n="feature.free.desc">Open source and free to use. No hidden fees or limits.</p>
</div>
</section>
</main>
<footer class="border-t border-border mt-auto">
<div class="container mx-auto px-6 py-8 flex flex-col md:flex-row justify-between items-center text-xs text-secondary font-mono">
<div class="mb-4 md:mb-0">
<span data-i18n="footer.copyright">&copy; 2025 Gemini Watermark Remover</span>
</div>
<div class="flex gap-6">
<a href="terms.html" class="hover:text-primary transition-colors" data-i18n="footer.terms">Terms</a>
<a href="http://git.unissense.tech/mula/gemini_watermark_cleaner" target="_blank" class="hover:text-primary transition-colors">GitHub</a>
</div>
</div>
</footer>
<div id="loadingOverlay" class="fixed inset-0 bg-background/80 backdrop-blur-sm z-[100] hidden flex items-center justify-center">
<div class="flex flex-col items-center gap-4">
<div class="w-8 h-8 border-2 border-primary border-t-transparent rounded-full animate-spin"></div>
<p class="text-xs font-mono text-secondary" data-i18n="loading.text">PROCESSING</p>
</div>
</div>
<script src="app.js"></script>
</body>
</html>