Add SSH key and make clipboard items consistent

This commit is contained in:
Bad Manners 2024-08-23 22:27:40 -03:00
parent e2527064db
commit 67e17ae27f
10 changed files with 127 additions and 162 deletions

4
package-lock.json generated
View file

@ -1,12 +1,12 @@
{
"name": "badmanners.xyz",
"version": "2.1.2",
"version": "2.1.3",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "badmanners.xyz",
"version": "2.1.2",
"version": "2.1.3",
"hasInstallScript": true,
"dependencies": {
"@astrojs/check": "^0.9.2",

View file

@ -1,7 +1,7 @@
{
"name": "badmanners.xyz",
"type": "module",
"version": "2.1.2",
"version": "2.1.3",
"scripts": {
"postinstall": "astro sync",
"dev": "astro dev",

1
public/ssh.pub Normal file
View file

@ -0,0 +1 @@
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJ3QAZd3E95gxef2kiXppWa/xhcwBtnKMZJaW6s4d7Tm Bad Manners <me@badmanners.xyz>

View file

@ -33,6 +33,7 @@ import IconTriangleExclamation from "./icons/IconTriangleExclamation.astro";
class="flex w-full max-w-md flex-col-reverse justify-evenly gap-y-5 px-6 pt-5 font-medium sm:max-w-2xl sm:flex-row"
>
<button
style={{ display: "none" }}
data-modal-reject
id="age-verification-reject"
class="rounded bg-stone-400 py-3 text-lg text-stone-900 hover:bg-stone-500 hover:text-stone-50 focus:bg-stone-500 focus:text-stone-50 sm:px-9 dark:bg-zinc-300 dark:text-zinc-900 dark:hover:bg-zinc-600 dark:hover:text-zinc-50 dark:focus:bg-zinc-600 dark:focus:text-zinc-50"
@ -40,6 +41,7 @@ import IconTriangleExclamation from "./icons/IconTriangleExclamation.astro";
Cancel
</button>
<button
style={{ display: "none" }}
data-modal-accept
id="age-verification-accept"
class="rounded bg-bm-500 py-3 text-lg text-stone-900 hover:bg-stone-500 hover:text-stone-50 focus:bg-stone-500 focus:text-stone-50 sm:px-9 dark:bg-bm-400 dark:text-zinc-900 dark:hover:bg-zinc-600 dark:hover:text-zinc-50 dark:focus:bg-zinc-600 dark:focus:text-zinc-50"
@ -73,7 +75,9 @@ import IconTriangleExclamation from "./icons/IconTriangleExclamation.astro";
location.href = "about:blank";
};
rejectButton.addEventListener("click", onRejectButtonClick);
modal.querySelector<HTMLElementTagNameMap["button"]>("button[data-modal-accept]")!.addEventListener(
rejectButton.style.removeProperty("display");
const acceptButton = modal.querySelector<HTMLElementTagNameMap["button"]>("button[data-modal-accept]")!;
acceptButton.addEventListener(
"click",
(e: MouseEvent) => {
e.preventDefault();
@ -86,6 +90,7 @@ import IconTriangleExclamation from "./icons/IconTriangleExclamation.astro";
},
{ once: true },
);
acceptButton.style.removeProperty("display");
rejectButton.focus();
}
};

View file

@ -0,0 +1,15 @@
---
import SVGIcon from "../SVGIcon.astro";
type Props = {
width: string;
height: string;
class?: string;
};
---
<SVGIcon {...Astro.props} viewBox="0 0 64 64">
<path
d="m 48.675781,20.294922 v 23.107422 h 4.53125 v -7.814453 c 0,-1.763417 0.253035,-3.11254 0.759766,-4.044922 0.526997,-0.95265 1.470092,-1.427735 2.828125,-1.427735 1.783686,0 2.675781,1.19613 2.675781,3.587891 v 9.699219 H 64 V 32.578125 c 0,-2.128261 -0.548043,-3.668443 -1.642578,-4.621094 -1.074264,-0.97292 -2.512452,-1.460937 -4.316406,-1.460937 -1.013458,0 -1.936542,0.193011 -2.767578,0.578125 -0.831035,0.385113 -1.510111,1.004164 -2.03711,1.855469 h -0.242187 c 0.04055,-0.304038 0.08055,-0.832073 0.121093,-1.582032 0.06081,-0.749958 0.0918,-1.529077 0.0918,-2.339844 v -4.71289 z M 0,24.398438 v 3.558593 L 10.154297,32.667969 0,36.833984 v 3.556641 l 14.746094,-6.505859 v -2.128907 z m 24.019531,2.097656 c -1.986373,0 -3.577558,0.386024 -4.773437,1.15625 -1.195878,0.770226 -1.794922,1.926342 -1.794922,3.466797 0,0.932379 0.162023,1.7115 0.486328,2.339843 0.324308,0.608075 0.821353,1.13611 1.490234,1.582032 0.668883,0.42565 1.520963,0.860721 2.554688,1.30664 1.074263,0.445922 1.864363,0.809985 2.371094,1.09375 0.506726,0.283768 0.830771,0.538758 0.972656,0.761719 0.162161,0.222961 0.244141,0.475998 0.24414,0.759766 0,0.42565 -0.193013,0.769704 -0.578124,1.033203 -0.364846,0.263497 -0.992924,0.394531 -1.884766,0.394531 -0.790494,0 -1.702602,-0.131034 -2.736328,-0.394531 -1.033724,-0.263499 -1.996831,-0.598527 -2.888672,-1.003906 v 3.740234 c 0.831034,0.344576 1.661153,0.588584 2.492187,0.730469 0.831036,0.162157 1.825128,0.242187 2.980469,0.242187 2.35122,0 4.115407,-0.44605 5.291016,-1.33789 1.195878,-0.912113 1.792968,-2.208286 1.792968,-3.890626 0,-0.993186 -0.193013,-1.79427 -0.578124,-2.402343 -0.364846,-0.628345 -0.890926,-1.1454 -1.580079,-1.550781 -0.689148,-0.425653 -1.510241,-0.831684 -2.46289,-1.216797 -0.972918,-0.405382 -1.713977,-0.729427 -2.220703,-0.972657 -0.486461,-0.243228 -0.81953,-0.465278 -1.001954,-0.667968 -0.162157,-0.222961 -0.24414,-0.466969 -0.24414,-0.730469 0,-0.729687 0.670051,-1.09375 2.007812,-1.09375 0.749959,0 1.489061,0.122003 2.21875,0.365234 0.72969,0.222962 1.499784,0.505034 2.310547,0.84961 l 1.369141,-3.251953 C 28.864236,27.338497 27.90113,27.003474 26.96875,26.800781 26.036372,26.598089 25.053257,26.496094 24.019531,26.496094 Z m 15.109375,0 c -1.986375,0 -3.577557,0.386023 -4.773437,1.15625 -1.195879,0.770227 -1.792969,1.926341 -1.792969,3.466797 0,0.93238 0.162022,1.711499 0.486328,2.339843 0.324308,0.608075 0.821352,1.13611 1.490234,1.582032 0.668883,0.425651 1.519009,0.86072 2.552735,1.30664 1.074264,0.445922 1.866316,0.809984 2.373047,1.09375 0.506727,0.283768 0.830771,0.538758 0.972656,0.761719 0.162161,0.222961 0.242188,0.475998 0.242188,0.759766 0,0.425651 -0.19106,0.769704 -0.576172,1.033203 -0.364846,0.263498 -0.994876,0.394531 -1.886719,0.394531 -0.790495,0 -1.702601,-0.131033 -2.736328,-0.394531 -1.033725,-0.263499 -1.994877,-0.598526 -2.886719,-1.003906 v 3.740234 c 0.831035,0.344576 1.661152,0.588584 2.492188,0.730469 0.831035,0.162158 1.825126,0.242187 2.980468,0.242187 2.351222,0 4.113453,-0.446049 5.289063,-1.33789 1.195878,-0.912113 1.794922,-2.208285 1.794922,-3.890626 0,-0.993187 -0.193012,-1.794269 -0.578125,-2.402343 -0.364845,-0.628345 -0.892879,-1.145399 -1.582032,-1.550781 -0.689149,-0.425653 -1.51024,-0.831683 -2.46289,-1.216797 -0.972919,-0.405382 -1.712023,-0.729427 -2.21875,-0.972657 C 37.822133,32.090755 37.48711,31.868707 37.304688,31.666016 37.142529,31.443055 37.0625,31.199047 37.0625,30.935547 c 0,-0.729688 0.668097,-1.09375 2.005859,-1.09375 0.74996,0 1.491014,0.122003 2.220703,0.365234 0.729691,0.222962 1.499783,0.505034 2.310547,0.84961 l 1.367188,-3.251953 C 43.97361,27.338497 43.010506,27.003474 42.078125,26.800781 41.145746,26.598089 40.162633,26.496094 39.128906,26.496094 Z"
></path>
</SVGIcon>

View file

@ -75,7 +75,6 @@ const title = pageTitle ? `${pageTitle} | Bad Manners` : "Bad Manners";
<span class="print:hidden" aria-hidden="true">&nbsp;|&nbsp;</span>
<a
href="/licenses.txt"
target="_blank"
class="transition-colors hover:text-white hover:underline focus:text-white focus:underline motion-reduce:transition-none dark:hover:text-bm-300 dark:focus:text-bm-300 print:hidden"
>
Licenses

View file

@ -1,40 +1,41 @@
import type { APIRoute, GetStaticPaths } from "astro";
import { APACHE_CONFIG } from "astro:env/server";
const htaccess = `
const htaccess = String.raw`
ErrorDocument 404 /404.html
RedirectMatch 301 ^/tos(/(index.html)?)?$ /terms_of_service/
RedirectMatch 301 ^/contact(/(index.html)?)?$ /
RedirectMatch 301 ^/@/(aryion|ekas?)\\b https://aryion.com/g4/user/BadManners
RedirectMatch 301 ^/@/(bluesky|bsky)\\b https://bsky.app/profile/badmanners.xyz
RedirectMatch 301 ^/@/(buymeacoffee|bmac)\\b https://www.buymeacoffee.com/BadMannersXYZ
RedirectMatch 301 ^/@/carrd\\b https://badmanners.carrd.co
RedirectMatch 301 ^/@/codeberg\\b https://codeberg.org/BadManners
RedirectMatch 301 ^/@/cohost\\b https://cohost.org/BadManners
RedirectMatch 301 ^/@/(fur[_-]?affinity|fa)\\b https://www.furaffinity.net/user/badmanners
RedirectMatch 301 ^/@/gallery\\b https://gallery.badmanners.xyz
RedirectMatch 301 ^/@/(github|gh)\\b https://github.com/BadMannersXYZ
RedirectMatch 301 ^/@/gitlab\\b https://gitlab.com/Bad_Manners
RedirectMatch 301 ^/@/gumroad\\b https://badmanners.gumroad.com/
RedirectMatch 301 ^/@/(inkbunny|ib)\\b https://inkbunny.net/BadManners
RedirectMatch 301 ^/@/itaku\\b https://itaku.ee/profile/badmanners
RedirectMatch 301 ^/@/itch\\b https://bad-manners.itch.io
RedirectMatch 301 ^/@/keybase\\b https://keybase.io/badmanners
RedirectMatch 301 ^/@/ko[_-]?fi\\b https://ko-fi.com/badmanners
RedirectMatch 301 ^/@/(mastodon|meow\\.social|gulp\\.cafe)\\b https://meow.social/@BadManners
RedirectMatch 301 ^/@/neocities\\b https://badmanners.neocities.org/
RedirectMatch 301 ^/@/picarto\\b https://www.picarto.tv/BadManners
RedirectMatch 301 ^/@/pillowfort\\b https://www.pillowfort.social/BadManners
RedirectMatch 301 ^/@/reddit\\b https://www.reddit.com/user/BadManners_/
RedirectMatch 301 ^/@/signal\\b https://signal.me/#eu/ytt_rk0fFmAB2JAW-x2PbUiJyc_H3kYmfL_Pq4QNh5QIDsiFtjdFHaqFRs1D36tB
RedirectMatch 301 ^/@/(sofurry|sf)\\b https://bad-manners.sofurry.com/
RedirectMatch 301 ^/@/steam\\b https://steamcommunity.com/id/badmanners_/
RedirectMatch 301 ^/@/subscribestar\\b https://subscribestar.adult/bad-manners
RedirectMatch 301 ^/@/(telegram|t\\.me)\\b https://t.me/bad_manners
RedirectMatch 301 ^/@/twitch\\b https://www.twitch.tv/bad__manners
RedirectMatch 301 ^/@/weasyl\\b https://www.weasyl.com/~badmanners
RedirectMatch 301 ^/@/(x|twitter)\\b https://x.com/BadManners__
RedirectMatch 301 ^/@/(youtu\\.?be|yt)\\b https://www.youtube.com/@BadMannersXYZ
RedirectMatch 301 ^/@/(aryion|ekas?)\b https://aryion.com/g4/user/BadManners
RedirectMatch 301 ^/@/(bluesky|bsky)\b https://bsky.app/profile/badmanners.xyz
RedirectMatch 301 ^/@/(buymeacoffee|bmac)\b https://www.buymeacoffee.com/BadMannersXYZ
RedirectMatch 301 ^/@/carrd\b https://badmanners.carrd.co
RedirectMatch 301 ^/@/codeberg\b https://codeberg.org/BadManners
RedirectMatch 301 ^/@/cohost\b https://cohost.org/BadManners
RedirectMatch 301 ^/@/(fur[_-]?affinity|fa)\b https://www.furaffinity.net/user/badmanners
RedirectMatch 301 ^/@/gallery\b https://gallery.badmanners.xyz
RedirectMatch 301 ^/@/(github|gh)\b https://github.com/BadMannersXYZ
RedirectMatch 301 ^/@/gitlab\b https://gitlab.com/Bad_Manners
RedirectMatch 301 ^/@/gumroad\b https://badmanners.gumroad.com
RedirectMatch 301 ^/@/(inkbunny|ib)\b https://inkbunny.net/BadManners
RedirectMatch 301 ^/@/itaku\b https://itaku.ee/profile/badmanners
RedirectMatch 301 ^/@/itch\b https://bad-manners.itch.io
RedirectMatch 301 ^/@/keybase\b https://keybase.io/badmanners
RedirectMatch 301 ^/@/ko[_-]?fi\b https://ko-fi.com/badmanners
RedirectMatch 301 ^/@/(mastodon|meow\.social|gulp\.cafe)\b https://meow.social/@BadManners
RedirectMatch 301 ^/@/neocities\b https://badmanners.neocities.org
RedirectMatch 301 ^/@/picarto\b https://www.picarto.tv/BadManners
RedirectMatch 301 ^/@/pillowfort\b https://www.pillowfort.social/BadManners
RedirectMatch 301 ^/@/reddit\b https://www.reddit.com/user/BadManners_
RedirectMatch 301 ^/@/signal\b https://signal.me/#eu/ytt_rk0fFmAB2JAW-x2PbUiJyc_H3kYmfL_Pq4QNh5QIDsiFtjdFHaqFRs1D36tB
RedirectMatch 301 ^/@/(sofurry|sf)\b https://bad-manners.sofurry.com
RedirectMatch 301 ^/@/ssh\b https://badmanners.xyz/ssh.pub
RedirectMatch 301 ^/@/steam\b https://steamcommunity.com/id/badmanners_
RedirectMatch 301 ^/@/subscribestar\b https://subscribestar.adult/bad-manners
RedirectMatch 301 ^/@/(telegram|t\.me)\b https://t.me/bad_manners
RedirectMatch 301 ^/@/twitch\b https://www.twitch.tv/bad__manners
RedirectMatch 301 ^/@/weasyl\b https://www.weasyl.com/~badmanners
RedirectMatch 301 ^/@/(x|twitter)\b https://x.com/BadManners__
RedirectMatch 301 ^/@/(youtu\.?be|yt)\b https://www.youtube.com/@BadMannersXYZ
`.trim();
export const getStaticPaths: GetStaticPaths = async () => {

View file

@ -28,6 +28,7 @@ import IconTwitch from "../components/icons/brands/IconTwitch.astro";
import IconWeasyl from "../components/icons/brands/IconWeasyl.astro";
import IconX from "../components/icons/brands/IconX.astro";
import IconYouTube from "../components/icons/brands/IconYouTube.astro";
import IconSSH from "../components/icons/brands/IconSSH.astro";
---
<BaseLayout>
@ -64,9 +65,10 @@ import IconYouTube from "../components/icons/brands/IconYouTube.astro";
<a
class="u-email text-link group block w-full transition-colors motion-reduce:transition-none"
href="mailto:me@badmanners.xyz"
target="_blank"
rel="me"
aria-label="me@badmanners.xyz"
data-clipboard="me@badmanners.xyz"
data-noun="E-mail address"
>
<IconEnvelope
height="1.75rem"
@ -80,7 +82,6 @@ import IconYouTube from "../components/icons/brands/IconYouTube.astro";
<a
class="u-url text-link group block w-full transition-colors motion-reduce:transition-none"
href="https://bsky.app/profile/badmanners.xyz"
target="_blank"
rel="me"
aria-label="Bluesky"
>
@ -96,7 +97,6 @@ import IconYouTube from "../components/icons/brands/IconYouTube.astro";
<a
class="u-url text-link group block w-full transition-colors motion-reduce:transition-none"
href="https://codeberg.org/BadManners"
target="_blank"
rel="me"
aria-label="Codeberg"
>
@ -112,7 +112,6 @@ import IconYouTube from "../components/icons/brands/IconYouTube.astro";
<a
class="u-url text-link group block w-full transition-colors motion-reduce:transition-none"
href="https://cohost.org/BadManners"
target="_blank"
rel="me"
aria-label="Cohost"
>
@ -128,7 +127,8 @@ import IconYouTube from "../components/icons/brands/IconYouTube.astro";
<button
class="text-link group block w-full transition-colors motion-reduce:transition-none"
aria-label="Discord"
data-username="badmanners"
data-clipboard="badmanners"
data-noun="Discord username"
aria-disabled="true"
>
<IconDiscord
@ -143,7 +143,6 @@ import IconYouTube from "../components/icons/brands/IconYouTube.astro";
<a
class="u-url text-link group block w-full transition-colors motion-reduce:transition-none"
href="https://aryion.com/g4/user/BadManners"
target="_blank"
rel="me"
aria-label="Eka's Portal"
>
@ -159,7 +158,6 @@ import IconYouTube from "../components/icons/brands/IconYouTube.astro";
<a
class="u-url text-link group block w-full transition-colors motion-reduce:transition-none"
href="https://www.furaffinity.net/user/BadManners"
target="_blank"
rel="me"
aria-label="Fur Affinity"
>
@ -175,7 +173,6 @@ import IconYouTube from "../components/icons/brands/IconYouTube.astro";
<a
class="u-url text-link group block w-full transition-colors motion-reduce:transition-none"
href="https://github.com/BadMannersXYZ"
target="_blank"
rel="me"
aria-label="GitHub"
>
@ -191,7 +188,6 @@ import IconYouTube from "../components/icons/brands/IconYouTube.astro";
<a
class="u-url text-link group block w-full transition-colors motion-reduce:transition-none"
href="https://gitlab.com/Bad_Manners"
target="_blank"
rel="me"
aria-label="GitLab"
>
@ -207,9 +203,10 @@ import IconYouTube from "../components/icons/brands/IconYouTube.astro";
<a
class="u-email text-link group block w-full transition-colors motion-reduce:transition-none"
href="mailto:badmanners.vore@gmail.com"
target="_blank"
rel="me"
aria-label="badmanners.vore@gmail.com"
data-clipboard="badmanners.vore@gmail.com"
data-noun="Gmail address"
>
<IconGoogle
height="1.75rem"
@ -223,7 +220,6 @@ import IconYouTube from "../components/icons/brands/IconYouTube.astro";
<a
class="u-url text-link group block w-full transition-colors motion-reduce:transition-none"
href="https://inkbunny.net/BadManners"
target="_blank"
rel="me"
aria-label="Inkbunny"
>
@ -239,7 +235,6 @@ import IconYouTube from "../components/icons/brands/IconYouTube.astro";
<a
class="u-url text-link group block w-full transition-colors motion-reduce:transition-none"
href="https://itaku.ee/profile/badmanners"
target="_blank"
rel="me"
aria-label="Itaku"
>
@ -255,7 +250,6 @@ import IconYouTube from "../components/icons/brands/IconYouTube.astro";
<a
class="u-url text-link group block w-full transition-colors motion-reduce:transition-none"
href="https://bad-manners.itch.io"
target="_blank"
rel="me"
aria-label="Itch.io"
>
@ -271,7 +265,6 @@ import IconYouTube from "../components/icons/brands/IconYouTube.astro";
<a
class="u-url text-link group block w-full transition-colors motion-reduce:transition-none"
href="https://keybase.io/badmanners"
target="_blank"
rel="me"
aria-label="Keybase"
>
@ -287,7 +280,6 @@ import IconYouTube from "../components/icons/brands/IconYouTube.astro";
<a
class="u-url text-link group block w-full transition-colors motion-reduce:transition-none"
href="https://ko-fi.com/badmanners"
target="_blank"
rel="me"
aria-label="Ko-fi"
>
@ -303,7 +295,6 @@ import IconYouTube from "../components/icons/brands/IconYouTube.astro";
<a
class="u-url text-link group block w-full transition-colors motion-reduce:transition-none"
href="https://meow.social/@BadManners"
target="_blank"
rel="me"
aria-label="Mastodon"
>
@ -312,14 +303,13 @@ import IconYouTube from "../components/icons/brands/IconYouTube.astro";
width="1.75rem"
class="inline transition-transform group-hover:scale-150 group-focus:scale-150 motion-reduce:transition-none motion-reduce:group-hover:scale-100 motion-reduce:group-focus:scale-100"
/>
<p class="sr-only">@BadManners p-nickname@meow.social on Mastodon</p>
<p class="p-nickname sr-only">@BadManners@meow.social on Mastodon</p>
</a>
</li>
<li id="neocities">
<a
class="u-url text-link group block w-full transition-colors motion-reduce:transition-none"
href="https://badmanners.neocities.org/"
target="_blank"
href="https://badmanners.neocities.org"
rel="me"
aria-label="Neocities"
>
@ -328,14 +318,13 @@ import IconYouTube from "../components/icons/brands/IconYouTube.astro";
width="1.75rem"
class="inline transition-transform group-hover:scale-150 group-focus:scale-150 motion-reduce:transition-none motion-reduce:group-hover:scale-100 motion-reduce:group-focus:scale-100"
/>
<p class="sr-only">badmanners p-nickname.neocities.org on Neocities</p>
<p class="p-nickname sr-only">badmanners.neocities.org on Neocities</p>
</a>
</li>
<li id="picarto">
<a
class="u-url text-link group block w-full transition-colors motion-reduce:transition-none"
href="https://www.picarto.tv/BadManners"
target="_blank"
rel="me"
aria-label="Picarto"
>
@ -350,8 +339,7 @@ import IconYouTube from "../components/icons/brands/IconYouTube.astro";
<li id="reddit">
<a
class="u-url text-link group block w-full transition-colors motion-reduce:transition-none"
href="https://www.reddit.com/user/BadManners_/"
target="_blank"
href="https://www.reddit.com/user/BadManners_"
rel="me"
aria-label="Reddit"
>
@ -367,7 +355,6 @@ import IconYouTube from "../components/icons/brands/IconYouTube.astro";
<a
class="u-url text-link group block w-full transition-colors motion-reduce:transition-none"
href="https://signal.me/#eu/ytt_rk0fFmAB2JAW-x2PbUiJyc_H3kYmfL_Pq4QNh5QIDsiFtjdFHaqFRs1D36tB"
target="_blank"
rel="me"
aria-label="Signal"
>
@ -382,8 +369,7 @@ import IconYouTube from "../components/icons/brands/IconYouTube.astro";
<li id="sofurry">
<a
class="u-url text-link group block w-full transition-colors motion-reduce:transition-none"
href="https://bad-manners.sofurry.com/"
target="_blank"
href="https://bad-manners.sofurry.com"
rel="me"
aria-label="SoFurry"
>
@ -395,11 +381,26 @@ import IconYouTube from "../components/icons/brands/IconYouTube.astro";
<p class="p-nickname sr-only">Bad Manners on SoFurry</p>
</a>
</li>
<li id="ssh">
<a
class="u-key text-link group block w-full transition-colors motion-reduce:transition-none"
href="/ssh.pub"
aria-label="SSH public key"
data-clipboard="ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJ3QAZd3E95gxef2kiXppWa/xhcwBtnKMZJaW6s4d7Tm Bad Manners <me@badmanners.xyz>"
data-noun="SSH key"
>
<IconSSH
height="1.75rem"
width="1.75rem"
class="inline transition-transform group-hover:scale-150 group-focus:scale-150 motion-reduce:transition-none motion-reduce:group-hover:scale-100 motion-reduce:group-focus:scale-100"
/>
<p class="sr-only">SSH public key</p>
</a>
</li>
<li id="steam">
<a
class="u-url text-link group block w-full transition-colors motion-reduce:transition-none"
href="https://steamcommunity.com/id/badmanners_/"
target="_blank"
href="https://steamcommunity.com/id/badmanners_"
rel="me"
aria-label="Steam"
>
@ -415,7 +416,6 @@ import IconYouTube from "../components/icons/brands/IconYouTube.astro";
<a
class="u-url text-link group block w-full transition-colors motion-reduce:transition-none"
href="https://subscribestar.adult/bad-manners"
target="_blank"
rel="me"
aria-label="SubscribeStar"
>
@ -431,7 +431,6 @@ import IconYouTube from "../components/icons/brands/IconYouTube.astro";
<a
class="u-url text-link group block w-full transition-colors motion-reduce:transition-none"
href="https://t.me/bad_manners"
target="_blank"
rel="me"
aria-label="Telegram"
>
@ -447,7 +446,6 @@ import IconYouTube from "../components/icons/brands/IconYouTube.astro";
<a
class="u-url text-link group block w-full transition-colors motion-reduce:transition-none"
href="https://www.twitch.tv/bad__manners"
target="_blank"
rel="me"
aria-label="Twitch"
>
@ -463,7 +461,6 @@ import IconYouTube from "../components/icons/brands/IconYouTube.astro";
<a
class="u-url text-link group block w-full transition-colors motion-reduce:transition-none"
href="https://www.weasyl.com/~badmanners"
target="_blank"
rel="me"
aria-label="Weasyl"
>
@ -479,7 +476,6 @@ import IconYouTube from "../components/icons/brands/IconYouTube.astro";
<a
class="u-url text-link group block w-full transition-colors motion-reduce:transition-none"
href="https://x.com/BadManners__"
target="_blank"
rel="me"
aria-label="X"
>
@ -495,7 +491,6 @@ import IconYouTube from "../components/icons/brands/IconYouTube.astro";
<a
class="u-url text-link group block w-full transition-colors motion-reduce:transition-none"
href="https://www.youtube.com/@BadMannersXYZ"
target="_blank"
rel="me"
aria-label="YouTube"
>
@ -526,13 +521,11 @@ import IconYouTube from "../components/icons/brands/IconYouTube.astro";
}
// Validate links
const emailAnchors = indexLinks.querySelectorAll<HTMLElementTagNameMap["a"]>(`li > a[href^="mailto:"]`);
const usernameButtons = indexLinks.querySelectorAll<HTMLElementTagNameMap["button"]>("li > button[data-username]");
if (!emailAnchors.length) {
console.warn("Missing e-mail anchors in #links list.");
}
if (!usernameButtons.length) {
console.warn("Missing username buttons in #links list.");
const customClipboardItems = indexLinks.querySelectorAll<HTMLElementTagNameMap["a" | "button"]>(
"li > :is(a, button)[data-clipboard]",
);
if (!customClipboardItems.length) {
console.warn("Missing custom clipboard elements in #links list.");
}
indexLinks.querySelectorAll("li > :not(a, button)").forEach((el) => {
console.warn("Element with unknown type found in #links list:", el);
@ -547,68 +540,32 @@ import IconYouTube from "../components/icons/brands/IconYouTube.astro";
theme: "bm",
});
// Add clipboard functionality to e-mail anchors and username buttons
// Add functionality to custom clipboard items
let tooltipTimeoutTag: TimeoutTag = null;
emailAnchors.forEach((anchor) => {
if (!anchor.href.startsWith("mailto:")) {
console.warn("Missing mailto: href for e-mail anchor, ignoring...", anchor);
customClipboardItems.forEach((element) => {
const label = element.dataset.noun ?? element.getAttribute("aria-label");
const clipboard = element.dataset.clipboard;
if (!clipboard) {
console.warn(`Missing "data-clipboard" field for custom clipboard element, ignoring...`, element);
return;
}
const emailAddress = anchor.href.slice("mailto:".length);
const anchorTooltip = tippy(anchor, {
content: "E-mail address copied to clipboard!",
element.removeAttribute("aria-disabled");
const elementTooltip = tippy(element, {
content: label ? `${label} copied to clipboard!` : "Copied to clipboard!",
trigger: "manual",
theme: "bm",
});
anchor.addEventListener("click", (ev) => {
element.addEventListener("click", (ev) => {
ev.preventDefault();
tooltipTimeoutTag && clearTimeout(tooltipTimeoutTag);
hideAll();
navigator.clipboard
.writeText(emailAddress)
.writeText(clipboard)
.then(() => {
anchorTooltip.setContent("E-mail address copied to clipboard!");
anchorTooltip.show();
elementTooltip.show();
})
.catch((e) => {
console.error("Unable to copy e-mail address to clipboard.", e);
anchorTooltip.setContent("Unable to copy e-mail address!");
anchorTooltip.show();
});
});
});
usernameButtons.forEach((button) => {
const label = button.getAttribute("aria-label");
const username = button.dataset.username;
if (!username) {
console.warn("Missing data-username for button, ignoring...", button);
return;
}
button.removeAttribute("aria-disabled");
button.removeAttribute("disabled");
const successContent = label ? `${label} username copied to clipboard!` : "Username copied to clipboard!";
const buttonTooltip = tippy(button, {
content: successContent,
trigger: "manual",
theme: "bm",
});
button.addEventListener("click", (ev) => {
ev.preventDefault();
tooltipTimeoutTag && clearTimeout(tooltipTimeoutTag);
hideAll();
navigator.clipboard
.writeText(username)
.then(() => {
buttonTooltip.setContent(successContent);
buttonTooltip.show();
})
.catch((e) => {
console.error(
label ? `Unable to copy ${label} username to clipboard.` : "Unable to copy username to clipboard.",
e,
);
buttonTooltip.setContent(label ? `Unable to copy ${label} username!` : "Unable to copy username!");
buttonTooltip.show();
console.error("Unable to copy custom content to clipboard.", clipboard, e);
});
});
});

View file

@ -21,7 +21,6 @@ import { TOS_COMMISSION_STATUS, TOS_UPDATED_AT } from "../data/tos";
href="/feed.xml"
rel="alternate"
type="application/rss+xml"
target="_blank"
title="RSS feed"
aria-label="RSS feed"
>
@ -131,7 +130,7 @@ import { TOS_COMMISSION_STATUS, TOS_UPDATED_AT } from "../data/tos";
If you have any doubts, or are considering getting a commission from me,
<a href="/" class="text-link underline transition-colors motion-reduce:transition-none"
>please reach out through my socials</a
>! Preferably Discord or Telegram, where I'm more active.
>! Preferably through Discord or Telegram, where I'm more active.
</li>
</ul>
</section>

View file

@ -22,17 +22,10 @@ import { SUBSCRIBESTAR_ENABLED } from "../data/subscribestar";
I've been a lurker in the furry vore community for a long time before I decided to start writing
<a
class="text-link transition-colors motion-reduce:transition-none"
href="https://gallery.badmanners.xyz/stories/1"
target="_blank"
><span class="underline">safe vore stories</span>
<IconArrowUpRightFromSquare width="0.75rem" height="0.75rem" class="inline" /></a
href="https://gallery.badmanners.xyz/stories/1"><span class="underline">safe vore stories</span></a
>. Since there's a lot in furry endosoma that I enjoy, my stories tend to
<a
class="text-link transition-colors motion-reduce:transition-none"
href="https://gallery.badmanners.xyz/tags"
target="_blank"
><span class="underline">have all sorts of themes and scenarios</span>
<IconArrowUpRightFromSquare width="0.75rem" height="0.75rem" class="inline" /></a
<a class="text-link transition-colors motion-reduce:transition-none" href="https://gallery.badmanners.xyz/tags"
><span class="underline">have all sorts of themes and scenarios</span></a
>, including exotic ones. My content is all tagged with the appropriate content warnings, so if you enjoy safe
vore, chances are that you'll find something in my gallery that is right up your alley.
</p>
@ -40,27 +33,22 @@ import { SUBSCRIBESTAR_ENABLED } from "../data/subscribestar";
I've also made a game called
<a
class="text-link transition-colors motion-reduce:transition-none"
href="https://gallery.badmanners.xyz/games/crossing-over"
target="_blank"
><span class="underline">"Crossing Over"</span>
<IconArrowUpRightFromSquare width="0.75rem" height="0.75rem" class="inline" /></a
href="https://gallery.badmanners.xyz/games/crossing-over"><span class="underline">"Crossing Over"</span></a
>, as part of Strawberry Jam 8 (a game jam hosted by eevee on Feb. 2024). It's been my biggest project so far,
and I'm very proud of it!
and I'm very proud of it! Check it out if you have an hour to spare and the subject matters interest you.
</p>
<p class="my-4 text-justify indent-6 sm:mb-3 sm:mt-6 sm:px-5 sm:indent-12">
You can find my gallery on the following websites, which include all of my content. Aside from the first link,
these also include some of the art that I've gotten from others (commissions, gifts, etc.).
<p class="mb-4 mt-4 text-justify indent-6 sm:mt-6 sm:px-5 sm:indent-12">
You can find my gallery and its mirrors below, which include all of my content. Aside from the first link, these
also include some of the art that I got from others (commissions, gifts, etc.).
</p>
<ul class="h-card flex flex-col items-center">
<li class="mb-2 w-max sm:mb-1">
<a
class="u-url text-link mx-1 transition-colors motion-reduce:transition-none"
href="https://gallery.badmanners.xyz/"
target="_blank"
href="https://gallery.badmanners.xyz"
>
<IconBriefcase height="1.75rem" width="1.75rem" class="mr-1 inline" />
<span class="underline">gallery.badmanners.xyz</span>
<IconArrowUpRightFromSquare width="0.75rem" height="0.75rem" class="inline" />
</a>
</li>
<li class="mb-2 w-max sm:mb-1">
@ -102,7 +90,7 @@ import { SUBSCRIBESTAR_ENABLED } from "../data/subscribestar";
<li class="mb-2 w-max sm:mb-1">
<a
class="u-url text-link mx-1 transition-colors motion-reduce:transition-none"
href="https://bad-manners.sofurry.com/"
href="https://bad-manners.sofurry.com"
target="_blank"
rel="me"
>
@ -130,17 +118,17 @@ import { SUBSCRIBESTAR_ENABLED } from "../data/subscribestar";
{
TOS_COMMISSION_STATUS == "CLOSED" ? (
<p class="mb-6 mt-2 sm:mt-3 sm:px-5">
My story commissions are currently closed, but regardless, feel free to
<a href="/terms_of_service" class="text-link underline transition-colors motion-reduce:transition-none">
check out my Terms of Service
</a>
My story commissions are currently closed, but regardless, feel free to{" "}
<a href="/terms_of_service" class="text-link transition-colors motion-reduce:transition-none">
<span class="underline">check out my Terms of Service</span>
</a>{" "}
if interested.
</p>
) : TOS_COMMISSION_STATUS == "OPEN" ? (
<p class="mb-6 mt-2 sm:mt-3 sm:px-5">
My story commissions are currently open! Feel free to{" "}
<a href="/terms_of_service" class="text-link underline transition-colors motion-reduce:transition-none">
check out my Terms of Service
<a class="text-link transition-colors motion-reduce:transition-none" href="/terms_of_service">
<span class="underline">check out my Terms of Service</span>
</a>{" "}
if interested.
</p>
@ -148,8 +136,8 @@ import { SUBSCRIBESTAR_ENABLED } from "../data/subscribestar";
<p class="mb-6 mt-2 sm:mt-3 sm:px-5">
My story commissions are currently semi-open, meaning that I may take some commissions, but might reject or
postpone them more easily. Feel free to{" "}
<a href="/terms_of_service" class="text-link underline transition-colors motion-reduce:transition-none">
check out my Terms of Service
<a href="/terms_of_service" class="text-link transition-colors motion-reduce:transition-none">
<span class="underline">check out my Terms of Service</span>
</a>{" "}
if interested.
</p>
@ -157,16 +145,16 @@ import { SUBSCRIBESTAR_ENABLED } from "../data/subscribestar";
<p class="mb-6 mt-2 sm:mt-3 sm:px-5">
My story commissions are currently private, meaning that I'm not offering slots publicly, but I may still
work on commissions for specific clients. Regardless of whether this applies to you or not, feel free to{" "}
<a href="/terms_of_service" class="text-link underline transition-colors motion-reduce:transition-none">
check out my Terms of Service
<a href="/terms_of_service" class="text-link transition-colors motion-reduce:transition-none">
<span class="underline">check out my Terms of Service</span>
</a>{" "}
if interested.
</p>
) : (
<p class="mb-6 mt-2 sm:mt-3 sm:px-5">
Feel free to{" "}
<a href="/terms_of_service" class="text-link underline transition-colors motion-reduce:transition-none">
check out my Terms of Service
<a href="/terms_of_service" class="text-link transition-colors motion-reduce:transition-none">
<span class="underline">check out my Terms of Service</span>
</a>{" "}
if interested.
</p>