Compare commits

..

No commits in common. "48d2a6658f0655346c44f25dfb2b6c5ab78db081" and "738e32a1e5879fc2a8705060e0108573be9b564c" have entirely different histories.

14 changed files with 68 additions and 395 deletions

View file

@ -1,4 +1,4 @@
h1, h2, h3, h4, h5, h6, p, li, br { h1, h2, h3, h4, h5, h6, p, br {
font-weight: normal; font-weight: normal;
margin: 0; margin: 0;
/* text-shadow: 1px 1px 0 var(--color-text-shadow); */ /* text-shadow: 1px 1px 0 var(--color-text-shadow); */
@ -27,11 +27,6 @@ h1 a, h2 a, h3 a, h4 a, h5 a, h6 a {
p { p {
margin-inline-start: 1rem; margin-inline-start: 1rem;
margin-block: 1.5rem;
}
p.nomargin {
margin-block: unset;
} }
ul { ul {
@ -44,51 +39,7 @@ ul li {
margin-block: 1.5rem; margin-block: 1.5rem;
} }
div {
margin-block: 1.5em;
margin-inline-start: 1em;
}
img {
vertical-align: middle;
}
a { a {
color: var(--color-accent); color: var(--color-accent);
text-decoration: underline solid currentColor 1px; text-decoration: underline solid currentColor 1px;
}
code {
display: inline-block;
font: inherit;
background-color: var(--color-code);
padding-inline: 0.5rem;
color: var(--color-code-text);
user-select: all;
}
button, input {
border: none;
background: transparent;
color: inherit;
font: inherit;
padding: 0;
outline: none;
}
input[type=text], input[type=url] {
padding-inline: 0.5rem;
border-inline: 0.5em solid var(--color-accent);
}
button, input[type=submit] {
padding-inline: 0.5rem;
background-color: var(--color-accent);
color: var(--color-bg);
cursor: pointer;
}
button:active, input[type=submit]:active {
background-color: transparent;
color: var(--color-accent);
} }

BIN
assets/fonts/jbm/jbm.ttf Normal file

Binary file not shown.

BIN
assets/fonts/m3x6/m3x6.ttf Normal file

Binary file not shown.

View file

@ -1,6 +1,15 @@
@font-face {
font-family: "m3x6";
src: url("./m3x6/m3x6.ttf");
}
@font-face {
font-family: "jbm";
src: url("./jbm/jbm.ttf");
}
@font-face { @font-face {
font-family: "dos"; font-family: "dos";
font-weight: regular;
src: url("./dos/dos.woff"); src: url("./dos/dos.woff");
} }

View file

@ -4,10 +4,8 @@
:root { :root {
--color-bg-scrim: #111; --color-bg-scrim: #111;
--color-bg: #222; --color-bg: #222;
--color-code: #000;
--color-code-text: #888;
--color-text: #ccc; --color-text: #ccc;
--color-accent: #bac; --color-accent: #aca;
font-size: 12px; font-size: 12px;
font-smooth: never; font-smooth: never;
@ -23,7 +21,6 @@ html {
body { body {
margin: 0; margin: 0;
padding: 0.1px 1rem; padding: 0.1px 1rem;
padding-block-end: 1.5rem;
min-height: 100%; min-height: 100%;
box-sizing: border-box; box-sizing: border-box;
width: 100%; width: 100%;

View file

@ -1,13 +1,11 @@
import express from "express"; import express from "express";
import { config as dotenvConfig } from "dotenv"; import { config } from "dotenv";
import path from "path"; import path from "path";
import SQLite from 'better-sqlite3'; import SQLite from 'better-sqlite3';
import { Kysely, SqliteDialect } from 'kysely'; import { Kysely, SqliteDialect } from 'kysely';
import { nanoid } from "nanoid"; import { nanoid } from "nanoid";
import { JSDOM } from "jsdom"; import { JSDOM } from "jsdom";
dotenvConfig();
const __dirname = import.meta.dirname; const __dirname = import.meta.dirname;
const rawDB = new SQLite('abtmtr.db'); const rawDB = new SQLite('abtmtr.db');
@ -26,19 +24,31 @@ app.set('view engine', 'ejs');
app.use('/assets', express.static('assets')); app.use('/assets', express.static('assets'));
app.set('views', path.join(__dirname, "views", "pages")); app.set('views', path.join(__dirname, "views", "pages"));
// app.use(async (req, res, next) => { app.locals = {
// const buttonsJson = await fetch("https://cdn.abtmtr.link/site_content/buttons.json") visibility: [
// .catch(() => res.status(500).send()) "Backend",
// .then((res) => res.json()) "Personal",
// .catch(() => res.status(500).send()); "Friends-only",
// const followingJson = await fetch("https://cdn.abtmtr.link/site_content/following.json") "Login-only",
// .catch(() => res.status(500).send()) "Public"
// .then((res) => res.json()) ]
// .catch(() => res.status(500).send()); }
// app.locals.buttons = buttonsJson;
// app.locals.following = followingJson; config();
// next();
// }) app.use(async (req, res, next) => {
const buttonsJson = await fetch("https://cdn.abtmtr.link/site_content/buttons.json")
.catch(() => res.status(500).send())
.then((res) => res.json())
.catch(() => res.status(500).send());
const followingJson = await fetch("https://cdn.abtmtr.link/site_content/following.json")
.catch(() => res.status(500).send())
.then((res) => res.json())
.catch(() => res.status(500).send());
app.locals.buttons = buttonsJson;
app.locals.following = followingJson;
next();
})
app.get('/', async (req, res) => { app.get('/', async (req, res) => {
const statusesJson = await fetch("https://cdn.abtmtr.link/site_content/v13/statuses.json") const statusesJson = await fetch("https://cdn.abtmtr.link/site_content/v13/statuses.json")
@ -50,50 +60,38 @@ app.get('/', async (req, res) => {
}); });
}) })
app.get('/servers', async (req, res) => { app.get('/services', async (req, res) => {
const servicesJson = await fetch("https://cdn.abtmtr.link/site_content/v13/services.json") const servicesJson = await fetch("https://cdn.abtmtr.link/site_content/v13/services.json")
.catch(() => res.status(500).send()) .catch(() => res.status(500).send())
.then((res) => res.json()); .then((res) => res.json());
res.render('services/index', { services: servicesJson });
});
app.get('/computers', async (req, res) => {
const computersJson = await fetch("https://cdn.abtmtr.link/site_content/v13/computers.json") const computersJson = await fetch("https://cdn.abtmtr.link/site_content/v13/computers.json")
.catch(() => res.status(500).send()) .catch(() => res.status(500).send())
.then((res) => res.json()); .then((res) => res.json());
res.render('servers', { res.render('computers/index', { computers: computersJson });
services: servicesJson,
computers: computersJson,
visibility: [
"for domain performance",
"for personal use",
"for use by friends of abtmtr.link's webmaster(s)",
"for restricted public use",
"for public use"
]
});
}); });
app.get('/about', async (req, res) => { app.get('/links', async (req, res) => {
const linksJson = await fetch("https://cdn.abtmtr.link/site_content/v13/links.json") const linksJson = await fetch("https://cdn.abtmtr.link/site_content/v13/links.json")
.catch(() => res.status(500).send()) .catch(() => res.status(500).send())
.then((res) => res.json()); .then((res) => res.json());
res.render('about', { res.render('links/index', {
links: linksJson links: linksJson
}); });
}); });
app.get('/sites', async (req, res) => { app.get('/matkap', (req, res) => {
const buttonsJson = await fetch("https://cdn.abtmtr.link/site_content/buttons.json") res.render('matkap/index');
.catch(() => res.status(500).send()) });
.then((res) => res.json())
.catch(() => res.status(500).send());
const followingJson = await fetch("https://cdn.abtmtr.link/site_content/following.json")
.catch(() => res.status(500).send())
.then((res) => res.json())
.catch(() => res.status(500).send());
res.render('sites', { app.get('/about', (req, res) => {
b: buttonsJson, f: followingJson res.render('about/index');
});
}); });
app.get('/blurbs', async (req, res) => { app.get('/blurbs', async (req, res) => {
@ -103,7 +101,7 @@ app.get('/blurbs', async (req, res) => {
.where('verified', '=', 1) .where('verified', '=', 1)
.orderBy('time', "desc") .orderBy('time', "desc")
.execute(); .execute();
res.render('blurbs', { data }); res.render('blurbs/index', { data });
}); });
// brbrleibbghbelsbbsbuuebbuubsubss // brbrleibbghbelsbbsbuuebbuubsubss
@ -116,11 +114,6 @@ async function cleanupBlurbles() {
.execute() .execute()
} }
app.get('/blurbs/testsend', async (req, res) => {
res.render('blurbsent', { id: "THISISATESTLOL" });
});
app.get('/blurbs/send', async (req, res) => { app.get('/blurbs/send', async (req, res) => {
const body = req.query; const body = req.query;
const errors = []; const errors = [];
@ -160,7 +153,7 @@ app.get('/blurbs/send', async (req, res) => {
cleanupBlurbles(); cleanupBlurbles();
res.render('blurbsent', { id: postId }); res.render('blurbs/sent', { id: postId });
}); });
app.get('/blurbs/check', async (req, res) => { app.get('/blurbs/check', async (req, res) => {

View file

@ -1,6 +1,6 @@
<footer> <footer>
<h1>abtmtr.link v13-2</h1> <h1>abtmtr.link v13-2</h1>
<p class="nomargin">(c) MeowcaTheoRange 2023-24</p> <p>(c) MeowcaTheoRange 2023-24</p>
<p class="nomargin">licensed under the <a href="https://git.abtmtr.link/MeowcaTheoRange/KarkatPublicLicense/">KKPL</a>.</p> <p>licensed under the <a href="https://git.abtmtr.link/MeowcaTheoRange/KarkatPublicLicense/">KKPL</a>.</p>
<p class="nomargin">fork <a href="https://git.abtmtr.link/MeowcaTheoRange/abtmtr-v13/">MeowcaTheoRange/abtmtr-v13</a> with git</p> <p>fork <a href="https://git.abtmtr.link/MeowcaTheoRange/abtmtr-v13/">MeowcaTheoRange/abtmtr-v13</a> with git</p>
</footer> </footer>

View file

@ -1,7 +0,0 @@
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<title>abtmtr.link</title>
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="stylesheet" href="/assets/style.css" />
</head>

View file

@ -1,44 +0,0 @@
<!DOCTYPE html>
<html>
<%- include("../components/page-head.ejs") %>
<body>
<main>
<h1>about</h1>
<p>hey, i'm MeowcaTheoRange.<br />i run abtmtr.link, for the most part.</p>
<h2>MeowcaTheoRange's h-card</h2>
<div class="h-card">
<h3><span class="p-name">Theo Range</span>
(<span class="p-nickname">MeowcaTheoRange</span>)</h3>
<p class="nomargin">(<span class="p-honorific-prefix">Mx.</span>
<span class="p-given-name">Theo</span>
<span class="p-family-name">Range</span>)</p>
<p class="nomargin">
<span class="p-gender-identity">Non-binary</span>,
<span class="p-pronouns">they/them</span>
</p>
<p><img class="u-photo" src="https://abtmtr.link/favicon.ico" height="72"></p>
<p class="nomargin">
<a class="u-url" href="https://abtmtr.link/">website</a>,
<a class="u-email" href="mailto:me@abtmtr.link">email</a>
</p>
<p class="nomargin">
born <time class="dt-bday">2007-08-07</time>
</p>
<p class="p-adr nomargin">
<span class="p-region">Minnesota</span>,
<span class="p-country-name">USA</span>
</p>
</div>
<h2>MeowcaTheoRange's links</h2>
<p>where else is MeowcaTheoRange?</p>
<ul>
<% links.forEach((link) => { %>
<li><h3><a href="<%= link.link %>" target="_blank"><%= link.title %> / <%= new URL(link.link).hostname %></a></h3>
<p class="nomargin"><%= link.subtitle %></p>
</li>
<% }) %>
</ul>
</main>
<%- include("../components/footer.ejs") %>
</body>
</html>

View file

@ -1,42 +0,0 @@
<!DOCTYPE html>
<html>
<%- include("../components/page-head.ejs") %>
<body>
<main>
<h1>blurbs</h1>
<p>what are other sites saying about abtmtr.link?</p>
<h2>submit a blurb</h2>
<form action="/blurbs/send" method="get">
<p>
<label for="siteName">Website URL:</label>
<input type="url" name="site" id="siteName">
</p>
<p>
<label for="blurbText">Blurb:</label>
<input type="text" name="text" id="blurbText" maxlength="140" minlength="1">
</p>
<p>
<input type="submit" value="Submit Blurb">
</p>
<p style="opacity: 0.5;">by clicking this button and successfully submitting a blurb, you agree that your input may be displayed on this site and stored on abtmtr.link servers.</p>
<p style="opacity: 0.5;">you'll also need to verify your blurb by leaving a X/HTML snippet on your site. further instructions will be given to do this after you submit your blurb. thanks!</p>
</form>
<h2>current blurbs</h2>
<ul>
<% data.forEach((blurb) => { %>
<li class="blurb" id="<%= blurb.id %>"><a href="<%= blurb.site %>" target="_blank"><%= new URL(blurb.site).host %></a>: <%= blurb.blurb %> <a class="removePopup" href="/blurbs/check?id=<%= blurb.id %>">remove</a></li>
<% }) %>
</ul>
</main>
<%- include("../components/footer.ejs") %>
<style>
.blurb .removePopup {
visibility: hidden;
opacity: 0.5;
}
.blurb:hover .removePopup {
visibility: visible;
}
</style>
</body>
</html>

View file

@ -1,34 +0,0 @@
<!DOCTYPE html>
<html>
<%- include("../components/page-head.ejs") %>
<body>
<main>
<h1>blurb sent</h1>
<p>congrations! you done it!</p>
<h2>what now?</h2>
<p>you have to add one of these code snippets to your site in order for the blurb to actually pop up.</p>
<p>invisible: <code tabindex="0">&lt;link rel="me" href="https://abtmtr.link/blurbs/#<%= id %>"&gt;</code></p>
<p>visible: <code tabindex="0">&lt;a rel="me" href="https://abtmtr.link/blurbs/#<%= id %>"&gt;&lt;/a&gt;</code></p>
<p>88x31: <code tabindex="0">&lt;a rel="me" href="https://abtmtr.link/blurbs/#<%= id %>" target="_blank"&gt;&lt;img src="https://cdn.abtmtr.link/site_content/88x31/abtmtr_link.png"&gt;&lt;/a&gt;</code></p>
<p>if you want to remove your blurb from abtmtr.link, remove the snippet from your site and then click "remove" on the blurb.</p>
<p>do not leave this site until you have added the snippet! you can bookmark this page if you need to:</p>
<p><code tabindex="0">https://abtmtr.link/blurbs/check/?id=<%= id %></code></p>
<p>once you've done that, click this button below, and your blurb should appear if everything was done correctly. make sure your page has updated in your browser!</p>
<form action="/blurbs/check/" method="get">
<input type="hidden" value="<%= id %>" name="id">
<p><input type="submit" value="Done and added"></p>
</form>
<p style="opacity: 0.5;">can't/don't want to add the snippet? <a href="/about" target="_blank">contact me</a>.</p>
</main>
<%- include("../components/footer.ejs") %>
<style>
.blurb .removePopup {
visibility: hidden;
opacity: 0.5;
}
.blurb:hover .removePopup {
visibility: visible;
}
</style>
</body>
</html>

View file

@ -1,6 +1,13 @@
<!DOCTYPE html> <!DOCTYPE html>
<html> <html>
<%- include("../components/page-head.ejs") %> <head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<title>abtmtr.link</title>
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="stylesheet" href="/assets/style.css" />
</head>
<body> <body>
<main> <main>
<h1>welcome to abtmtr.link!</h1> <h1>welcome to abtmtr.link!</h1>
@ -9,19 +16,15 @@
<ul> <ul>
<li> <li>
<h3><a href="/blurbs/">blurbs</a></h3> <h3><a href="/blurbs/">blurbs</a></h3>
<p class="nomargin">what are other sites saying about abtmtr.link?</p> <p>what are other sites saying about abtmtr.link?</p>
</li> </li>
<li> <li>
<h3><a href="/servers/">servers</a></h3> <h3><a href="/servers/">servers</a></h3>
<p class="nomargin">about the services on abtmtr.link and the machines that serve them.</p> <p>about the services on abtmtr.link and the machines that serve them.</p>
</li>
<li>
<h3><a href="/sites/">sites</a></h3>
<p class="nomargin">a collection of other sites in the form of 88x31s.</p>
</li> </li>
<li> <li>
<h3><a href="/about/">about</a></h3> <h3><a href="/about/">about</a></h3>
<p class="nomargin">who runs abtmtr.link?</p> <p>who runs abtmtr.link?</p>
</li> </li>
</ul> </ul>
</main> </main>

View file

@ -1,32 +0,0 @@
<!DOCTYPE html>
<html>
<%- include("../components/page-head.ejs") %>
<body>
<main>
<h1>servers</h1>
<p>about the services on abtmtr.link and the machines that serve them.</p>
<h2>services</h2>
<p>stuff that's hosted on abtmtr.link.</p>
<ul>
<% services.forEach((service) => { %>
<li>
<h3><a href="https://<%= service.domain %>/" target="_blank"><%= service.domain %> / <%= service.when.month %> <%= service.when.year %></a></h3>
<p class="nomargin">Runs <%= service.software %> <%= visibility[service.visibility] %></p>
</li>
<% }) %>
</ul>
<h2>machines</h2>
<p>stuff that hosts on abtmtr.link.</p>
<ul>
<% computers.forEach((puter) => { %>
<li>
<h3><%= puter.name %> / <%= puter.whenGot.month %> <%= puter.whenGot.year %></h3>
<p class="nomargin"><%= puter.model %> / <%= puter.description %></p>
<p><%= puter.subtitle %></p>
</li>
<% }) %>
</ul>
</main>
<%- include("../components/footer.ejs") %>
</body>
</html>

View file

@ -1,121 +0,0 @@
<!DOCTYPE html>
<html>
<%- include("../components/page-head.ejs") %>
<body>
<main>
<h1>sites</h1>
<p>a large collection of 88x31s.</p>
<h2>friends (<%= b.length %>)</h2>
<div>
<% b.forEach((button) => { %>
<% if (button.img != null) { %>
<a class="web-button" target="_blank" href="<%= button.href %>"><img src="<%= button.img %>" title="<%= button.alt %>" alt="<%= button.alt %>" /></a>
<% } else { %>
<a class="web-button noimg" target="_blank" href="<%= button.href %>" title="<%= button.alt %>" style="background-color: <%= button.accent[0] %>;color: <%= button.accent[1] %>"><span><%= button.name %></span></a>
<% } %>
<% }) %>
</div>
<h2>following (<%= f.length %>)</h2>
<div>
<% f.forEach((button) => { %>
<% if (button.img != null) { %>
<a class="web-button" target="_blank" href="<%= button.href %>"><img src="<%= button.img %>" title="<%= button.alt %>" alt="<%= button.alt %>" /></a>
<% } else { %>
<a class="web-button noimg" target="_blank" href="<%= button.href %>" title="<%= button.alt %>" style="background-color: <%= button.accent[0] %>;color: <%= button.accent[1] %>"><span><%= button.name %></span></a>
<% } %>
<% }) %>
</div>
</main>
<%- include("../components/footer.ejs") %>
<style>
@property --hue {
syntax: '<number>';
initial-value: 0;
inherits: false;
}
@keyframes hue-shift {
0% {
--hue: 0;
}
50% {
--hue: 180;
}
100% {
--hue: 360;
}
}
.web-button img {
vertical-align: baseline;
}
.web-button {
position: relative;
filter: grayscale(1);
left: 0;
top: 0;
transition: all 0.5s ease-out;
opacity: 1 !important;
display: inline-block;
width: 88px;
height: 31px;
line-height: 31px;
border: 1px solid black;
vertical-align: middle;
margin: 0.5rem;
text-decoration: none;
text-align: center;
/* text-overflow: ellipsis;
overflow: hidden;
padding: 0 8px;
box-sizing: border-box; */
}
.web-button.noimg {
text-shadow: 1px 1px 0 #000;
box-shadow:
inset -1px -1px 0 0 #000,
inset 1px 1px 0 0 #fff,
inset -2px -2px 0 0 #0008;
/* background-image: linear-gradient(135deg, transparent, #8888); */
}
.web-button:hover {
left: -4px;
top: -4px;
z-index: 999;
filter: grayscale(0);
animation: hue-shift 1s linear infinite;
transition: all 0.0625s ease-out;
--shadow: hsl(var(--hue), 50%, 75%);
box-shadow:
4px 4px 0 -1px var(--shadow),
3px 3px 0 -1px var(--shadow),
2px 2px 0 -1px var(--shadow),
1px 1px 0 -1px var(--shadow),
4px 4px 0 0px black,
3px 3px 0 0px black,
2px 2px 0 0px black,
1px 1px 0 0px black;
}
.web-button.noimg:hover {
box-shadow:
inset -1px -1px 0 0 #000,
inset 1px 1px 0 0 #fff,
inset -2px -2px 0 0 #0008,
4px 4px 0 -1px var(--shadow),
3px 3px 0 -1px var(--shadow),
2px 2px 0 -1px var(--shadow),
1px 1px 0 -1px var(--shadow),
4px 4px 0 0px black,
3px 3px 0 0px black,
2px 2px 0 0px black,
1px 1px 0 0px black;
}
</style>
</body>
</html>