Files
splatter-tennis/promo/index.html
T

347 lines
19 KiB
HTML

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>SPLATTER TENNIS — the dead club plays you</title>
<meta name="description" content="SNES-style tennis that turns into a zombie splatter game. Free in your browser, built for one hand on a phone. Serve at the dead.">
<meta property="og:title" content="SPLATTER TENNIS">
<meta property="og:description" content="Real tennis until the club turns. Then you serve at the dead. Free, in your browser.">
<meta property="og:image" content="/assets/logo.png">
<link rel="icon" href="/assets/favicon.png">
<style>
@font-face { font-family: 'Silkscreen'; src: url('/assets/fonts/Silkscreen-Regular.ttf'); font-weight: 400; }
@font-face { font-family: 'Silkscreen'; src: url('/assets/fonts/Silkscreen-Bold.ttf'); font-weight: 700; }
@font-face { font-family: 'Bangers'; src: url('/assets/fonts/Bangers-Regular.ttf'); }
:root {
--bg: #0c140e;
--panel: #12201636;
--panel-solid: #101c14;
--chalk: #e8e8dc;
--dim: #9aa694;
--blood: #b83030;
--blood-dark: #6e1414;
--acid: #6ea52a;
--line: #e8e8dc2e;
}
* { margin: 0; padding: 0; box-sizing: border-box; }
html { scroll-behavior: smooth; }
body {
background: var(--bg);
color: var(--chalk);
font-family: Georgia, 'Times New Roman', serif;
font-size: 17px;
line-height: 1.6;
overflow-x: hidden;
}
img.px { image-rendering: pixelated; }
h1, h2, h3 { font-family: 'Silkscreen', monospace; font-weight: 700; line-height: 1.2; }
h2 { font-size: clamp(1.3rem, 4vw, 2rem); margin-bottom: .4em; }
h2 span { color: var(--blood); }
.kicker {
font-family: 'Silkscreen', monospace; font-weight: 400; font-size: .72rem;
letter-spacing: .18em; color: var(--acid); text-transform: uppercase; margin-bottom: .8em;
}
section { max-width: 1060px; margin: 0 auto; padding: 4.5rem 1.25rem; }
section + section { border-top: 1px solid var(--line); }
p.lead { max-width: 46rem; color: var(--chalk); }
p.sub { max-width: 46rem; color: var(--dim); margin-top: .8em; }
/* ---- hero ---- */
.hero {
text-align: center; padding: 4rem 1.25rem 3.5rem; position: relative;
background:
radial-gradient(ellipse 90% 60% at 50% -10%, #1c3322 0%, transparent 70%),
radial-gradient(ellipse 40% 30% at 85% 100%, #3a101055 0%, transparent 70%);
}
.hero .logo { width: min(420px, 82vw); height: auto; filter: drop-shadow(0 6px 0 #00000066); }
.hero .tag {
font-family: 'Bangers', cursive; font-size: clamp(1.6rem, 6vw, 3rem);
letter-spacing: .04em; margin: .6em 0 .2em; color: var(--chalk);
text-shadow: 3px 3px 0 var(--blood-dark);
}
.hero .tag em { font-style: normal; color: var(--blood); }
.hero .under {
font-family: 'Silkscreen', monospace; font-size: .78rem; color: var(--dim);
letter-spacing: .12em; margin-bottom: 2rem;
}
.cta {
display: inline-block; font-family: 'Silkscreen', monospace; font-weight: 700;
font-size: 1rem; letter-spacing: .08em; text-decoration: none;
color: #fff; background: var(--blood); padding: .9em 1.8em;
border: 3px solid var(--chalk); box-shadow: 0 5px 0 var(--blood-dark);
transition: transform .08s, box-shadow .08s;
}
.cta:hover { transform: translateY(2px); box-shadow: 0 3px 0 var(--blood-dark); }
.cta.ghost { background: transparent; color: var(--chalk); box-shadow: 0 5px 0 #00000055; margin-left: .8rem; }
.hero .free {
display: block; margin-top: 1rem; font-family: 'Silkscreen', monospace;
font-size: .7rem; color: var(--acid); letter-spacing: .14em;
}
/* ---- pitch + phone ---- */
.split { display: flex; gap: 3rem; align-items: center; flex-wrap: wrap; }
.split > div { flex: 1 1 320px; }
.phone {
flex: 0 0 auto; margin: 0 auto; width: min(250px, 70vw);
border: 4px solid #2a352c; border-radius: 22px; padding: 10px; background: #000;
box-shadow: 0 18px 40px #000c; transform: rotate(2deg);
}
.phone img { width: 100%; height: auto; display: block; border-radius: 10px; }
.checks { list-style: none; margin-top: 1.4rem; }
.checks li {
font-family: 'Silkscreen', monospace; font-size: .78rem; letter-spacing: .06em;
padding: .45em 0 .45em 1.6em; position: relative; color: var(--chalk);
}
.checks li::before { content: '■'; position: absolute; left: 0; color: var(--blood); }
/* ---- run timeline ---- */
.flow { display: grid; grid-template-columns: repeat(auto-fit, minmax(170px, 1fr)); gap: 1rem; margin-top: 2rem; }
.flow .step {
background: var(--panel); border: 1px solid var(--line); padding: 1.1rem 1rem 1.2rem; position: relative;
}
.flow .n {
font-family: 'Bangers', cursive; font-size: 2rem; color: var(--blood);
line-height: 1; display: block; margin-bottom: .35rem;
}
.flow h3 { font-size: .8rem; letter-spacing: .06em; margin-bottom: .4rem; }
.flow p { font-size: .85rem; color: var(--dim); line-height: 1.45; }
/* ---- modes ---- */
.modes { display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: 1.2rem; margin-top: 2rem; }
.mode { background: var(--panel-solid); border: 1px solid var(--line); overflow: hidden; }
.mode img { width: 100%; height: auto; display: block; border-bottom: 2px solid var(--blood-dark); }
.mode .body { padding: .9rem 1rem 1.1rem; }
.mode h3 { font-size: .95rem; letter-spacing: .05em; }
.mode .rule {
font-family: 'Silkscreen', monospace; font-size: .62rem; color: var(--acid);
letter-spacing: .1em; display: block; margin: .25rem 0 .5rem;
}
.mode p { font-size: .88rem; color: var(--dim); line-height: 1.5; }
/* ---- roster ---- */
.roster { display: grid; grid-template-columns: repeat(auto-fill, minmax(160px, 1fr)); gap: 1rem; margin-top: 2rem; }
.z {
background: var(--panel); border: 1px solid var(--line); text-align: center;
padding: 1.2rem .8rem 1rem;
}
.sprite { height: 130px; position: relative; margin-bottom: .8rem; }
.sprite img {
position: absolute; left: 50%; bottom: 0; transform: translateX(-50%);
height: 100%; width: auto; image-rendering: pixelated;
filter: drop-shadow(0 3px 0 #00000080);
}
.sprite img + img { opacity: 0; animation: shamble .8s steps(1) infinite; }
@keyframes shamble { 50% { opacity: 1; } }
.z h3 { font-size: .72rem; letter-spacing: .04em; }
.z .sub {
font-family: 'Silkscreen', monospace; font-size: .56rem; color: var(--blood);
letter-spacing: .08em; display: block; margin-top: .35rem; min-height: 2em;
}
.z q { font-size: .8rem; color: var(--dim); font-style: italic; quotes: '\201C' '\201D'; }
.boss-grid .sprite { height: 150px; }
.champ {
grid-column: 1 / -1; display: flex; align-items: center; gap: 2rem; flex-wrap: wrap;
background: linear-gradient(135deg, #1c0e0e, #0c140e 65%);
border: 2px solid var(--blood); padding: 1.6rem; text-align: left;
}
.champ .sprite { height: 200px; flex: 0 0 160px; margin: 0; }
.champ h3 { font-family: 'Bangers', cursive; font-size: 2.2rem; letter-spacing: .04em; color: var(--blood); font-weight: 400; }
.champ p { color: var(--dim); max-width: 34rem; margin-top: .4rem; }
.champ .sub { font-family: 'Silkscreen', monospace; font-size: .62rem; letter-spacing: .12em; color: var(--acid); }
/* ---- courts ---- */
.courts { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 1.2rem; margin-top: 2rem; }
.court { border: 1px solid var(--line); background: var(--panel-solid); overflow: hidden; }
.court img { width: 100%; height: 140px; object-fit: cover; display: block; image-rendering: pixelated; }
.court .body { padding: .8rem 1rem 1rem; }
.court h3 { font-size: .78rem; }
.court p { font-family: 'Silkscreen', monospace; font-size: .58rem; color: var(--dim); letter-spacing: .08em; margin-top: .3rem; }
.court.night img { filter: brightness(.62) saturate(.8); }
/* ---- footer ---- */
.foot { text-align: center; padding-bottom: 5rem; }
.foot .tag {
font-family: 'Bangers', cursive; font-size: clamp(1.5rem, 5vw, 2.6rem);
text-shadow: 3px 3px 0 var(--blood-dark); margin-bottom: 1.6rem;
}
.foot .fine {
margin-top: 2.2rem; font-family: 'Silkscreen', monospace; font-size: .6rem;
color: var(--dim); letter-spacing: .1em; line-height: 2;
}
@media (max-width: 560px) {
section { padding: 3rem 1rem; }
.cta.ghost { margin-left: 0; margin-top: .8rem; }
.champ { text-align: center; justify-content: center; }
}
</style>
</head>
<body>
<header class="hero">
<img class="logo px" src="/assets/logo.png" alt="Splatter Tennis">
<p class="tag">Real tennis. Until the club <em>turns</em>.</p>
<p class="under">SNES-STYLE PSEUDO-3D · UMPIRE VOICE · 15/30/40 · AND THE DEAD</p>
<a class="cta" href="/">▶ PLAY NOW</a>
<a class="cta ghost" href="#dead">MEET THE DEAD</a>
<span class="free">FREE · IN YOUR BROWSER · NO DOWNLOAD · NO ACCOUNT</span>
</header>
<section>
<div class="split">
<div>
<p class="kicker">What is it</p>
<h2>A proper tennis game<br>with a <span>body count</span></h2>
<p class="lead">Splatter Tennis opens as a straight-faced 16-bit tennis sim — the kind you
remember from a SNES summer. Toss, time your swing, hold serve. Then you win a game,
the light goes wrong, and the club is on its feet — because the club is dead. From that
point on you serve at zombies, and every tennis ritual keeps running as if nothing
happened: the umpire calls the score, the ball boys still fetch, the crowd still applauds.</p>
<p class="sub">Hit hard enough and a body splatters. Hit soft and it just gets angry.
Kills score points, points make games, games make sets — and the dead keep coming faster.</p>
<ul class="checks">
<li>BUILT FOR ONE THUMB · PORTRAIT · ON YOUR PHONE</li>
<li>INSTALLS TO YOUR HOME SCREEN LIKE AN APP</li>
<li>GLOBAL LEADERBOARD · ONE LIFE PER RUN</li>
<li>RECORDED UMPIRE · REAL SCORING · REAL GORE</li>
</ul>
</div>
<div class="phone"><img class="px" src="/assets/menu_bg.png" alt="Splatter Tennis on a phone"></div>
</div>
</section>
<section>
<p class="kicker">How a run goes</p>
<h2>Every game you win, <span>it escalates</span></h2>
<div class="flow">
<div class="step"><span class="n">1</span><h3>HOLD SERVE</h3>
<p>Win a real game of tennis against a real opponent. He turns mid-match. They all do.</p></div>
<div class="step"><span class="n">2</span><h3>SERVE AT THE DEAD</h3>
<p>Your serve is the weapon. Full power splatters; anything less only staggers them.</p></div>
<div class="step"><span class="n">3</span><h3>SURVIVE THE HORDE</h3>
<p>Every set ends in a horde — the racket auto-fires and your finger just has to keep you alive.</p></div>
<div class="step"><span class="n">4</span><h3>WIN YOUR WEAPONS</h3>
<p>Bombs, triple serves, flame balls. Never found, never bought — only won in sudden-death duels.</p></div>
<div class="step"><span class="n">5</span><h3>FACE THE CHAPTER BOSS</h3>
<p>Every ten games the club sends someone who used to run this place. Contact is still death.</p></div>
</div>
</section>
<section>
<p class="kicker">Five ways to play</p>
<h2>Modes</h2>
<div class="modes">
<div class="mode"><img class="px" src="/assets/mode_classic.png" alt="">
<div class="body"><h3>CLASSIC TENNIS</h3><span class="rule">REAL TENNIS · BEST OF THREE SETS</span>
<p>No blood, no bites. A clean, honest SNES-style tennis match — the game the club used to play.</p></div></div>
<div class="mode"><img class="px" src="/assets/mode_arcade.png" alt="">
<div class="body"><h3>ARCADE</h3><span class="rule">ONE GAME PER OPPONENT · BLOOD ONLY</span>
<p>The endless ladder. Eighteen rungs of undead opponents, each one game, each faster and meaner than the last.</p></div></div>
<div class="mode"><img class="px" src="/assets/mode_cup.png" alt="">
<div class="body"><h3>THE TOURNAMENT</h3><span class="rule">FOUR ROUNDS · THE CHAMPION WAITS</span>
<p>A drawn bracket: round one, quarter-final, semi, and a final that is always THE CHAMPION. Wounds carry between games.</p></div></div>
<div class="mode"><img class="px" src="/assets/mode_gore.png" alt="">
<div class="body"><h3>SPLATTER GORE</h3><span class="rule">NO WARM-UP · SURVIVE THE DEAD CLUB</span>
<p>Straight into the splatter. Hordes, bosses, ball machines, permadeath — the run summary is the whole game.</p></div></div>
<div class="mode"><img class="px" src="/assets/mode_vs.png" alt="">
<div class="body"><h3>VS A FRIEND</h3><span class="rule">LIVE 1V1 · REAL TENNIS · TWO PHONES</span>
<p>Live tennis against a friend, phone to phone. Share a room code and settle it on centre court.</p></div></div>
</div>
</section>
<section id="dead">
<p class="kicker">Know your enemy</p>
<h2>Meet <span>the dead</span></h2>
<p class="lead">Everyone who worked, watched or played at this club is still here. They have kept
their jobs. The jobs have changed.</p>
<div class="roster">
<div class="z"><div class="sprite"><img src="/assets/z_a1.png" alt=""><img src="/assets/z_a2.png" alt=""></div>
<h3>SHAMBLER</h3><span class="sub">THE ORDINARY DEAD</span><q>He was here before any of this.</q></div>
<div class="z"><div class="sprite"><img src="/assets/z_e1.png" alt=""><img src="/assets/z_e2.png" alt=""></div>
<h3>THE BALL BOY</h3><span class="sub">STILL FETCHING</span><q>He still fetches. He just bites now.</q></div>
<div class="z"><div class="sprite"><img src="/assets/z_s1.png" alt=""><img src="/assets/z_s2.png" alt=""></div>
<h3>THE SPECTATOR</h3><span class="sub">BLOCKS WITH HIS CHAIR</span><q>He paid for the whole seat.</q></div>
<div class="z"><div class="sprite"><img src="/assets/z_d1.png" alt=""><img src="/assets/z_d2.png" alt=""></div>
<h3>THE STEWARD</h3><span class="sub">HI-VIS · ONE HIT TOUGHER</span><q>He is asking you to leave.</q></div>
<div class="z"><div class="sprite"><img src="/assets/z_f1.png" alt=""><img src="/assets/z_f2.png" alt=""></div>
<h3>THE RUNNER</h3><span class="sub">ONE HIT · BUT HE SPRINTS</span><q>He covers the court. All of it.</q></div>
<div class="z"><div class="sprite"><img src="/assets/z_g1.png" alt=""><img src="/assets/z_g2.png" alt=""></div>
<h3>THE BRUTE</h3><span class="sub">SLOW · DRAGS A POLE</span><q>Nothing gets past him twice.</q></div>
<div class="z"><div class="sprite"><img src="/assets/z_h1.png" alt=""><img src="/assets/z_h2.png" alt=""></div>
<h3>THE BOUNCER</h3><span class="sub">BUILT LIKE A DOOR</span><q>Name's not on the list.</q></div>
<div class="z"><div class="sprite"><img src="/assets/z_k1.png" alt=""><img src="/assets/z_k2.png" alt=""></div>
<h3>THE ROLLER MAN</h3><span class="sub">HAULS THE COURT ROLLER</span><q>He flattened this court. Then the rest.</q></div>
<div class="z"><div class="sprite"><img src="/assets/z_r1.png" alt=""><img src="/assets/z_r2.png" alt=""></div>
<h3>THE CLUB PRO</h3><span class="sub">STILL HAS A BACKHAND</span><q>Beat him and his weapon is yours.</q></div>
<div class="z"><div class="sprite"><img src="/assets/z_mach1.png" alt=""><img src="/assets/z_mach2.png" alt=""></div>
<h3>THE BALL MACHINE</h3><span class="sub">FIRES BACK · FURNITURE</span><q>Somebody left it on.</q></div>
</div>
</section>
<section>
<p class="kicker">Every tenth game</p>
<h2>The <span>chapter bosses</span></h2>
<p class="lead">The staff went down with the club — and every ten games one of them walks back on
court, clears the stage, and volleys at you until one of you stops moving. They don't shamble.
They remember the game.</p>
<div class="roster boss-grid">
<div class="z"><div class="sprite"><img src="/assets/z_boss1.png" alt=""><img src="/assets/z_boss2.png" alt=""></div>
<h3>THE GROUNDSKEEPER</h3><q>He mowed this lawn for thirty years.</q></div>
<div class="z"><div class="sprite"><img src="/assets/z_judge1.png" alt=""><img src="/assets/z_judge2.png" alt=""></div>
<h3>THE LINE JUDGE</h3><q>Every ball of yours is out.</q></div>
<div class="z"><div class="sprite"><img src="/assets/z_chair1.png" alt=""><img src="/assets/z_chair2.png" alt=""></div>
<h3>THE CHAIR UMPIRE</h3><q>His call was always final.</q></div>
<div class="z"><div class="sprite"><img src="/assets/z_coach1.png" alt=""><img src="/assets/z_coach2.png" alt=""></div>
<h3>THE HEAD COACH</h3><q>He taught you every shot you have.</q></div>
<div class="z"><div class="sprite"><img src="/assets/z_physio1.png" alt=""><img src="/assets/z_physio2.png" alt=""></div>
<h3>THE PHYSIO</h3><q>He knows exactly where it hurts.</q></div>
<div class="z"><div class="sprite"><img src="/assets/z_mascot1.png" alt=""><img src="/assets/z_mascot2.png" alt=""></div>
<h3>THE SPONSOR MASCOT</h3><q>The crowd still loves him.</q></div>
<div class="z"><div class="sprite"><img src="/assets/z_string1.png" alt=""><img src="/assets/z_string2.png" alt=""></div>
<h3>THE STRINGER</h3><q>He strung your racket. He knows its limit.</q></div>
<div class="z"><div class="sprite"><img src="/assets/z_dir1.png" alt=""><img src="/assets/z_dir2.png" alt=""></div>
<h3>THE TOURNAMENT DIRECTOR</h3><q>He is calling security.</q></div>
<div class="z"><div class="sprite"><img src="/assets/z_berry1.png" alt=""><img src="/assets/z_berry2.png" alt=""></div>
<h3>THE STRAWBERRY SELLER</h3><q>Cream with that?</q></div>
<div class="champ">
<div class="sprite"><img src="/assets/z_champ1.png" alt=""><img src="/assets/z_champ2.png" alt=""></div>
<div>
<span class="sub">EVERY TENTH CHAPTER · THE FINAL</span>
<h3>THE CHAMPION</h3>
<p>The name on every trophy in the clubhouse. He returns everything you can hit, he is
faster than anything else on court, and he waits at the end of every tournament. Nobody
has retired him yet.</p>
</div>
</div>
</div>
</section>
<section>
<p class="kicker">Four surfaces</p>
<h2>The courts</h2>
<div class="courts">
<div class="court"><img src="/assets/court_grass.png" alt="">
<div class="body"><h3>CENTRE COURT</h3><p>GRASS · FAST, LOW SKID</p></div></div>
<div class="court"><img src="/assets/court_clay.png" alt="">
<div class="body"><h3>TERRE ROUGE</h3><p>CLAY · SLOW, HIGH KICK</p></div></div>
<div class="court"><img src="/assets/court_hard.png" alt="">
<div class="body"><h3>THE SLAB</h3><p>HARD · TRUE BOUNCE</p></div></div>
<div class="court night"><img src="/assets/court_gloom.png" alt="">
<div class="body"><h3>THE NIGHT COURT</h3><p>AFTER DARK · TRUE BOUNCE, NO LIGHT</p></div></div>
</div>
</section>
<section class="foot">
<p class="tag">The umpire is still calling the score.</p>
<a class="cta" href="/">▶ PLAY SPLATTER TENNIS</a>
<p class="fine">FREE · NO DOWNLOAD · NO ADS · NO ACCOUNT<br>
BEST ON A PHONE, HELD IN ONE HAND · ADD IT TO YOUR HOME SCREEN<br>
ZERO DEPENDENCIES · HANDMADE PIXELS · QUIET, PLEASE</p>
</section>
</body>
</html>