The-Clan-website / index.html
Barkmaster's picture
Upload index.html
c65a6db verified
Raw
History Blame Contribute Delete
44.8 kB
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<!--
══════════════════════════════════════════════════════
BROWSER TAB TITLE
Change the text below to set what appears in the tab.
══════════════════════════════════════════════════════
-->
<title>The Clan</title>
<!--
══════════════════════════════════════════════════════
FONTS
Current: Orbitron (headings) + Inter (body text)
To change:
1. Go to https://fonts.google.com
2. Pick a font → Get embed code → copy the <link>
3. Paste it here replacing the line below
4. Update --font-display / --font-body in :root
══════════════════════════════════════════════════════
-->
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link href="https://fonts.googleapis.com/css2?family=Orbitron:wght@700;900&family=Inter:wght@400;500;600&display=swap" rel="stylesheet" />
<!-- Supabase — DO NOT CHANGE -->
<script src="https://cdn.jsdelivr.net/npm/@supabase/supabase-js@2"></script>
<!-- QR Code generator -->
<script src="https://cdn.jsdelivr.net/npm/qrcodejs@1.0.0/qrcode.min.js"></script>
<style>
/*
══════════════════════════════════════════════════════
COLOUR PALETTE
Change the hex values here to restyle the whole site.
--col-bg Page background
--col-surface Cards and panel backgrounds
--col-border Thin border lines
--col-accent Main brand colour (buttons, glow)
--col-accent2 Lighter accent for hover states
--col-text Main readable text
--col-text-dim Muted label / caption text
Colour pickers:
https://coolors.co
https://htmlcolorcodes.com
══════════════════════════════════════════════════════
*/
:root {
--col-bg: #0a0a0f;
--col-surface: #16161f;
--col-border: #2a2a3a;
--col-accent: #7c5cfc; /* CHANGE THIS — your main brand colour */
--col-accent2: #a78bfa;
--col-text: #e8e8f0;
--col-text-dim: #6b6b8a;
--font-display: 'Orbitron', sans-serif;
--font-body: 'Inter', sans-serif;
--radius-sm: 8px;
--radius-lg: 20px;
--transition: 0.2s ease;
}
/*
══════════════════════════════════════════════════════
PAGE BACKGROUND
Default: solid dark colour from --col-bg above.
OPTION A — Background image:
body { background-image: url('background.jpg');
background-size: cover;
background-position: center;
background-attachment: fixed; }
Upload background.jpg to Hugging Face alongside index.html.
OPTION B — Gradient:
body { background: linear-gradient(135deg, #0a0a0f 0%, #1a0533 100%); }
OPTION C — Animated gradient:
body { background: linear-gradient(270deg, #0a0a0f, #1a0533, #0a1a2e);
background-size: 400% 400%;
animation: bgMove 12s ease infinite; }
@keyframes bgMove {
0%,100% { background-position: 0% 50%; }
50% { background-position: 100% 50%; }
}
══════════════════════════════════════════════════════
*/
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
body {
background: var(--col-bg);
color: var(--col-text);
font-family: var(--font-body);
font-size: 16px;
line-height: 1.6;
min-height: 100vh;
}
a { color: var(--col-accent); text-decoration: none; }
a:hover { color: var(--col-accent2); }
img { max-width: 100%; display: block; }
.container { width: 100%; max-width: 1100px; margin: 0 auto; padding: 0 24px; }
.btn {
display: inline-block; padding: 10px 24px;
border-radius: var(--radius-sm);
font-family: var(--font-body); font-size: 14px; font-weight: 600;
cursor: pointer; border: none;
transition: opacity var(--transition), transform var(--transition);
}
.btn:hover { opacity: 0.85; transform: translateY(-1px); }
.btn:active { transform: translateY(0); }
.btn-primary { background: var(--col-accent); color: #fff; }
.btn-outline { background: transparent; border: 1px solid var(--col-border); color: var(--col-text); }
.btn-outline:hover { border-color: var(--col-accent); color: var(--col-accent); }
.hidden { display: none !important; }
/*
══════════════════════════════════════════════════════
ADDING EXTRA TEXT ANYWHERE ON THE PAGE
Use these classes on any <p> tag:
<p>Normal paragraph text</p>
<p class="text-dim">Smaller muted text</p>
<p class="text-accent">Text in your brand colour</p>
<p><strong>Bold text</strong></p>
DIVIDER LINE between sections:
<hr class="divider" />
══════════════════════════════════════════════════════
*/
.text-dim { color: var(--col-text-dim); font-size: 14px; }
.text-accent { color: var(--col-accent); font-weight: 600; }
.divider { border: none; border-top: 1px solid var(--col-border); margin: 40px 0; }
/* Toast notification — do not remove */
#toast {
position: fixed; bottom: 24px; right: 24px;
background: var(--col-surface); border: 1px solid var(--col-border);
border-left: 3px solid var(--col-accent); color: var(--col-text);
padding: 12px 20px; border-radius: var(--radius-sm); font-size: 14px;
z-index: 9999; opacity: 0; transform: translateY(10px);
transition: all 0.3s ease; pointer-events: none;
}
#toast.show { opacity: 1; transform: translateY(0); }
#toast.error { border-left-color: #f87171; }
/* NAV */
header {
position: sticky; top: 0; z-index: 100;
background: rgba(10,10,15,0.90); backdrop-filter: blur(12px);
border-bottom: 1px solid var(--col-border);
}
.nav-inner { display: flex; align-items: center; justify-content: space-between; height: 64px; }
.nav-logo {
font-family: var(--font-display); font-size: 18px; font-weight: 900;
color: var(--col-accent); letter-spacing: 3px;
/*
TO USE A LOGO IMAGE:
Replace <div class="nav-logo">THE CLAN</div> in the HTML with:
<div class="nav-logo"><img src="logo.png" alt="The Clan" style="height:36px" /></div>
Upload logo.png to Hugging Face.
*/
}
.nav-links { display: flex; align-items: center; gap: 32px; list-style: none; }
.nav-links a { color: var(--col-text-dim); font-size: 14px; font-weight: 500; letter-spacing: 1px; transition: color var(--transition); }
.nav-links a:hover { color: var(--col-text); }
#nav-auth-guest { display: flex; gap: 10px; align-items: center; }
#nav-auth-user { display: flex; gap: 12px; align-items: center; font-size: 14px; }
#nav-username { color: var(--col-accent2); font-weight: 600; }
/* HERO */
.hero {
padding: 100px 0 80px; text-align: center;
/*
══════════════════════════════════════════════════════
HERO BACKGROUND
Default is a subtle purple glow gradient.
TO USE YOUR OWN BANNER IMAGE:
Replace everything below with:
background-image: url('hero-banner.jpg');
background-size: cover;
background-position: center;
Upload hero-banner.jpg to Hugging Face.
══════════════════════════════════════════════════════
*/
background: radial-gradient(ellipse 80% 50% at 50% 0%, rgba(124,92,252,0.15) 0%, transparent 70%);
}
.hero-eyebrow {
display: inline-block; font-size: 11px; font-weight: 600;
letter-spacing: 4px; text-transform: uppercase;
color: var(--col-accent); margin-bottom: 20px;
}
.hero h1 {
font-family: var(--font-display); font-size: clamp(36px, 6vw, 72px);
font-weight: 900; line-height: 1.1; letter-spacing: 2px; margin-bottom: 20px;
}
.hero-sub { font-size: 18px; color: var(--col-text-dim); max-width: 540px; margin: 0 auto 36px; }
.hero-cta { display: flex; gap: 14px; justify-content: center; flex-wrap: wrap; }
/* Hero photo (optional) */
#hero-photo { margin: 40px auto 0; max-width: 700px; border-radius: var(--radius-lg); overflow: hidden; border: 1px solid var(--col-border); }
/* Stats bar */
.stats-bar { border-top: 1px solid var(--col-border); border-bottom: 1px solid var(--col-border); padding: 28px 0; }
.stats-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); gap: 16px; text-align: center; }
.stat-value { font-family: var(--font-display); font-size: 28px; font-weight: 700; color: var(--col-accent); }
.stat-label { font-size: 12px; letter-spacing: 2px; text-transform: uppercase; color: var(--col-text-dim); margin-top: 4px; }
/* Sections */
.section { padding: 80px 0; }
.section-label { font-size: 11px; font-weight: 600; letter-spacing: 4px; text-transform: uppercase; color: var(--col-accent); margin-bottom: 12px; }
.section h2 { font-family: var(--font-display); font-size: clamp(24px, 3vw, 36px); font-weight: 700; margin-bottom: 16px; }
.section-intro { color: var(--col-text-dim); max-width: 560px; margin-bottom: 48px; }
/* Feature cards */
.features-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: 20px; }
.feature-card { background: var(--col-surface); border: 1px solid var(--col-border); border-radius: var(--radius-sm); padding: 28px; transition: border-color var(--transition); }
.feature-card:hover { border-color: var(--col-accent); }
.feature-icon { font-size: 28px; margin-bottom: 14px; }
.feature-card h3 { font-size: 16px; font-weight: 600; margin-bottom: 8px; }
.feature-card p { font-size: 14px; color: var(--col-text-dim); line-height: 1.6; }
/*
══════════════════════════════════════════════════════
ADDING PHOTOS / IMAGES
1. Upload your image to Hugging Face (Files → Add file)
2. Use one of these HTML patterns where you want it:
Full-width image:
<img src="photo.jpg" alt="description" class="page-image" />
Rounded image:
<img src="photo.jpg" alt="description" class="page-image rounded" />
Image with caption:
<div class="image-card">
<img src="photo.jpg" alt="description" />
<p class="image-caption">Your caption here</p>
</div>
Two images side by side:
<div class="image-row">
<img src="photo1.jpg" alt="First" class="page-image rounded" />
<img src="photo2.jpg" alt="Second" class="page-image rounded" />
</div>
══════════════════════════════════════════════════════
*/
.page-image { width: 100%; max-width: 700px; margin: 20px auto; display: block; }
.page-image.rounded { border-radius: var(--radius-lg); }
.image-card { background: var(--col-surface); border: 1px solid var(--col-border); border-radius: var(--radius-sm); overflow: hidden; margin: 20px 0; }
.image-card img { width: 100%; display: block; }
.image-caption { padding: 10px 16px; font-size: 13px; color: var(--col-text-dim); }
.image-row { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; margin: 20px 0; }
@media (max-width: 600px) { .image-row { grid-template-columns: 1fr; } }
/* Members */
.members-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(180px, 1fr)); gap: 16px; }
.member-card { background: var(--col-surface); border: 1px solid var(--col-border); border-radius: var(--radius-sm); padding: 20px; text-align: center; transition: border-color var(--transition); }
.member-card:hover { border-color: var(--col-accent); }
.member-avatar { width: 56px; height: 56px; border-radius: 50%; background: var(--col-border); margin: 0 auto 12px; display: flex; align-items: center; justify-content: center; font-size: 22px; }
.member-name { font-weight: 600; font-size: 14px; margin-bottom: 4px; }
.member-role { font-size: 12px; color: var(--col-accent); letter-spacing: 1px; text-transform: uppercase; }
#members-loading { color: var(--col-text-dim); font-size: 14px; padding: 20px 0; }
/* Dashboard */
#dashboard { background: var(--col-surface); border: 1px solid var(--col-border); border-radius: var(--radius-sm); padding: 32px; margin-bottom: 40px; }
.dashboard-header { display: flex; align-items: center; justify-content: space-between; margin-bottom: 28px; flex-wrap: wrap; gap: 12px; }
.dashboard-header h2 { font-family: var(--font-display); font-size: 18px; font-weight: 700; }
.dashboard-stats { display: grid; grid-template-columns: repeat(auto-fit, minmax(130px, 1fr)); gap: 16px; }
.dash-stat { background: var(--col-bg); border: 1px solid var(--col-border); border-radius: var(--radius-sm); padding: 16px; text-align: center; }
.dash-stat-value { font-family: var(--font-display); font-size: 22px; font-weight: 700; color: var(--col-accent); }
.dash-stat-label { font-size: 11px; letter-spacing: 2px; text-transform: uppercase; color: var(--col-text-dim); margin-top: 4px; }
/*
══════════════════════════════════════════════════════
AUTH MODAL (Sign In / Sign Up box)
The box is now solid fill with rounded corners and a glow.
TO CHANGE BOX COLOUR:
Find .modal below, change background: #1a1825 to any hex.
TO CHANGE ROUNDNESS:
Change border-radius: var(--radius-lg) — 0px = sharp, 30px = very round.
TO CHANGE GLOW COLOUR:
Change the rgba values in box-shadow to match your brand colour.
TO CHANGE BOX SIZE:
Change max-width: 440px in .modal
══════════════════════════════════════════════════════
*/
.modal-overlay {
position: fixed; inset: 0;
background: rgba(0,0,0,0.78);
backdrop-filter: blur(6px);
z-index: 200;
display: flex; align-items: center; justify-content: center;
padding: 20px;
}
.modal {
background: #1a1825; /* solid box fill — CHANGE this */
border: 1px solid var(--col-accent); /* border uses accent colour */
border-radius: var(--radius-lg); /* 20px rounded corners */
box-shadow:
0 0 0 1px rgba(124,92,252,0.2), /* outer ring */
0 8px 40px rgba(0,0,0,0.65), /* depth shadow */
0 0 60px rgba(124,92,252,0.12); /* colour glow */
padding: 40px;
width: 100%; max-width: 440px;
}
.modal-header { display: flex; align-items: flex-start; justify-content: space-between; margin-bottom: 6px; }
.modal h2 { font-family: var(--font-display); font-size: 20px; font-weight: 700; }
.modal-sub { font-size: 13px; color: var(--col-text-dim); margin-bottom: 28px; }
.modal-close { background: none; border: none; color: var(--col-text-dim); font-size: 22px; cursor: pointer; line-height: 1; padding: 0; flex-shrink: 0; }
.modal-close:hover { color: var(--col-text); }
.form-group { margin-bottom: 16px; }
.form-group label { display: block; font-size: 12px; font-weight: 600; letter-spacing: 1px; text-transform: uppercase; color: var(--col-text-dim); margin-bottom: 6px; }
.form-group input {
width: 100%; background: rgba(255,255,255,0.05);
border: 1px solid var(--col-border); border-radius: var(--radius-sm);
color: var(--col-text); font-family: var(--font-body); font-size: 14px;
padding: 11px 14px; outline: none;
transition: border-color var(--transition), box-shadow var(--transition);
}
.form-group input:focus { border-color: var(--col-accent); box-shadow: 0 0 0 3px rgba(124,92,252,0.15); }
.form-actions { margin-top: 24px; display: flex; flex-direction: column; gap: 10px; }
.form-actions .btn { width: 100%; text-align: center; padding: 12px; font-size: 15px; }
.modal-toggle { text-align: center; margin-top: 18px; font-size: 13px; color: var(--col-text-dim); }
.modal-toggle a { color: var(--col-accent); }
/*
══════════════════════════════════════════════════════
QR CODES
Auto-generated from the data-url attribute.
No image needed — they appear automatically on page load.
TO CHANGE A QR CODE URL:
Find id="qr-url-1" in HTML and change data-url="..."
TO ADD ANOTHER QR CODE:
Copy a <div class="qr-item"> block, give it a new id
e.g. id="qr-url-3", and set a new data-url.
══════════════════════════════════════════════════════
*/
.qr-row { display: flex; gap: 36px; flex-wrap: wrap; margin-bottom: 32px; }
.qr-item { text-align: center; }
.qr-box { background: #fff; border-radius: var(--radius-sm); padding: 12px; display: inline-block; margin-bottom: 10px; }
.qr-title { font-weight: 600; font-size: 14px; margin-bottom: 2px; }
.qr-label { font-size: 12px; color: var(--col-text-dim); }
/* Footer */
footer { border-top: 1px solid var(--col-border); padding: 32px 0; }
.footer-inner { display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: 16px; }
.footer-copy { font-size: 13px; color: var(--col-text-dim); }
.footer-links { display: flex; gap: 20px; list-style: none; }
.footer-links a { font-size: 13px; color: var(--col-text-dim); transition: color var(--transition); }
.footer-links a:hover { color: var(--col-text); }
@media (max-width: 600px) {
.nav-links { display: none; }
.hero { padding: 60px 0 50px; }
.modal { padding: 28px 20px; }
}
</style>
</head>
<body>
<!-- Toast notification — do not remove -->
<div id="toast"></div>
<!--
══════════════════════════════════════════════════════
AUTH MODAL
Text you can change here:
- placeholder="you@example.com" on the email input
- placeholder="••••••••" on the password input
All other text (titles, button labels) is set in
updateModalUI() in the JavaScript section below.
══════════════════════════════════════════════════════
-->
<div class="modal-overlay hidden" id="auth-modal">
<div class="modal">
<div class="modal-header">
<div>
<h2 id="modal-title">Sign In</h2>
<p class="modal-sub" id="modal-sub">Welcome back, soldier.</p>
</div>
<button class="modal-close" onclick="closeModal()">&#x2715;</button>
</div>
<div class="form-group">
<label for="auth-email">Email</label>
<!-- CHANGE placeholder text -->
<input type="email" id="auth-email" placeholder="you@example.com" />
</div>
<div class="form-group">
<label for="auth-password">Password</label>
<input type="password" id="auth-password" placeholder="&bull;&bull;&bull;&bull;&bull;&bull;&bull;&bull;" />
</div>
<!--
TO ADD A USERNAME FIELD: remove the comment tags around this block
<div class="form-group">
<label for="auth-username">Clan Tag / Username</label>
<input type="text" id="auth-username" placeholder="YourClanTag" />
</div>
-->
<div class="form-actions">
<button class="btn btn-primary" id="modal-submit-btn" onclick="handleAuth()">Sign In</button>
</div>
<div class="modal-toggle">
<span id="modal-toggle-text">Don't have an account?</span>
<a href="#" onclick="toggleMode(); return false;" id="modal-toggle-link">Sign Up</a>
</div>
</div>
</div>
<!--
══════════════════════════════════════════════════════
NAVIGATION BAR
Change:
"THE CLAN" → your clan name (nav-logo div)
Link text → text inside each <a> tag
Link targets → href="#section-id" values
Button text → "Sign In" and "Join" button text
To add a nav link: copy a <li><a> line and paste it
inside the <ul class="nav-links"> block.
══════════════════════════════════════════════════════
-->
<header>
<div class="container">
<nav class="nav-inner">
<!-- CHANGE: clan name or swap for a logo image -->
<div class="nav-logo">THE CLAN</div>
<ul class="nav-links">
<!-- CHANGE: link labels and href targets -->
<li><a href="#about">About</a></li>
<li><a href="#media">Media</a></li>
<li><a href="#members">Members</a></li>
<li><a href="#links">Links</a></li>
<li><a href="#dashboard-section">Dashboard</a></li>
<!-- TO ADD A LINK: copy a line above and paste it here -->
</ul>
<!-- do not change IDs below -->
<div id="nav-auth-guest">
<!-- CHANGE button labels -->
<button class="btn btn-outline" onclick="openModal('login')">Sign In</button>
<button class="btn btn-primary" onclick="openModal('signup')">Join</button>
</div>
<div id="nav-auth-user" class="hidden">
<span>&#x1F47E; <span id="nav-username"></span></span>
<button class="btn btn-outline" onclick="signOut()">Sign Out</button>
</div>
</nav>
</div>
</header>
<!--
══════════════════════════════════════════════════════
HERO SECTION (big banner at the top)
Text to change:
1. Small eyebrow label → "Est. 2026 · Competitive Gaming"
2. Big headline → "We Don't Play. We Dominate."
Use <br/> to force a new line.
3. Subheading paragraph → inside <p class="hero-sub">
4. Button labels → "Join The Clan" and "Meet The Team"
TO SHOW THE OPTIONAL PHOTO below the buttons:
1. Upload your image to Hugging Face
2. Remove style="display:none" from the #hero-photo div
3. Change src="team-photo.jpg" to your filename
══════════════════════════════════════════════════════
-->
<section class="hero">
<div class="container">
<!-- CHANGE: small label above headline -->
<span class="hero-eyebrow">Est. 2026 &nbsp;&middot;&nbsp; Competitive Gaming</span>
<!-- CHANGE: main headline — use <br/> for line breaks -->
<h1>We Don't Play.<br/>We Dominate.</h1>
<!-- CHANGE: subheading paragraph -->
<p class="hero-sub">
The Clan is a competitive FPS team built on precision,
communication, and relentless improvement.
</p>
<div class="hero-cta">
<!-- CHANGE: button labels -->
<button class="btn btn-primary" onclick="openModal('signup')">Join The Clan</button>
<a href="#members" class="btn btn-outline">Meet The Team</a>
</div>
<!--
OPTIONAL HERO IMAGE
Remove style="display:none" to show.
Change src to your uploaded image filename.
-->
<div id="hero-photo" style="display:none">
<img src="team-photo.jpg" alt="The Clan team photo" />
</div>
</div>
</section>
<!--
STATS BAR
Change: the text inside each .stat-label div
Numbers are pulled live from Supabase — see fetchPublicStats() in JS
-->
<section class="stats-bar">
<div class="container">
<div class="stats-grid">
<div class="stat-item">
<div class="stat-value" id="stat-members">&#x2014;</div>
<div class="stat-label">Members</div> <!-- CHANGE label -->
</div>
<div class="stat-item">
<div class="stat-value" id="stat-kills">&#x2014;</div>
<div class="stat-label">Total Kills</div> <!-- CHANGE label -->
</div>
<div class="stat-item">
<div class="stat-value" id="stat-wins">&#x2014;</div>
<div class="stat-label">Wins</div> <!-- CHANGE label -->
</div>
<div class="stat-item">
<div class="stat-value" id="stat-top-rank">&#x2014;</div>
<div class="stat-label">Top Rank Pts</div> <!-- CHANGE label -->
</div>
</div>
</div>
</section>
<!--
══════════════════════════════════════════════════════
ABOUT / FEATURES SECTION
Text to change:
- Small label → "Who We Are"
- Section h2 → "Built Different. Playing Harder."
- Intro <p> → paragraph inside section-intro
- Each card: → icon emoji, <h3> title, <p> text
TO ADD A CARD: copy one <div class="feature-card"> block
and paste it inside the .features-grid div.
TO ADD EXTRA TEXT lines below the cards:
<hr class="divider" />
<p class="text-accent">Your highlighted text here.</p>
<p class="text-dim" style="margin-top:8px">A muted line below it.</p>
══════════════════════════════════════════════════════
-->
<section class="section" id="about">
<div class="container">
<p class="section-label">Who We Are</p> <!-- CHANGE label -->
<h2>Built Different.<br/>Playing Harder.</h2> <!-- CHANGE heading -->
<p class="section-intro">
We're a team of dedicated players who push each other to be better
every session. No toxicity, no excuses &mdash; just results.
<!-- CHANGE this text -->
</p>
<div class="features-grid">
<!-- CARD 1 — change emoji, title, description -->
<div class="feature-card">
<div class="feature-icon">&#x1F3AF;</div>
<h3>Competitive Focus</h3>
<p>We analyse every match, review VODs, and constantly work on improving our aim, positioning, and strategy.</p>
</div>
<!-- CARD 2 — change emoji, title, description -->
<div class="feature-card">
<div class="feature-icon">&#x1F91D;</div>
<h3>Tight Comms</h3>
<p>Clear, calm callouts win matches. We train communication as much as mechanics.</p>
</div>
<!-- CARD 3 — change emoji, title, description -->
<div class="feature-card">
<div class="feature-icon">&#x1F4CA;</div>
<h3>Stat Tracking</h3>
<p>Every kill, death, and match result is tracked in real time via our live stats dashboard.</p>
</div>
<!-- TO ADD A CARD: copy a block above and paste it here -->
</div>
<!-- Extra text lines — change or delete these -->
<hr class="divider" />
<p class="text-accent">Want to join? Hit the Join button at the top.</p>
<p class="text-dim" style="margin-top:8px">Open to all skill levels. Applications reviewed weekly.</p>
</div>
</section>
<!--
══════════════════════════════════════════════════════
MEDIA / PHOTOS SECTION
This section is hidden by default.
TO SHOW IT: remove style="display:none" from the <section> tag.
TO ADD YOUR OWN PHOTOS:
1. Upload images to Hugging Face (Files tab → Add file → Upload files)
Supported: .jpg .jpeg .png .gif .webp
2. Replace src="screenshot1.jpg" etc with your actual filenames
3. Change the alt="..." text to describe your image
IMAGE LAYOUT OPTIONS:
Full-width: <img src="file.jpg" class="page-image" />
Rounded corners: <img src="file.jpg" class="page-image rounded" />
With caption: <div class="image-card"><img src="file.jpg" /><p class="image-caption">Caption</p></div>
Side by side: <div class="image-row"><img ... /><img ... /></div>
══════════════════════════════════════════════════════
-->
<section class="section" id="media" style="padding-top:0; display:none">
<!-- Remove style="display:none" above to show this section -->
<div class="container">
<p class="section-label">Media</p> <!-- CHANGE label -->
<h2>Highlights &amp; Screenshots</h2> <!-- CHANGE heading -->
<p class="section-intro" style="margin-bottom:32px">
Our best moments captured. <!-- CHANGE text -->
</p>
<!-- FULL WIDTH ROUNDED IMAGE — change src -->
<img src="screenshot1.jpg" alt="Match screenshot" class="page-image rounded" />
<!-- TWO IMAGES SIDE BY SIDE — change both srcs -->
<div class="image-row">
<img src="photo1.jpg" alt="Team photo" class="page-image rounded" />
<img src="photo2.jpg" alt="Gameplay" class="page-image rounded" />
</div>
<!-- IMAGE WITH CAPTION — change src and caption text -->
<div class="image-card">
<img src="banner.jpg" alt="Clan banner" />
<p class="image-caption">Season 1 Champions &mdash; The Clan</p> <!-- CHANGE caption -->
</div>
<!-- ADD MORE IMAGES: copy any pattern above and paste it here -->
</div>
</section>
<!--
MEMBERS SECTION
Cards are pulled from Supabase "profiles" table.
Change label, heading, and intro text below.
Placeholder cards show until the DB table is set up.
-->
<section class="section" id="members" style="padding-top:0">
<div class="container">
<p class="section-label">The Roster</p> <!-- CHANGE label -->
<h2>Meet The Team</h2> <!-- CHANGE heading -->
<p class="section-intro" style="margin-bottom:32px">
The people behind the crosshairs. <!-- CHANGE text -->
</p>
<div id="members-loading">Loading members...</div>
<div class="members-grid hidden" id="members-grid"></div>
</div>
</section>
<!--
══════════════════════════════════════════════════════
QR CODES & LINKS SECTION
Each QR code is auto-generated when the page loads.
TO CHANGE A QR CODE:
Find the qr-box div with the id you want to edit.
Change data-url="..." to your actual URL.
Change the title and label text below it.
TO ADD ANOTHER QR CODE:
Copy one <div class="qr-item"> block,
give the inner div a new id (e.g. id="qr-url-3"),
set data-url="https://your-link-here.com"
and update the title and label.
TO ADD MORE QUICK LINK BUTTONS:
Copy one of the <a class="btn btn-outline"> lines
and change the href and label text.
══════════════════════════════════════════════════════
-->
<section class="section" id="links" style="padding-top:0">
<div class="container">
<p class="section-label">Connect</p> <!-- CHANGE label -->
<h2>Links &amp; QR Codes</h2> <!-- CHANGE heading -->
<p class="section-intro" style="margin-bottom:32px">
Scan to join our community or find us online. <!-- CHANGE text -->
</p>
<div class="qr-row">
<!-- QR CODE 1 — change data-url, title, label -->
<div class="qr-item">
<div class="qr-box" id="qr-url-1" data-url="https://discord.gg/example"></div>
<p class="qr-title">Discord Server</p> <!-- CHANGE -->
<p class="qr-label">Scan to join</p> <!-- CHANGE -->
</div>
<!-- QR CODE 2 — change data-url, title, label -->
<div class="qr-item">
<div class="qr-box" id="qr-url-2" data-url="https://youtube.com/@example"></div>
<p class="qr-title">YouTube Channel</p> <!-- CHANGE -->
<p class="qr-label">Watch our highlights</p> <!-- CHANGE -->
</div>
<!-- TO ADD A QR CODE: copy a qr-item block here with a new id -->
</div>
<hr class="divider" />
<p style="margin-bottom:16px; font-weight:600;">Quick Links</p>
<div style="display:flex; gap:12px; flex-wrap:wrap;">
<!-- CHANGE: hrefs and button labels -->
<a href="https://discord.gg/example" class="btn btn-outline" target="_blank">&#x1F4AC; Discord</a>
<a href="https://youtube.com/@example" class="btn btn-outline" target="_blank">&#x25B6; YouTube</a>
<a href="https://twitter.com/example" class="btn btn-outline" target="_blank">&#x1D54F; Twitter</a>
<!-- TO ADD A BUTTON: copy a line above, change href and label -->
</div>
</div>
</section>
<!--
PERSONAL DASHBOARD — visible only when signed in
Change: .dash-stat-label text inside each stat block
To add a stat: copy a .dash-stat block with a new id,
then add a matching line in loadMyStats() in JS.
-->
<section class="section" id="dashboard-section" style="padding-top:0">
<div class="container">
<div id="dashboard" class="hidden">
<div class="dashboard-header">
<h2>Your Stats</h2> <!-- CHANGE heading -->
<button class="btn btn-outline" style="font-size:12px" onclick="loadMyStats()">&#x21BB; Refresh</button>
</div>
<div class="dashboard-stats">
<div class="dash-stat">
<div class="dash-stat-value" id="my-kills">&#x2014;</div>
<div class="dash-stat-label">Kills</div> <!-- CHANGE -->
</div>
<div class="dash-stat">
<div class="dash-stat-value" id="my-deaths">&#x2014;</div>
<div class="dash-stat-label">Deaths</div> <!-- CHANGE -->
</div>
<div class="dash-stat">
<div class="dash-stat-value" id="my-rank">&#x2014;</div>
<div class="dash-stat-label">Rank Pts</div> <!-- CHANGE -->
</div>
<div class="dash-stat">
<div class="dash-stat-value" id="my-gold">&#x2014;</div>
<div class="dash-stat-label">Gold</div> <!-- CHANGE -->
</div>
<div class="dash-stat">
<div class="dash-stat-value" id="my-wins">&#x2014;</div>
<div class="dash-stat-label">Wins</div> <!-- CHANGE -->
</div>
<div class="dash-stat">
<div class="dash-stat-value" id="my-headshots">&#x2014;</div>
<div class="dash-stat-label">Headshots</div> <!-- CHANGE -->
</div>
<!--
TO ADD A STAT: paste this block and give it a new id:
<div class="dash-stat">
<div class="dash-stat-value" id="my-NEWSTAT">&#x2014;</div>
<div class="dash-stat-label">YOUR LABEL HERE</div>
</div>
Then add this line in loadMyStats() in the JS:
document.getElementById('my-NEWSTAT').textContent = (data.column_name || 0).toLocaleString();
-->
</div>
</div>
<div id="dashboard-prompt" style="text-align:center; padding:48px 0; color:var(--col-text-dim);">
<p style="font-size:15px; margin-bottom:16px;">Sign in to view your personal stats.</p>
<button class="btn btn-primary" onclick="openModal('login')">Sign In</button>
</div>
</div>
</section>
<!--
FOOTER
Change: copyright text, link labels, hrefs
To add a link: copy a <li><a> line inside .footer-links
-->
<footer>
<div class="container">
<div class="footer-inner">
<p class="footer-copy">&copy; 2026 The Clan. All rights reserved.</p> <!-- CHANGE -->
<ul class="footer-links">
<!-- CHANGE: labels and hrefs -->
<li><a href="https://discord.gg/example" target="_blank">Discord</a></li>
<li><a href="https://youtube.com/@example" target="_blank">YouTube</a></li>
<li><a href="#">Privacy</a></li>
<!-- TO ADD A LINK: copy a <li> line here -->
</ul>
</div>
</div>
</footer>
<script>
// DO NOT CHANGE THESE — Supabase config for The Clan project
const SUPABASE_URL = 'https://tunpuyutygievrpjnxdm.supabase.co';
const SUPABASE_KEY = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6InR1bnB1eXV0eWdpZXZycGpueGRtIiwicm9sZSI6ImFub24iLCJpYXQiOjE3ODM3ODM0NjEsImV4cCI6MjA5OTM1OTQ2MX0.93boIYL_bvGwVb_nLE8gtU37DXcsMkOqXtLp4SSLEgM';
const { createClient } = supabase;
const db = createClient(SUPABASE_URL, SUPABASE_KEY);
let currentUser = null;
let authMode = 'login';
function showToast(msg, isError = false) {
const t = document.getElementById('toast');
t.textContent = msg;
t.className = isError ? 'error show' : 'show';
setTimeout(() => t.className = '', 3000);
}
function openModal(mode) {
authMode = mode;
document.getElementById('auth-modal').classList.remove('hidden');
updateModalUI();
setTimeout(() => document.getElementById('auth-email').focus(), 50);
}
function closeModal() {
document.getElementById('auth-modal').classList.add('hidden');
document.getElementById('auth-email').value = '';
document.getElementById('auth-password').value = '';
}
function toggleMode() {
authMode = authMode === 'login' ? 'signup' : 'login';
updateModalUI();
}
/*
MODAL TEXT — change the strings here to update what the modal says.
Each string has a Sign In version and a Sign Up version.
*/
function updateModalUI() {
const isLogin = authMode === 'login';
document.getElementById('modal-title').textContent = isLogin ? 'Sign In' : 'Create Account';
document.getElementById('modal-sub').textContent = isLogin ? 'Welcome back, soldier.' : 'Join the clan today.';
document.getElementById('modal-submit-btn').textContent = isLogin ? 'Sign In' : 'Sign Up';
document.getElementById('modal-toggle-text').textContent = isLogin ? "Don't have an account?" : 'Already a member?';
document.getElementById('modal-toggle-link').textContent = isLogin ? 'Sign Up' : 'Sign In';
}
async function handleAuth() {
const email = document.getElementById('auth-email').value.trim();
const password = document.getElementById('auth-password').value;
if (!email || !password) { showToast('Please fill in all fields.', true); return; }
const btn = document.getElementById('modal-submit-btn');
btn.textContent = 'Please wait...'; btn.disabled = true;
try {
const result = authMode === 'login'
? await db.auth.signInWithPassword({ email, password })
: await db.auth.signUp({ email, password });
if (result.error) throw result.error;
showToast(authMode === 'login' ? 'Signed in!' : 'Account created! Check your email.');
closeModal();
if (result.data.user) onSignIn(result.data.user);
} catch (err) {
showToast(err.message, true);
} finally {
btn.textContent = authMode === 'login' ? 'Sign In' : 'Sign Up';
btn.disabled = false;
}
}
document.addEventListener('keydown', e => {
if (e.key === 'Enter' && !document.getElementById('auth-modal').classList.contains('hidden')) handleAuth();
});
document.getElementById('auth-modal').addEventListener('click', e => {
if (e.target === document.getElementById('auth-modal')) closeModal();
});
async function signOut() {
await db.auth.signOut();
currentUser = null; onSignOut();
showToast('Signed out.');
}
function onSignIn(user) {
currentUser = user;
document.getElementById('nav-username').textContent = user.email.split('@')[0];
document.getElementById('nav-auth-guest').classList.add('hidden');
document.getElementById('nav-auth-user').classList.remove('hidden');
document.getElementById('dashboard').classList.remove('hidden');
document.getElementById('dashboard-prompt').classList.add('hidden');
loadMyStats();
}
function onSignOut() {
document.getElementById('nav-auth-guest').classList.remove('hidden');
document.getElementById('nav-auth-user').classList.add('hidden');
document.getElementById('dashboard').classList.add('hidden');
document.getElementById('dashboard-prompt').classList.remove('hidden');
}
async function loadMyStats() {
if (!currentUser) return;
const { data, error } = await db.from('player_stats').select('*').eq('id', currentUser.id).single();
if (error || !data) {
['kills','deaths','rank','gold','wins','headshots'].forEach(k => {
const el = document.getElementById('my-' + k); if (el) el.textContent = '0';
});
return;
}
document.getElementById('my-kills').textContent = (data.kills || 0).toLocaleString();
document.getElementById('my-deaths').textContent = (data.deaths || 0).toLocaleString();
document.getElementById('my-rank').textContent = (data.rank_points || 0).toLocaleString();
document.getElementById('my-gold').textContent = (data.gold || 0).toLocaleString();
document.getElementById('my-wins').textContent = (data.wins || 0).toLocaleString();
document.getElementById('my-headshots').textContent = (data.headshots || 0).toLocaleString();
}
async function fetchPublicStats() {
const { data, error } = await db.from('player_stats').select('kills, wins, rank_points');
if (error || !data) return;
const total = k => data.reduce((a, r) => a + (r[k] || 0), 0);
const max = k => Math.max(0, ...data.map(r => r[k] || 0));
document.getElementById('stat-members').textContent = data.length.toLocaleString();
document.getElementById('stat-kills').textContent = total('kills').toLocaleString();
document.getElementById('stat-wins').textContent = total('wins').toLocaleString();
document.getElementById('stat-top-rank').textContent = max('rank_points').toLocaleString();
}
async function fetchMembers() {
const grid = document.getElementById('members-grid');
const load = document.getElementById('members-loading');
const { data, error } = await db.from('profiles').select('username, role, avatar_emoji').limit(12);
load.classList.add('hidden'); grid.classList.remove('hidden');
const members = (error || !data || data.length === 0)
? [
{ username: 'ShadowSniper99', role: 'Captain', avatar_emoji: '\uD83C\uDFAF' },
{ username: 'NightHawkX', role: 'Fragger', avatar_emoji: '\uD83D\uDC80' },
{ username: 'BlazeFury', role: 'Support', avatar_emoji: '\uD83D\uDEE1\uFE0F' },
]
: data;
grid.innerHTML = members.map(m => `
<div class="member-card">
<div class="member-avatar">${m.avatar_emoji || '\uD83D\uDC7E'}</div>
<div class="member-name">${m.username || 'Unknown'}</div>
<div class="member-role">${m.role || 'Member'}</div>
</div>`).join('');
}
// Auto-generate QR codes from data-url attributes
function generateQRCodes() {
if (typeof QRCode === 'undefined') return;
document.querySelectorAll('.qr-box[data-url]').forEach(el => {
new QRCode(el, { text: el.getAttribute('data-url'), width: 128, height: 128, colorDark: '#000', colorLight: '#fff' });
});
}
(async () => {
const { data: { session } } = await db.auth.getSession();
if (session?.user) onSignIn(session.user);
db.auth.onAuthStateChange((_e, s) => { if (s?.user) onSignIn(s.user); else onSignOut(); });
fetchPublicStats();
fetchMembers();
generateQRCodes();
})();
</script>
</body>
</html>