Skip to content

Commit 6987ae5

Browse files
authored
feat: add static landing page for TF2-QuickServer (#308)
* feat: add static landing page for TF2-QuickServer * refactor: customer-focused landing page, add Discord install CTA - Replace Self-Hosting section with Install Bot section - Add Discord OAuth install button with guild/user explanation - Make Install Bot the primary hero CTA - Remove contributor-focused self-hosting content - Update footer links to be customer-oriented * fix: OAuth scopes, separate guild/user install buttons, remove self-hosting
1 parent d57bd38 commit 6987ae5

3 files changed

Lines changed: 750 additions & 0 deletions

File tree

landing-page/index.html

Lines changed: 337 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,337 @@
1+
<!doctype html>
2+
<html lang="en" data-bs-theme="dark">
3+
<head>
4+
<meta charset="UTF-8" />
5+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
6+
<title>TF2-QuickServer — Deploy TF2 Servers from Discord</title>
7+
<meta name="description" content="Deploy Team Fortress 2 servers directly from Discord using Docker and multi-cloud infrastructure. Spin up a server in minutes." />
8+
<meta property="og:title" content="TF2-QuickServer — Deploy TF2 Servers from Discord" />
9+
<meta property="og:description" content="Deploy Team Fortress 2 servers directly from Discord using Docker and multi-cloud infrastructure. Spin up a server in minutes." />
10+
<meta property="og:url" content="https://tf2-quickserver.sonikro.com" />
11+
<meta property="og:image" content="https://raw.githubusercontent.com/sonikro/TF2-QuickServer/main/assets/logo.png" />
12+
<meta property="og:image:width" content="512" />
13+
<meta property="og:image:height" content="512" />
14+
<meta property="og:type" content="website" />
15+
<meta name="twitter:card" content="summary_large_image" />
16+
<meta name="twitter:image" content="https://raw.githubusercontent.com/sonikro/TF2-QuickServer/main/assets/logo.png" />
17+
<link rel="preconnect" href="https://fonts.googleapis.com" />
18+
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
19+
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&display=swap" rel="stylesheet" />
20+
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet" />
21+
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css" rel="stylesheet" />
22+
<link href="https://cdn.jsdelivr.net/npm/flag-icons@7.2.3/css/flag-icons.min.css" rel="stylesheet" />
23+
<link href="style.css" rel="stylesheet" />
24+
<link rel="icon" href="../assets/logo.png" type="image/png" />
25+
</head>
26+
<body>
27+
28+
<!-- Navigation -->
29+
<nav class="navbar navbar-expand-lg navbar-dark fixed-top" aria-label="Main navigation">
30+
<div class="container">
31+
<a class="navbar-brand" href="#">
32+
<img src="../assets/logo.png" alt="TF2-QuickServer" height="36" class="d-inline-block align-middle me-2" />
33+
<span class="align-middle fw-bold">TF2-QuickServer</span>
34+
</a>
35+
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#mainNav">
36+
<span class="navbar-toggler-icon"></span>
37+
</button>
38+
<div class="collapse navbar-collapse" id="mainNav">
39+
<ul class="navbar-nav ms-auto">
40+
<li class="nav-item"><a class="nav-link" href="#features">Features</a></li>
41+
<li class="nav-item"><a class="nav-link" href="#how-it-works">How It Works</a></li>
42+
<li class="nav-item"><a class="nav-link" href="#regions">Regions</a></li>
43+
<li class="nav-item"><a class="nav-link" href="#commands">Commands</a></li>
44+
<li class="nav-item"><a class="nav-link" href="#install">Install Bot</a></li>
45+
</ul>
46+
</div>
47+
</div>
48+
</nav>
49+
50+
<!-- Hero -->
51+
<section id="hero" class="hero d-flex align-items-center">
52+
<div class="container text-center">
53+
<img src="../assets/logo.png" alt="TF2-QuickServer Logo" class="hero-logo mb-4" />
54+
<h1 class="hero-title">TF2-QuickServer</h1>
55+
<p class="hero-subtitle">Deploy Team Fortress 2 servers directly from Discord.<br />Powered by Docker &mdash; multi-cloud, global, and ready in minutes.</p>
56+
<div class="hero-cta mt-4">
57+
<a href="https://discord.com/oauth2/authorize?client_id=1355639481020977243&scope=bot%20applications.commands&permissions=0" class="btn btn-install btn-lg me-3 mb-2" target="_blank" rel="noopener">
58+
<i class="fab fa-discord me-2"></i>Install the Bot
59+
</a>
60+
<a href="https://discord.gg/HfDgMj73cW" class="btn btn-discord btn-lg me-3 mb-2" target="_blank" rel="noopener">
61+
<i class="fab fa-discord me-2"></i>Join Discord
62+
</a>
63+
<a href="https://github.com/sonikro/TF2-QuickServer/wiki" class="btn btn-outline-light btn-lg mb-2" target="_blank" rel="noopener">
64+
<i class="fas fa-book me-2"></i>Wiki
65+
</a>
66+
</div>
67+
</div>
68+
</section>
69+
70+
<!-- Features -->
71+
<section id="features" class="section">
72+
<div class="container">
73+
<h2 class="section-title text-center">Features</h2>
74+
<p class="section-subtitle text-center">Everything you need to run TF2 servers</p>
75+
<div class="row g-4 mt-3">
76+
<div class="col-md-6 col-lg-4">
77+
<div class="feature-card card h-100">
78+
<div class="card-body text-center p-4">
79+
<div class="feature-icon"><i class="fas fa-bolt"></i></div>
80+
<h5 class="card-title">Quick Server Deployment</h5>
81+
<p class="card-text">Spin up a TF2 server in ~3 minutes with a simple Discord command. No manual configuration needed.</p>
82+
</div>
83+
</div>
84+
</div>
85+
<div class="col-md-6 col-lg-4">
86+
<div class="feature-card card h-100">
87+
<div class="card-body text-center p-4">
88+
<div class="feature-icon"><i class="fas fa-globe-americas"></i></div>
89+
<h5 class="card-title">Multi-Cloud Global</h5>
90+
<p class="card-text">Deploy across Oracle Cloud regions and AWS Local Zones for low-latency gameplay worldwide.</p>
91+
</div>
92+
</div>
93+
</div>
94+
<div class="col-md-6 col-lg-4">
95+
<div class="feature-card card h-100">
96+
<div class="card-body text-center p-4">
97+
<div class="feature-icon"><i class="fas fa-shield-halved"></i></div>
98+
<h5 class="card-title">DDoS Protection</h5>
99+
<p class="card-text">TF2-QuickServer-Shield monitors and blocks attacks in real time with in-game notifications.</p>
100+
</div>
101+
</div>
102+
</div>
103+
<div class="col-md-6 col-lg-4">
104+
<div class="feature-card card h-100">
105+
<div class="card-body text-center p-4">
106+
<div class="feature-icon"><i class="fas fa-cubes"></i></div>
107+
<h5 class="card-title">Containerized</h5>
108+
<p class="card-text">Each server runs in an isolated Docker container with baked-in maps and configs.</p>
109+
</div>
110+
</div>
111+
</div>
112+
<div class="col-md-6 col-lg-4">
113+
<div class="feature-card card h-100">
114+
<div class="card-body text-center p-4">
115+
<div class="feature-icon"><i class="fas fa-coins"></i></div>
116+
<h5 class="card-title">Auto Cost Savings</h5>
117+
<p class="card-text">Idle servers terminate after 10 minutes. Pay only for what you use &mdash; no wasted resources.</p>
118+
</div>
119+
</div>
120+
</div>
121+
<div class="col-md-6 col-lg-4">
122+
<div class="feature-card card h-100">
123+
<div class="card-body text-center p-4">
124+
<div class="feature-icon"><i class="fas fa-chart-line"></i></div>
125+
<h5 class="card-title">Full Observability</h5>
126+
<p class="card-text">OpenTelemetry instrumentation provides traces, metrics, and logs. Optional New Relic sidecar for enhanced infrastructure monitoring.</p>
127+
</div>
128+
</div>
129+
</div>
130+
</div>
131+
</div>
132+
</section>
133+
134+
<!-- How It Works -->
135+
<section id="how-it-works" class="section bg-section">
136+
<div class="container">
137+
<h2 class="section-title text-center">How It Works</h2>
138+
<p class="section-subtitle text-center">From command to server in five simple steps</p>
139+
<div class="row mt-4">
140+
<div class="col-lg-10 mx-auto">
141+
<div class="step-list">
142+
<div class="step">
143+
<div class="step-number">1</div>
144+
<div class="step-content">
145+
<h5>Install the Bot</h5>
146+
<p>Add TF2-QuickServer to your Discord server with one click.</p>
147+
</div>
148+
</div>
149+
<div class="step">
150+
<div class="step-number">2</div>
151+
<div class="step-content">
152+
<h5>Run <code>/create-server &lt;region&gt;</code></h5>
153+
<p>Choose a region near you for the best latency.</p>
154+
</div>
155+
</div>
156+
<div class="step">
157+
<div class="step-number">3</div>
158+
<div class="step-content">
159+
<h5>Select a Variant</h5>
160+
<p>Pick a server config like <code>standard-competitive</code> or your custom variant.</p>
161+
</div>
162+
</div>
163+
<div class="step">
164+
<div class="step-number">4</div>
165+
<div class="step-content">
166+
<h5>Receive Connection Info</h5>
167+
<p>Get SDR, direct, and STV addresses along with passwords instantly.</p>
168+
</div>
169+
</div>
170+
<div class="step">
171+
<div class="step-number">5</div>
172+
<div class="step-content">
173+
<h5>Connect &amp; Play</h5>
174+
<p>Join the server and play. The server auto-terminates after 10 minutes of idle.</p>
175+
</div>
176+
</div>
177+
</div>
178+
</div>
179+
</div>
180+
</div>
181+
</section>
182+
183+
<!-- Install the Bot -->
184+
<section id="install" class="section">
185+
<div class="container">
186+
<h2 class="section-title text-center">Install the Bot</h2>
187+
<p class="section-subtitle text-center">Add TF2-QuickServer to your Discord in seconds</p>
188+
<div class="row mt-4 justify-content-center">
189+
<div class="col-lg-8">
190+
<div class="card install-card">
191+
<div class="card-body p-5 text-center">
192+
<div class="install-icon mb-4"><i class="fab fa-discord"></i></div>
193+
<p class="install-description">
194+
You can install TF2-QuickServer in any Discord server where you have the
195+
<strong>Manage Server</strong> permission, or install it for your own user account
196+
to use across all your servers.
197+
</p>
198+
<div class="d-flex flex-wrap justify-content-center gap-3 mt-3">
199+
<a href="https://discord.com/oauth2/authorize?client_id=1355639481020977243&scope=bot%20applications.commands&permissions=0&integration_type=0" class="btn btn-install btn-lg" target="_blank" rel="noopener">
200+
<i class="fab fa-discord me-2"></i>Add to Server
201+
</a>
202+
<a href="https://discord.com/oauth2/authorize?client_id=1355639481020977243&scope=applications.commands&integration_type=1" class="btn btn-outline-light btn-lg" target="_blank" rel="noopener">
203+
<i class="fas fa-user me-2"></i>Install for Me
204+
</a>
205+
</div>
206+
<p class="text-muted small mt-3 mb-0">
207+
No credit card required. No setup needed. Works immediately after install.
208+
</p>
209+
</div>
210+
</div>
211+
</div>
212+
</div>
213+
</div>
214+
</section>
215+
216+
<!-- Regions -->
217+
<section id="regions" class="section bg-section">
218+
<div class="container">
219+
<h2 class="section-title text-center">Supported Regions</h2>
220+
<p class="section-subtitle text-center">Global coverage for low-latency gameplay</p>
221+
<div class="row mt-4 g-4">
222+
<div class="col-md-6">
223+
<div class="card h-100">
224+
<div class="card-body p-4">
225+
<h5 class="card-title"><i class="fas fa-cloud me-2 text-primary"></i>Oracle Cloud Infrastructure</h5>
226+
<ul class="list-unstyled mt-3 region-list">
227+
<li><span class="fi fi-cl region-flag" title="Chile"></span> Santiago</li>
228+
<li><span class="fi fi-br region-flag" title="Brazil"></span> S&atilde;o Paulo</li>
229+
<li><span class="fi fi-co region-flag" title="Colombia"></span> Bogot&aacute;</li>
230+
<li><span class="fi fi-us region-flag" title="United States"></span> Chicago</li>
231+
<li><span class="fi fi-de region-flag" title="Germany"></span> Frankfurt</li>
232+
<li><span class="fi fi-au region-flag" title="Australia"></span> Sydney</li>
233+
</ul>
234+
</div>
235+
</div>
236+
</div>
237+
<div class="col-md-6">
238+
<div class="card h-100">
239+
<div class="card-body p-4">
240+
<h5 class="card-title"><i class="fas fa-cloud me-2 text-warning"></i>AWS Local Zones <span class="badge bg-warning text-dark">Experimental</span></h5>
241+
<ul class="list-unstyled mt-3 region-list">
242+
<li><span class="fi fi-ar region-flag" title="Argentina"></span> Buenos Aires</li>
243+
<li><span class="fi fi-pe region-flag" title="Peru"></span> Lima</li>
244+
</ul>
245+
</div>
246+
</div>
247+
</div>
248+
</div>
249+
</div>
250+
</section>
251+
252+
<!-- Commands -->
253+
<section id="commands" class="section">
254+
<div class="container">
255+
<h2 class="section-title text-center">Discord Commands</h2>
256+
<p class="section-subtitle text-center">Control everything from your chat</p>
257+
<div class="row mt-4">
258+
<div class="col-lg-10 mx-auto">
259+
<div class="table-responsive">
260+
<table class="table table-dark table-striped command-table">
261+
<thead>
262+
<tr>
263+
<th scope="col">Command</th>
264+
<th scope="col">Description</th>
265+
</tr>
266+
</thead>
267+
<tbody>
268+
<tr>
269+
<td><code>/create-server &lt;region&gt;</code></td>
270+
<td>Launches a server in the selected region (prompts for variant)</td>
271+
</tr>
272+
<tr>
273+
<td><code>/get-my-servers</code></td>
274+
<td>Retrieves all your active server details (IPs, passwords, etc.)</td>
275+
</tr>
276+
<tr>
277+
<td><code>/status</code></td>
278+
<td>Shows current status of all servers across all regions</td>
279+
</tr>
280+
<tr>
281+
<td><code>/terminate-servers</code></td>
282+
<td>Terminates all servers created by the user</td>
283+
</tr>
284+
<tr>
285+
<td><code>/set-user-data &lt;steamId&gt;</code></td>
286+
<td>Sets SteamID for Sourcemod admin permissions</td>
287+
</tr>
288+
</tbody>
289+
</table>
290+
</div>
291+
</div>
292+
</div>
293+
</div>
294+
</section>
295+
296+
<!-- Footer -->
297+
<footer class="footer">
298+
<div class="container">
299+
<div class="row g-4">
300+
<div class="col-md-4">
301+
<h5><img src="../assets/logo.png" alt="TF2-QuickServer" height="28" class="me-2" />TF2-QuickServer</h5>
302+
<p class="text-muted small mt-2">Deploy Team Fortress 2 servers from Discord. Multi-cloud, global, and ready in minutes.</p>
303+
</div>
304+
<div class="col-md-4">
305+
<h5>Get Started</h5>
306+
<ul class="list-unstyled footer-links">
307+
<li><a href="https://discord.com/oauth2/authorize?client_id=1355639481020977243&scope=bot%20applications.commands&permissions=0" target="_blank" rel="noopener"><i class="fab fa-discord me-2"></i>Install Bot</a></li>
308+
<li><a href="https://discord.gg/HfDgMj73cW" target="_blank" rel="noopener"><i class="fab fa-discord me-2"></i>Join Discord</a></li>
309+
<li><a href="https://github.com/sonikro/TF2-QuickServer/wiki" target="_blank" rel="noopener"><i class="fas fa-book me-2"></i>Wiki</a></li>
310+
<li><a href="https://status.sonikro.com/" target="_blank" rel="noopener"><i class="fas fa-heart-pulse me-2"></i>Status</a></li>
311+
</ul>
312+
</div>
313+
<div class="col-md-4">
314+
<h5>Resources</h5>
315+
<ul class="list-unstyled footer-links">
316+
<li><a href="https://github.com/sonikro/TF2-QuickServer/issues" target="_blank" rel="noopener"><i class="fas fa-bug me-2"></i>Report a Bug</a></li>
317+
<li><a href="https://github.com/sonikro/TF2-QuickServer" target="_blank" rel="noopener"><i class="fab fa-github me-2"></i>GitHub</a></li>
318+
<li><a href="https://github.com/sonikro/TF2-QuickServer/blob/main/docs/api/openapi.yaml" target="_blank" rel="noopener"><i class="fas fa-code me-2"></i>API Spec</a></li>
319+
</ul>
320+
</div>
321+
</div>
322+
<hr class="mt-4 mb-3" />
323+
<div class="row">
324+
<div class="col-md-6 text-center text-md-start">
325+
<p class="text-muted small mb-0">&copy; 2025-2026 TF2-QuickServer. MIT License.</p>
326+
</div>
327+
<div class="col-md-6 text-center text-md-end">
328+
<p class="text-muted small mb-0">Logo by <a href="https://www.instagram.com/thecleandesign/" target="_blank" rel="noopener" class="text-muted">kcaugolden</a></p>
329+
</div>
330+
</div>
331+
</div>
332+
</footer>
333+
334+
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>
335+
<script src="script.js"></script>
336+
</body>
337+
</html>

landing-page/script.js

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
document.addEventListener('DOMContentLoaded', () => {
2+
const nav = document.querySelector('.navbar');
3+
const navLinks = document.querySelectorAll('.nav-link');
4+
const sections = document.querySelectorAll('section[id]');
5+
6+
function updateActiveLink() {
7+
const navHeight = nav.offsetHeight;
8+
let current = '';
9+
sections.forEach(section => {
10+
const top = section.offsetTop - navHeight - 10;
11+
if (window.scrollY >= top) {
12+
current = section.getAttribute('id');
13+
}
14+
});
15+
navLinks.forEach(link => {
16+
link.classList.remove('active');
17+
if (link.getAttribute('href') === '#' + current) {
18+
link.classList.add('active');
19+
}
20+
});
21+
}
22+
23+
navLinks.forEach(link => {
24+
link.addEventListener('click', e => {
25+
const target = document.querySelector(link.getAttribute('href'));
26+
if (target) {
27+
e.preventDefault();
28+
const navbarCollapse = document.querySelector('.navbar-collapse');
29+
if (navbarCollapse.classList.contains('show')) {
30+
bootstrap.Collapse.getInstance(navbarCollapse).hide();
31+
}
32+
target.scrollIntoView({ behavior: 'smooth', block: 'start' });
33+
}
34+
});
35+
});
36+
37+
if (window.location.hash) {
38+
const target = document.querySelector(window.location.hash);
39+
if (target) {
40+
setTimeout(() => {
41+
target.scrollIntoView({ behavior: 'smooth', block: 'start' });
42+
}, 100);
43+
}
44+
}
45+
46+
window.addEventListener('scroll', updateActiveLink, { passive: true });
47+
updateActiveLink();
48+
});

0 commit comments

Comments
 (0)