goon/site/index.html
goon-foss 5eb72aeb7f release: 0.4.4 (obwodka fokusu pilota, tablet bez pionu na starcie)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 12:41:11 +02:00

448 lines
21 KiB
HTML

<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover" />
<meta name="description" content="Goon: self-hosted adult content metadata aggregator. Mobile-first, FOSS, ad-free." />
<meta name="robots" content="noindex, nofollow" />
<link rel="icon" type="image/png" href="/favicon.png" />
<link rel="apple-touch-icon" href="/logo.png" />
<title>goon · self-hosted adult content aggregator</title>
<script src="https://cdn.tailwindcss.com"></script>
<script>
tailwind.config = {
theme: {
extend: {
colors: {
/* Warm dark + oxblood, match z mobile theme (2026-05-29 overhaul).
Wcześniej tu był slop navy+purple, niespójność vs nowy app UI. */
bg: '#15110D',
bgElevated: '#1E1A14',
card: '#26201A',
border: '#3A3128',
accent: '#B23A48',
accentGlow: '#D89B4A',
accentDeep: '#7A1F2A',
good: '#5E8C5A',
},
fontFamily: {
sans: ['-apple-system', 'BlinkMacSystemFont', 'Inter', 'system-ui', 'sans-serif'],
mono: ['ui-monospace', 'SFMono-Regular', 'Menlo', 'monospace'],
},
},
},
};
</script>
<style>
body { background-color: #15110D; color: #F5EDE0; }
/* Subtle warm glow zamiast neonowego purpla. */
.glow { box-shadow: 0 0 50px -12px rgba(178, 58, 72, 0.45); }
.grad { background: radial-gradient(60% 60% at 50% 0%, rgba(178,58,72,0.14) 0%, rgba(21,17,13,0) 70%); }
.card-hover { transition: transform 200ms ease, border-color 200ms ease; }
.card-hover:hover { transform: translateY(-2px); border-color: #B23A48; }
.pulse-dot { animation: pulse 2.5s ease-in-out infinite; }
@keyframes pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.4; } }
</style>
</head>
<body class="font-sans antialiased">
<!-- AGE GATE -->
<div id="agegate" class="fixed inset-0 z-50 bg-bg flex items-center justify-center px-6">
<div class="max-w-md text-center">
<div class="inline-block w-3 h-3 rounded-full bg-accent glow pulse-dot mb-6"></div>
<h1 class="text-3xl font-extrabold tracking-tight mb-3">18+ Adults Only</h1>
<p class="text-sm text-gray-400 mb-8 leading-relaxed">
This site discusses software for indexing adult content. You must be of legal
age in your jurisdiction to enter.
</p>
<div class="flex gap-3 justify-center">
<button onclick="document.getElementById('agegate').style.display='none'"
class="px-6 py-3 rounded-xl bg-accent text-white font-bold hover:bg-accentDeep transition">
I'm 18 or older
</button>
<a href="https://www.google.com"
class="px-6 py-3 rounded-xl bg-bgElevated border border-border text-gray-300 font-semibold">
Take me out
</a>
</div>
</div>
</div>
<!-- HERO -->
<header class="grad relative pt-20 pb-24 px-6 overflow-hidden">
<div class="max-w-5xl mx-auto">
<div class="flex items-center gap-3 mb-8">
<img src="/logo.png" alt="goon" width="40" height="40" class="rounded-lg" />
<span class="text-2xl font-extrabold tracking-tight">
<span class="text-gray-100">g</span><span class="text-accent">oo</span><span class="text-gray-100">n</span>
</span>
</div>
<h1 class="text-5xl md:text-7xl font-extrabold tracking-tight leading-[0.95] mb-6">
Self-hosted<br>
<span class="text-accent">scene catalog</span><br>
for grown-ups.
</h1>
<p class="text-lg md:text-xl text-gray-400 max-w-2xl leading-relaxed mb-10">
Goon indexes scene and movie metadata from TPDB &amp; StashDB, deduplicates it
across 43 public sources, and serves a fast mobile client. Zero ads. Zero tracking.
Download, open, browse. No account, no setup.
</p>
<div class="flex flex-wrap gap-3">
<a href="/goon-v0.4.4.apk"
class="px-6 py-4 rounded-xl bg-accent text-white font-bold hover:bg-accentDeep transition glow">
Download APK
</a>
<a href="#donate"
class="px-6 py-4 rounded-xl bg-transparent border border-border text-gray-400 font-semibold hover:text-accent hover:border-accent transition">
♥ Donate
</a>
</div>
<div class="flex flex-wrap gap-x-8 gap-y-3 mt-10 font-mono text-sm">
<div><span class="text-accent font-bold">3.3M</span> <span class="text-gray-500">scenes</span></div>
<div><span class="text-accent font-bold">110k</span> <span class="text-gray-500">performers</span></div>
<div><span class="text-accent font-bold">46k</span> <span class="text-gray-500">movies</span></div>
<div><span class="text-accent font-bold">43</span> <span class="text-gray-500">sources</span></div>
</div>
<p class="text-xs text-gray-500 mt-6 font-mono">
Android 7+ · no setup, no login · 18+
</p>
</div>
</header>
<!-- FEATURES -->
<section class="px-6 py-20 bg-bgElevated/30 border-y border-border">
<div class="max-w-5xl mx-auto">
<h2 class="text-3xl font-extrabold mb-2 tracking-tight">What it does</h2>
<p class="text-gray-500 mb-12 max-w-xl">
Goon is not a tube. It does not host, transcode, or proxy content.
It is a metadata aggregator + mobile UI for finding scenes that are
already publicly available.
</p>
<div class="grid md:grid-cols-2 lg:grid-cols-3 gap-4">
<div class="card-hover bg-card border border-border rounded-2xl p-6">
<div class="text-accent text-2xl mb-3">⌬</div>
<h3 class="text-lg font-bold mb-2">Multi-source ingest</h3>
<p class="text-sm text-gray-400 leading-relaxed">
TPDB &amp; StashDB metadata plus 43 public sources, scenes and full movies.
Cross-source deduplication via perceptual-hash thumbnails and title matching,
so the same scene from six tubes stays one entry.
</p>
</div>
<div class="card-hover bg-card border border-border rounded-2xl p-6">
<div class="text-accent text-2xl mb-3">⌖</div>
<h3 class="text-lg font-bold mb-2">Per-performer backfill</h3>
<p class="text-sm text-gray-400 leading-relaxed">
A continuous worker walks performers by staleness and back-fills tube scenes
for the longest-stale first. Completeness over recency.
</p>
</div>
<div class="card-hover bg-card border border-border rounded-2xl p-6">
<div class="text-accent text-2xl mb-3">⌥</div>
<h3 class="text-lg font-bold mb-2">Smart stream resolution</h3>
<p class="text-sm text-gray-400 leading-relaxed">
yt-dlp for mainstream tubes + P.A.C.K.E.R. unpacker for JWPlayer hosters
+ WebView fallback for IP-bound CDNs. Streams direct from source, no transcoding.
</p>
</div>
<div class="card-hover bg-card border border-border rounded-2xl p-6">
<div class="text-accent text-2xl mb-3">⌗</div>
<h3 class="text-lg font-bold mb-2">Mobile-first UI</h3>
<p class="text-sm text-gray-400 leading-relaxed">
React Native + Expo. Separate tabs for scenes, movies, sites and JAV,
plus performer pages, watch history, favorites and hold-to-preview
thumbnails. Built for thumb scrolling.
</p>
</div>
<div class="card-hover bg-card border border-border rounded-2xl p-6">
<div class="text-accent text-2xl mb-3">⌘</div>
<h3 class="text-lg font-bold mb-2">Privacy by default</h3>
<p class="text-sm text-gray-400 leading-relaxed">
App lock (PIN + biometrics), FLAG_SECURE screenshot block, age gate.
No analytics. No telemetry unless YOU configure Sentry with your own DSN.
</p>
</div>
<div class="card-hover bg-card border border-border rounded-2xl p-6">
<div class="text-accent text-2xl mb-3">⌬</div>
<h3 class="text-lg font-bold mb-2">Works out of the box</h3>
<p class="text-sm text-gray-400 leading-relaxed">
Download the APK and it connects automatically, no account, no
config. Power users can point it at their own self-hosted backend.
</p>
</div>
</div>
</div>
</section>
<!-- SCREENSHOTS -->
<section class="px-6 py-20">
<div class="max-w-5xl mx-auto">
<h2 class="text-3xl font-extrabold mb-2 tracking-tight">In the app</h2>
<p class="text-gray-500 mb-12">Screenshots from a real install. Thumbnails are blurred here, not in the app.</p>
<div class="grid grid-cols-2 md:grid-cols-4 gap-4">
<figure class="bg-card border border-border rounded-2xl overflow-hidden">
<img src="/shots/01_scenes_grid.png" alt="Scenes screen" loading="lazy" width="1080" height="2400"
class="w-full h-auto block" />
<figcaption class="p-4">
<div class="text-sm font-bold mb-1">Scenes</div>
<div class="text-xs text-gray-500 leading-relaxed">Grid with search, tag filters and favourites.</div>
</figcaption>
</figure>
<figure class="bg-card border border-border rounded-2xl overflow-hidden">
<img src="/shots/03_scene_detail.png" alt="Scene screen" loading="lazy" width="1080" height="2400"
class="w-full h-auto block" />
<figcaption class="p-4">
<div class="text-sm font-bold mb-1">Scene</div>
<div class="text-xs text-gray-500 leading-relaxed">Cast, studio, tags and every source that has it.</div>
</figcaption>
</figure>
<figure class="bg-card border border-border rounded-2xl overflow-hidden">
<img src="/shots/06_performer_page.png" alt="Performer screen" loading="lazy" width="1080" height="2400"
class="w-full h-auto block" />
<figcaption class="p-4">
<div class="text-sm font-bold mb-1">Performer</div>
<div class="text-xs text-gray-500 leading-relaxed">Everything indexed for one performer.</div>
</figcaption>
</figure>
<figure class="bg-card border border-border rounded-2xl overflow-hidden">
<img src="/shots/02_settings.png" alt="App lock screen" loading="lazy" width="1080" height="2400"
class="w-full h-auto block" />
<figcaption class="p-4">
<div class="text-sm font-bold mb-1">App lock</div>
<div class="text-xs text-gray-500 leading-relaxed">PIN and biometrics, screenshots blocked.</div>
</figcaption>
</figure>
</div>
</div>
</section>
<!-- WHAT'S NEW -->
<section class="px-6 py-20 bg-bgElevated/30 border-y border-border">
<div class="max-w-5xl mx-auto">
<h2 class="text-3xl font-extrabold mb-2 tracking-tight">What's new</h2>
<p class="text-gray-500 mb-12 max-w-xl">
The catalog keeps growing. Recent additions, newest first.
</p>
<div class="space-y-6">
<div class="bg-card border border-border rounded-2xl p-6">
<div class="font-mono text-xs text-accent mb-2">October 2026 &middot; 0.4.4</div>
<h3 class="text-lg font-bold mb-2">TV remote you can see</h3>
<p class="text-sm text-gray-400 leading-relaxed">
On Fire TV and Android TV the item picked with the remote now gets a clear outline,
so you always know where you are. Tablets start in landscape instead of a narrow
portrait strip. Installs over 0.4.3 (same signing key).
</p>
</div>
<div class="bg-card border border-border rounded-2xl p-6">
<div class="font-mono text-xs text-accent mb-2">October 2026 &middot; 0.4.3</div>
<h3 class="text-lg font-bold mb-2">Android TV stays up</h3>
<p class="text-sm text-gray-400 leading-relaxed">
On TV boxes the app could crash when it was opened from two places at once,
for example the TV home screen and a shortcut. Fixed by running a single
activity. Native crash reports now carry debug symbols, so the remaining
rare crashes can be traced. Installs over 0.4.2 (same signing key).
</p>
</div>
<div class="bg-card border border-border rounded-2xl p-6">
<div class="font-mono text-xs text-accent mb-2">September 2026 &middot; 0.4.0</div>
<h3 class="text-lg font-bold mb-2">Edge</h3>
<p class="text-sm text-gray-400 leading-relaxed">
A new tab with a vertical feed of short clips from verified creators, one per
screen, playing the moment you land on it. Double-tap to save, tap for sound,
hold for double speed, swipe left to say what you want less of. The feed learns
from what you watch and never repeats a clip. Needs the 0.4.0 APK; it installs
over the version you have.
</p>
</div>
<div class="bg-card border border-border rounded-2xl p-6">
<div class="font-mono text-xs text-accent mb-2">August 2026</div>
<h3 class="text-lg font-bold mb-2">Fewer dead links</h3>
<p class="text-sm text-gray-400 leading-relaxed">
Around 81,000 sources whose page the host had quietly deleted were cleared out,
so scenes no longer look playable when they are not. One source that had never
worked at all is fixed, and two more now refresh the link and retry instead of
failing when the host expires it.
</p>
</div>
<div class="bg-card border border-border rounded-2xl p-6">
<div class="font-mono text-xs text-accent mb-2">August 2026 &middot; 0.3.0</div>
<h3 class="text-lg font-bold mb-2">Chromecast</h3>
<p class="text-sm text-gray-400 leading-relaxed">
Send a scene to the TV straight from the player. The button shows up when there
is a Chromecast on your network. Sources that open in the built-in browser cannot
be cast, so on those the button stays hidden.
</p>
</div>
<div class="bg-card border border-border rounded-2xl p-6">
<div class="font-mono text-xs text-accent mb-2">August 2026</div>
<h3 class="text-lg font-bold mb-2">Animation and 3D</h3>
<p class="text-sm text-gray-400 leading-relaxed">
Six new sources covering hentai and 3D animation, each with its own
catalogue rather than reposts of the others. Series, episode numbers and
genres come along with them.
</p>
</div>
<div class="bg-card border border-border rounded-2xl p-6">
<div class="font-mono text-xs text-accent mb-2">August 2026</div>
<h3 class="text-lg font-bold mb-2">45,000 movies</h3>
<p class="text-sm text-gray-400 leading-relaxed">
Full-length movies now sit in their own tab, enriched with cast, studio
and categories, and deduplicated against each other.
</p>
</div>
<div class="bg-card border border-border rounded-2xl p-6">
<div class="font-mono text-xs text-accent mb-2">July 2026</div>
<h3 class="text-lg font-bold mb-2">JAV in its own tab</h3>
<p class="text-sm text-gray-400 leading-relaxed">
JAV is a separate namespace that does not deduplicate against the western
catalogue, so it lives in its own tab instead of mixing into the main feed.
</p>
</div>
</div>
</div>
</section>
<!-- GET STARTED -->
<section class="px-6 py-20 bg-bgElevated/30 border-y border-border">
<div class="max-w-3xl mx-auto">
<h2 class="text-3xl font-extrabold mb-3 tracking-tight">Get started</h2>
<p class="text-gray-500 mb-8">Three steps. No account, no server, no config.</p>
<div class="bg-card border-2 border-accent rounded-2xl p-5 mb-6">
<p class="text-sm font-bold text-accent mb-2">Already have Goon installed? Read this first.</p>
<p class="text-sm text-gray-300 leading-relaxed">
<strong class="text-gray-100">On 0.2.2 or newer:</strong> nothing to do. 0.4.0 installs
straight over it and keeps your favourites, saved searches and watch progress.
<br><br>
<strong class="text-gray-100">On anything older than 0.2.2:</strong> that build was
signed with a key we no longer have, so Android refuses to install over it. You have to
uninstall first, and that wipes what is stored on the phone. Before you uninstall, open
Goon, go to Settings, Backup &amp; sync, and copy your sync code. Install this APK, then
paste the code into Restore. Without it your favourites, saved searches, hidden list and
watch progress cannot be found again.
</p>
</div>
<ol class="space-y-4">
<li class="bg-card border border-border rounded-2xl p-5 flex gap-4">
<span class="text-accent font-extrabold text-xl">1</span>
<span class="text-sm text-gray-300 leading-relaxed">
<a href="/goon-v0.4.4.apk" class="text-accent font-bold hover:underline">Download the APK</a>
and open it. Allow "install from unknown sources" for your browser if Android asks.
</span>
</li>
<li class="bg-card border border-border rounded-2xl p-5 flex gap-4">
<span class="text-accent font-extrabold text-xl">2</span>
<span class="text-sm text-gray-300 leading-relaxed">
Open the app, accept the 18+ gate. It connects automatically, no login.
</span>
</li>
<li class="bg-card border border-border rounded-2xl p-5 flex gap-4">
<span class="text-accent font-extrabold text-xl">3</span>
<span class="text-sm text-gray-300 leading-relaxed">
Browse. That's it.
</span>
</li>
</ol>
</div>
</section>
<!-- DONATE -->
<section id="donate" class="px-6 py-20">
<div class="max-w-3xl mx-auto">
<h2 class="text-3xl font-extrabold mb-3 tracking-tight">Support the project</h2>
<p class="text-gray-400 mb-8 leading-relaxed max-w-xl">
Goon stays free and ad-free because donations cover the VPS, the
TPDB/StashDB tokens, and the time. <strong class="text-gray-200">Crypto
only</strong>. Mainstream processors won't touch adult-adjacent
FOSS projects.
</p>
<div class="grid sm:grid-cols-3 gap-3">
<div class="bg-card border border-border rounded-2xl p-5">
<div class="text-orange-500 text-xs font-mono font-bold mb-1">XMR</div>
<div class="text-sm font-bold mb-3">Monero</div>
<p class="text-xs text-gray-500 leading-relaxed">
Privacy by default. Recommended. Get the address from the app or the project README.
</p>
</div>
<div class="bg-card border border-border rounded-2xl p-5">
<div class="text-yellow-500 text-xs font-mono font-bold mb-1">BTC</div>
<div class="text-sm font-bold mb-3">Bitcoin</div>
<p class="text-xs text-gray-500 leading-relaxed">
Mainstream &amp; easy to send. Use a fresh wallet if you care about on-chain anonymity.
</p>
</div>
<div class="bg-card border border-border rounded-2xl p-5">
<div class="text-blue-400 text-xs font-mono font-bold mb-1">LTC</div>
<div class="text-sm font-bold mb-3">Litecoin</div>
<p class="text-xs text-gray-500 leading-relaxed">
Fast and cheap (~$0.01 fee). Lower adoption than BTC but friendlier for small donations.
</p>
</div>
</div>
<p class="text-xs text-gray-500 mt-6">
Addresses + QR codes are shown in the app under Scenes &raquo; ♥.
</p>
</div>
</section>
<!-- FOOTER -->
<footer class="px-6 py-12 border-t border-border">
<div class="max-w-5xl mx-auto flex flex-col sm:flex-row gap-6 justify-between text-xs text-gray-500">
<div>
<div class="flex items-center gap-2 mb-2">
<div class="w-2 h-2 rounded-full bg-accent"></div>
<span class="font-bold tracking-widest uppercase">goon</span>
</div>
<p>Adult content metadata aggregator. FOSS, ad-free.</p>
<p>MIT license. No warranty. 18+ jurisdictions only.</p>
<p class="mt-2">
Source:
<a href="https://git.goon-foss.org/goon-foss/goon" class="text-accent hover:underline">git.goon-foss.org/goon-foss/goon</a>
</p>
</div>
<div class="flex flex-col gap-1 text-right">
<a href="/goon-v0.4.4.apk" class="hover:text-accent transition">Download APK</a>
<a href="https://git.goon-foss.org/goon-foss/goon" class="hover:text-accent transition">Source code</a>
<a href="#donate" class="hover:text-accent transition">Donate</a>
</div>
</div>
<p class="max-w-5xl mx-auto mt-6 text-[10px] text-gray-600 leading-relaxed">
Goon does not host, transcode, store, or distribute any media. It scrapes
publicly-available metadata and links out to the source. Users are
responsible for complying with local law.
</p>
</footer>
<script>
// Persist age-gate acknowledgement so it doesn't reappear every visit.
if (localStorage.getItem('agegate_v1') === 'ok') {
document.getElementById('agegate').style.display = 'none';
}
document.querySelector('#agegate button').addEventListener('click', function () {
localStorage.setItem('agegate_v1', 'ok');
});
</script>
</body>
</html>