This commit is contained in:
callum
2026-03-10 17:05:22 +00:00
commit 2c456a1279
6 changed files with 259 additions and 0 deletions

2
.dockerignore Normal file
View File

@@ -0,0 +1,2 @@
Dockerfile
.dockerignore

3
Dockerfile Normal file
View File

@@ -0,0 +1,3 @@
FROM nginx:alpine
COPY . /usr/share/nginx/html
EXPOSE 80

43
index.html Normal file
View File

@@ -0,0 +1,43 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="theme-color" content="#0f0f0f" />
<title>Fwdme.dev</title>
<link rel="stylesheet" href="style.css" />
</head>
<body>
<header>
<nav>
<a href="/" class="logo">Fwdme.dev</a>
</nav>
</header>
<main>
<section class="hero">
<h1>A home for services.</h1>
<p>A place for me where i host things for myself and others</p>
</section>
<section class="services">
<h2 class="section-title">Services</h2>
<ul class="service-grid">
</ul>
</section>
<section class="services">
<h2 class="section-title">Delegated Services</h2>
<p class="section-note">These services are hosted for others. I do not operate them directly and take no responsibility for their content or availability.</p>
<ul class="service-grid">
</ul>
</section>
</main>
<footer>
<p>&copy; 2026 Fwdme.dev &middot; <a href="/privacy.txt">Privacy Policy</a></p>
</footer>
<script type="module" src="main.js"></script>
</body>
</html>

11
main.js Normal file
View File

@@ -0,0 +1,11 @@
// Fade in elements as they scroll into view
const observer = new IntersectionObserver((entries) => {
for (const entry of entries) {
if (entry.isIntersecting) {
entry.target.classList.add('visible');
observer.unobserve(entry.target);
}
}
}, { threshold: 0.1 });
document.querySelectorAll('section').forEach((el) => observer.observe(el));

43
privacy.txt Normal file
View File

@@ -0,0 +1,43 @@
Privacy Policy - Fwdme.dev
This is Fwdme.dev ("we", "our", "us"). We're committed to protecting and respecting your privacy across all services hosted under this domain.
If you have questions about your personal data, contact us at admin@fwdme.dev.
What information we collect:
- Your IP address when you browse any part of the service.
- Technical metadata such as browser type and which pages you access.
This metadata is used solely for debugging and is deleted after no more than 48 hours.
How your information is used:
- IP addresses and technical metadata are collected to keep the service running and to detect abuse.
- We do not sell, share, or use your data for advertising or marketing purposes.
Keeping your data secure:
We take reasonable measures to protect any information we hold from unauthorized access or disclosure.
Your rights:
- You have the right to access or obtain a copy of any personal data we hold about you.
- You have the right to request correction of inaccurate data.
- You have the right to request erasure of your personal data.
To exercise any of these rights, contact us at admin@fwdme.dev.
Delegated services:
Some services linked from this domain are hosted for others and are not directly operated by Fwdme.dev. We take no responsibility for the content, availability, or privacy practices of these delegated services. Please refer to the respective operator's privacy policy for those services.
Changes to this policy:
We may update this policy at any time. Continued use of the service constitutes acceptance of the current policy.

157
style.css Normal file
View File

@@ -0,0 +1,157 @@
*, *::before, *::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
:root {
--color-bg: #0f0f0f;
--color-text: #e8e8e8;
--color-muted: #888;
--color-accent: #6ee7b7;
--font-sans: system-ui, sans-serif;
}
@media (prefers-color-scheme: light) {
:root {
--color-bg: #fafafa;
--color-text: #111;
--color-muted: #666;
}
}
html {
font-family: var(--font-sans);
background: var(--color-bg);
color: var(--color-text);
line-height: 1.6;
}
body {
min-height: 100dvh;
display: flex;
flex-direction: column;
}
/* Nav */
header {
padding: 1.5rem 2rem;
border-bottom: 1px solid color-mix(in srgb, var(--color-text) 10%, transparent);
}
nav {
max-width: 960px;
margin: 0 auto;
}
.logo {
font-weight: 600;
text-decoration: none;
color: var(--color-accent);
}
/* Main */
main {
flex: 1;
max-width: 960px;
margin: 0 auto;
padding: 4rem 2rem;
width: 100%;
}
.hero h1 {
font-size: clamp(2rem, 6vw, 4rem);
line-height: 1.1;
margin-bottom: 1rem;
}
.hero p {
color: var(--color-muted);
font-size: 1.125rem;
}
/* Services */
.services {
margin-top: 4rem;
}
.section-title {
font-size: 1rem;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.08em;
color: var(--color-muted);
margin-bottom: 1rem;
}
.section-note {
color: var(--color-muted);
font-size: 0.875rem;
margin-bottom: 1rem;
}
.service-card.delegated {
opacity: 0.7;
}
.service-grid {
list-style: none;
display: grid;
grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
gap: 1rem;
}
.service-card {
padding: 1.5rem;
border: 1px solid color-mix(in srgb, var(--color-text) 12%, transparent);
border-radius: 8px;
display: flex;
flex-direction: column;
gap: 0.5rem;
transition: border-color 0.2s;
}
.service-card:hover {
border-color: var(--color-accent);
}
.service-card h2 {
font-size: 1rem;
font-weight: 600;
}
.service-card p {
color: var(--color-muted);
font-size: 0.875rem;
flex: 1;
}
.service-link {
color: var(--color-accent);
text-decoration: none;
font-size: 0.875rem;
font-weight: 500;
align-self: flex-start;
}
.service-link:hover {
text-decoration: underline;
}
/* Footer */
footer {
padding: 1.5rem 2rem;
text-align: center;
color: var(--color-muted);
font-size: 0.875rem;
border-top: 1px solid color-mix(in srgb, var(--color-text) 10%, transparent);
}
footer a {
color: var(--color-muted);
text-decoration: underline;
}
footer a:hover {
color: var(--color-text);
}