Consolidate socials on index and add View Transitions API support
This commit is contained in:
parent
580cd2da26
commit
483f406037
23 changed files with 493 additions and 458 deletions
|
|
@ -1,82 +1,87 @@
|
|||
---
|
||||
import AgeRestrictedScriptInline from "./AgeRestrictedScriptInline.astro";
|
||||
import IconTriangleExclamation from "./icons/IconTriangleExclamation.astro";
|
||||
---
|
||||
|
||||
<template id="template-modal-age-restricted">
|
||||
<div
|
||||
id="modal-age-restricted"
|
||||
class="fixed inset-0 bg-stone-50 dark:bg-zinc-900"
|
||||
tabindex="-1"
|
||||
role="dialog"
|
||||
aria-hidden="false"
|
||||
>
|
||||
<div class="mx-auto flex min-h-screen max-w-3xl flex-col items-center justify-center text-center tracking-tight">
|
||||
<div class="text-bm-500 dark:text-bm-400">
|
||||
<IconTriangleExclamation width="3rem" height="3rem" />
|
||||
</div>
|
||||
<div class="pb-3 pt-2 text-3xl font-light text-stone-700 sm:pb-4 sm:pt-2 dark:text-zinc-50">
|
||||
Age verification
|
||||
</div>
|
||||
<div
|
||||
class="mx-6 mb-4 max-w-xl border-b border-stone-300 pb-4 text-xl text-stone-700 dark:border-zinc-300 dark:text-zinc-50"
|
||||
<div
|
||||
style={{ display: "none" }}
|
||||
id="modal-age-restricted"
|
||||
class="fixed inset-0 bg-stone-50 dark:bg-zinc-900"
|
||||
role="dialog"
|
||||
aria-labelledby="title-age-restricted"
|
||||
>
|
||||
<div class="mx-auto flex min-h-screen max-w-3xl flex-col items-center justify-center text-center tracking-tight">
|
||||
<div class="text-bm-500 dark:text-bm-400">
|
||||
<IconTriangleExclamation width="3rem" height="3rem" />
|
||||
</div>
|
||||
<div
|
||||
id="title-age-restricted"
|
||||
class="pb-3 pt-2 text-3xl font-normal text-stone-700 sm:pb-4 sm:pt-2 dark:text-zinc-50"
|
||||
>
|
||||
Age verification
|
||||
</div>
|
||||
<div
|
||||
class="mx-6 mb-4 max-w-xl border-b border-stone-300 pb-4 text-xl font-medium text-stone-700 dark:border-zinc-300 dark:text-zinc-50"
|
||||
>
|
||||
You must be 18+ to access this page.
|
||||
</div>
|
||||
<p class="px-8 text-lg font-normal leading-snug text-stone-700 sm:max-w-2xl dark:text-zinc-50">
|
||||
By confirming that you are at least 18 years old, your selection will be saved to your browser to prevent this
|
||||
screen from appearing in the future.
|
||||
</p>
|
||||
<div
|
||||
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
|
||||
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"
|
||||
>
|
||||
You must be 18+ to access this page.
|
||||
</div>
|
||||
<p class="px-8 text-lg font-light leading-snug text-stone-700 sm:max-w-2xl dark:text-zinc-50">
|
||||
By confirming that you are at least 18 years old, your selection will be saved to your browser to prevent this
|
||||
screen from appearing in the future.
|
||||
</p>
|
||||
<div class="flex w-full max-w-md flex-col-reverse justify-evenly gap-y-5 px-6 pt-5 sm:max-w-2xl sm:flex-row">
|
||||
<button
|
||||
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"
|
||||
>
|
||||
Cancel
|
||||
</button>
|
||||
<button
|
||||
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"
|
||||
>
|
||||
I'm at least 18 years old
|
||||
</button>
|
||||
</div>
|
||||
Cancel
|
||||
</button>
|
||||
<button
|
||||
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"
|
||||
>
|
||||
I'm at least 18 years old
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
|
||||
<AgeRestrictedScriptInline />
|
||||
|
||||
<script>
|
||||
(function () {
|
||||
if (localStorage.getItem("ageVerified") !== "true") {
|
||||
const fragment = document
|
||||
.querySelector<HTMLElementTagNameMap["template"]>("template#template-modal-age-restricted")!
|
||||
.content.cloneNode(true) as DocumentFragment;
|
||||
const modal = fragment.firstElementChild as HTMLElementTagNameMap["div"];
|
||||
const controller = new AbortController();
|
||||
const { signal } = controller;
|
||||
modal.querySelector<HTMLElementTagNameMap["button"]>("button[data-modal-reject]")!.addEventListener(
|
||||
"click",
|
||||
(e: MouseEvent) => {
|
||||
e.preventDefault();
|
||||
location.href = "about:blank";
|
||||
},
|
||||
{ signal },
|
||||
);
|
||||
import { ENABLE_VIEW_TRANSITIONS } from "astro:env/client";
|
||||
|
||||
const ageRestrictedModalSetup = () => {
|
||||
if (localStorage.ageVerified !== "true") {
|
||||
const modal = document.querySelector<HTMLElementTagNameMap["div"]>("div#modal-age-restricted")!;
|
||||
const rejectButton = modal.querySelector<HTMLElementTagNameMap["button"]>("button[data-modal-reject]")!;
|
||||
const onRejectButtonClick = (e: MouseEvent) => {
|
||||
e.preventDefault();
|
||||
location.href = "about:blank";
|
||||
};
|
||||
rejectButton.addEventListener("click", onRejectButtonClick);
|
||||
modal.querySelector<HTMLElementTagNameMap["button"]>("button[data-modal-accept]")!.addEventListener(
|
||||
"click",
|
||||
(e: MouseEvent) => {
|
||||
e.preventDefault();
|
||||
controller.abort();
|
||||
localStorage.setItem("ageVerified", "true");
|
||||
rejectButton.removeEventListener("click", onRejectButtonClick);
|
||||
localStorage.ageVerified = "true";
|
||||
document.body.style.overflow = "auto";
|
||||
modal.remove();
|
||||
document.querySelectorAll("body > :not(#modal-age-restricted)").forEach((el) => el.removeAttribute("inert"));
|
||||
modal.style.display = "none";
|
||||
},
|
||||
{ signal },
|
||||
{ once: true },
|
||||
);
|
||||
document.body.style.overflow = "hidden";
|
||||
document.body.appendChild(fragment);
|
||||
document.querySelector<HTMLElementTagNameMap["button"]>("button[data-modal-reject]")?.focus();
|
||||
rejectButton.focus();
|
||||
}
|
||||
})();
|
||||
};
|
||||
if (ENABLE_VIEW_TRANSITIONS) {
|
||||
document.addEventListener("astro:page-load", ageRestrictedModalSetup);
|
||||
} else {
|
||||
ageRestrictedModalSetup();
|
||||
}
|
||||
</script>
|
||||
|
|
|
|||
4
src/components/AgeRestrictedScriptInline.astro
Normal file
4
src/components/AgeRestrictedScriptInline.astro
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
---
|
||||
---
|
||||
|
||||
<script is:inline>function a(){let b=document,c="modal-age-restricted";localStorage.ageVerified!=="true"&&((b.body.style.overflow="hidden"),b.querySelectorAll("body > :not(#"+c+")").forEach(e=>e.setAttribute("inert","true")),(b.getElementById(c).style.display="block"));}document.addEventListener("astro:after-swap",a);a()</script>
|
||||
|
|
@ -1,4 +0,0 @@
|
|||
---
|
||||
---
|
||||
|
||||
<script is:inline>!function(){var a="dark",b="auto",c="colorScheme",d=document.body.classList,e=localStorage,f=e.getItem(c);f&&f!==b?f===a&&d.add(a):(e.setItem(c,b),matchMedia("(prefers-color-scheme: dark)").matches&&d.add(a))}();</script>
|
||||
|
|
@ -1,13 +1,15 @@
|
|||
---
|
||||
import DarkModeInline from "./AutoDarkMode.astro";
|
||||
import DarkModeScriptInline from "./DarkModeScriptInline.astro";
|
||||
---
|
||||
|
||||
<DarkModeInline />
|
||||
<DarkModeScriptInline />
|
||||
|
||||
<script>
|
||||
(function () {
|
||||
let colorScheme = localStorage.getItem("colorScheme");
|
||||
if (colorScheme == null || colorScheme === "auto") {
|
||||
import { ENABLE_VIEW_TRANSITIONS } from "astro:env/client";
|
||||
|
||||
const colorSchemeSetup = () => {
|
||||
let colorScheme = localStorage.colorScheme;
|
||||
if (!colorScheme || colorScheme === "auto") {
|
||||
colorScheme = matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light";
|
||||
}
|
||||
document.querySelectorAll<HTMLElementTagNameMap["button"]>("button[data-dark-mode]").forEach((button) => {
|
||||
|
|
@ -23,8 +25,13 @@ import DarkModeInline from "./AutoDarkMode.astro";
|
|||
colorScheme = "dark";
|
||||
document.body.classList.add("dark");
|
||||
}
|
||||
localStorage.setItem("colorScheme", colorScheme);
|
||||
localStorage.colorScheme = colorScheme;
|
||||
});
|
||||
});
|
||||
})();
|
||||
};
|
||||
if (ENABLE_VIEW_TRANSITIONS) {
|
||||
document.addEventListener("astro:page-load", colorSchemeSetup);
|
||||
} else {
|
||||
colorSchemeSetup();
|
||||
}
|
||||
</script>
|
||||
|
|
|
|||
4
src/components/DarkModeScriptInline.astro
Normal file
4
src/components/DarkModeScriptInline.astro
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
---
|
||||
---
|
||||
|
||||
<script is:inline>function a(){var b="dark",c="auto",d="colorScheme",e=document.body.classList,f=localStorage,g=f[d];g&&g!==c?g===b&&e.add(b):(f[d]=c,matchMedia("(prefers-color-scheme: dark)").matches&&e.add(b))};document.addEventListener("astro:after-swap",a);a()</script>
|
||||
|
|
@ -8,7 +8,6 @@ const navRoutes: NavRoute[] = [
|
|||
{ path: "/", name: "Home" },
|
||||
{ path: "/about", name: "About me" },
|
||||
{ path: "/work", name: "My work" },
|
||||
{ path: "/contact", name: "Contact" },
|
||||
];
|
||||
|
||||
const isCurrentRoute = (navRoute: NavRoute) => Astro.url.pathname == navRoute.path;
|
||||
|
|
|
|||
|
|
@ -1,15 +0,0 @@
|
|||
---
|
||||
import SVGIcon from "./SVGIcon.astro";
|
||||
|
||||
type Props = {
|
||||
width: string;
|
||||
height: string;
|
||||
class?: string;
|
||||
};
|
||||
---
|
||||
|
||||
<SVGIcon {...Astro.props} viewBox="0 0 512 512">
|
||||
<path
|
||||
d="M64 464H288c8.8 0 16-7.2 16-16V384h48v64c0 35.3-28.7 64-64 64H64c-35.3 0-64-28.7-64-64V224c0-35.3 28.7-64 64-64h64v48H64c-8.8 0-16 7.2-16 16V448c0 8.8 7.2 16 16 16zM224 352c-35.3 0-64-28.7-64-64V64c0-35.3 28.7-64 64-64H448c35.3 0 64 28.7 64 64V288c0 35.3-28.7 64-64 64H224z"
|
||||
></path>
|
||||
</SVGIcon>
|
||||
|
|
@ -1,15 +0,0 @@
|
|||
---
|
||||
import SVGIcon from "./SVGIcon.astro";
|
||||
|
||||
type Props = {
|
||||
width: string;
|
||||
height: string;
|
||||
class?: string;
|
||||
};
|
||||
---
|
||||
|
||||
<SVGIcon {...Astro.props} viewBox="0 0 448 512">
|
||||
<path
|
||||
d="M8 256a56 56 0 1 1 112 0A56 56 0 1 1 8 256zm160 0a56 56 0 1 1 112 0 56 56 0 1 1 -112 0zm216-56a56 56 0 1 1 0 112 56 56 0 1 1 0-112z"
|
||||
></path>
|
||||
</SVGIcon>
|
||||
15
src/components/icons/brands/IconCohost.astro
Normal file
15
src/components/icons/brands/IconCohost.astro
Normal 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 40.820312,8.9199219 C 36.257148,8.8605533 31.440597,9.5093383 26.373047,10.867188 20.554621,12.426215 15.490193,14.614059 11.177734,17.429688 6.8652759,20.245279 3.7316853,23.583136 1.7773438,27.441406 -0.17700239,31.299712 -0.52034379,35.598908 0.75,40.339844 c 1.263096,4.714066 3.7087126,8.259066 7.3339844,10.636718 3.6252706,2.377654 8.0124156,3.722128 13.1621096,4.03125 5.149729,0.309125 10.632671,-0.316018 16.451172,-1.875 5.238854,-1.403695 9.865205,-3.334276 13.876953,-5.791015 -0.477048,0.03214 -0.964536,0.04687 -1.462891,0.04687 -2.118726,0 -4.038277,-0.285908 -5.759766,-0.859375 -1.721487,-0.57383 -3.090342,-1.430597 -4.105468,-2.568359 -1.015125,-1.137763 -1.523438,-2.564783 -1.523438,-4.28125 0,-1.726256 0.508313,-3.156211 1.523438,-4.289063 1.015126,-1.132853 2.383981,-1.980915 4.105468,-2.544922 C 46.073051,32.281733 47.992602,32 50.111328,32 c 2.108615,0 4.021488,0.284633 5.738281,0.853516 1.153075,0.382214 2.149385,0.890534 2.988282,1.527343 0.409877,0.311002 0.78047,0.653647 1.115234,1.025391 0.681805,0.757172 1.135263,1.644203 1.361328,2.662109 0.319958,-0.521392 0.618124,-1.052349 0.892578,-1.59375 1.964164,-3.875351 2.313639,-8.170771 1.050781,-12.884765 -1.263217,-4.713996 -3.71256,-8.25072 -7.347656,-10.611328 C 54.717357,12.20395 53.445659,11.540917 52.091797,10.988281 49.319072,9.8567074 46.208157,9.1893425 42.759766,8.9882812 42.11818,8.9508774 41.472194,8.9284031 40.820312,8.9199219 Z M 22.804688,32 c 1.657604,0 3.187267,0.147162 4.589843,0.441406 1.402578,0.294246 2.607945,0.678586 3.613281,1.154297 1.005375,0.475712 1.732404,0.983987 2.183594,1.523438 l -3.765625,2.470703 c -0.549272,-0.598278 -1.383798,-1.075573 -2.501953,-1.433594 -1.118118,-0.357985 -2.475477,-0.537109 -4.074219,-0.537109 -0.784654,0 -1.577565,0.06103 -2.376953,0.183593 -0.799388,0.122639 -1.532255,0.330756 -2.199218,0.625 -0.666929,0.294246 -1.204303,0.706665 -1.611329,1.236328 -0.40706,0.529628 -0.609375,1.201538 -0.609375,2.015626 0,0.804263 0.202315,1.469424 0.609375,1.99414 0.407026,0.524753 0.9444,0.941056 1.611329,1.25 0.666963,0.30898 1.39983,0.526783 2.199218,0.654297 0.799388,0.127514 1.592299,0.191406 2.376953,0.191406 1.56931,0 2.929571,-0.195564 4.082032,-0.58789 1.15246,-0.392328 1.964746,-0.843499 2.435547,-1.353516 l 3.853515,2.457031 c -0.402149,0.431583 -1.109839,0.889287 -2.125,1.375 -1.015161,0.485355 -2.237912,0.894834 -3.669922,1.228516 -1.432008,0.333319 -2.973275,0.5 -4.621093,0.5 -1.441796,0 -2.85336,-0.138457 -4.236329,-0.417969 -1.382931,-0.279512 -2.633834,-0.723896 -3.751953,-1.332031 -1.118155,-0.608138 -2.007869,-1.401995 -2.669922,-2.382813 -0.662052,-0.980818 -0.99414,-2.173595 -0.99414,-3.576171 0,-1.422188 0.332088,-2.622661 0.99414,-3.603516 0.662053,-0.980818 1.551767,-1.770862 2.669922,-2.369141 1.118119,-0.598313 2.369022,-1.033008 3.751953,-1.302734 C 19.951328,32.134572 21.362892,32 22.804688,32 Z m 27.30664,3.677734 c -2.050114,0 -3.646459,0.355312 -4.789062,1.066407 -1.142604,0.711094 -1.714844,1.689877 -1.714844,2.935547 0,1.235846 0.57224,2.217532 1.714844,2.943359 1.142603,0.725792 2.738948,1.08789 4.789062,1.087891 2.049753,0 3.637466,-0.367901 4.765625,-1.103516 1.127798,-0.735614 1.693359,-1.711498 1.693359,-2.927734 0,-1.24567 -0.566364,-2.224453 -1.699218,-2.935547 -1.132853,-0.711095 -2.719763,-1.066407 -4.759766,-1.066407 z"
|
||||
></path>
|
||||
</SVGIcon>
|
||||
|
|
@ -1,11 +1,13 @@
|
|||
---
|
||||
import { ViewTransitions } from "astro:transitions";
|
||||
import { ENABLE_VIEW_TRANSITIONS } from "astro:env/client";
|
||||
import "../styles/base.css";
|
||||
import "../styles/fonts.css";
|
||||
import DarkModeScript from "../components/DarkModeScript.astro";
|
||||
import AgeRestrictedModal from "../components/AgeRestrictedModal.astro";
|
||||
import NavHeader from "../components/NavHeader.astro";
|
||||
import IconSun from "../components/icons/IconSun.astro";
|
||||
import IconMoon from "../components/icons/IconMoon.astro";
|
||||
import AgeRestrictedModal from "../components/AgeRestrictedModal.astro";
|
||||
|
||||
type Props = {
|
||||
pageTitle?: string;
|
||||
|
|
@ -44,6 +46,7 @@ const title = pageTitle ? `${pageTitle} | Bad Manners` : "Bad Manners";
|
|||
<slot name="head-description" />
|
||||
<meta property="og:url" content={Astro.url} />
|
||||
<meta content="/logo.webp" property="og:image" />
|
||||
{ENABLE_VIEW_TRANSITIONS ? <ViewTransitions /> : null}
|
||||
</head>
|
||||
<body>
|
||||
<div class="flex min-h-screen flex-col">
|
||||
|
|
@ -55,13 +58,13 @@ const title = pageTitle ? `${pageTitle} | Bad Manners` : "Bad Manners";
|
|||
</div>
|
||||
<div class="relative my-auto flex flex-col items-center justify-center px-3 py-8 sm:py-12 md:px-12 print:p-0">
|
||||
<main
|
||||
class="w-full max-w-5xl flex-shrink-0 flex-grow-0 justify-center rounded-xl bg-stone-50 px-4 pb-6 pt-4 text-center text-base font-light tracking-tight text-stone-700 sm:px-8 sm:pb-8 sm:pt-6 sm:text-lg dark:bg-zinc-800 dark:text-zinc-50 print:bg-transparent print:p-0"
|
||||
class="w-full max-w-5xl flex-shrink-0 flex-grow-0 justify-center rounded-xl bg-stone-50 px-4 pb-6 pt-4 text-center text-base font-normal tracking-tight text-stone-700 sm:px-8 sm:pb-8 sm:pt-6 sm:text-lg dark:bg-zinc-800 dark:text-zinc-50 print:bg-transparent print:p-0"
|
||||
>
|
||||
<NavHeader />
|
||||
<slot />
|
||||
</main>
|
||||
<footer
|
||||
class="sm:text-md flex flex-col items-center pt-9 text-sm font-normal tracking-wide text-black dark:text-white"
|
||||
class="sm:text-md flex flex-col items-center pt-9 text-sm font-medium tracking-wide text-black dark:text-white"
|
||||
>
|
||||
<div class="flex items-center">
|
||||
<span id="copyright"
|
||||
|
|
@ -80,8 +83,8 @@ const title = pageTitle ? `${pageTitle} | Bad Manners` : "Bad Manners";
|
|||
</div>
|
||||
<button
|
||||
data-dark-mode
|
||||
style={{display: "none"}}
|
||||
class="mt-2 print:hidden p-2 transition-colors hover:text-green-700 focus:text-green-700 motion-reduce:transition-none dark:hover:text-bm-300 dark:focus:text-bm-300"
|
||||
style={{ display: "none" }}
|
||||
class="mt-2 p-2 transition-colors hover:text-green-700 focus:text-green-700 motion-reduce:transition-none dark:hover:text-bm-300 dark:focus:text-bm-300 print:hidden"
|
||||
aria-labelledby="label-toggle-dark-mode"
|
||||
>
|
||||
<IconSun width="1.5rem" height="1.5rem" class="hidden dark:block" />
|
||||
|
|
|
|||
|
|
@ -4,11 +4,13 @@ import { APACHE_CONFIG } from "astro:env/server";
|
|||
const htaccess = `
|
||||
ErrorDocument 404 /404.html
|
||||
RedirectMatch 301 ^/tos(\/(index.html)?)?$ /terms_of_service/
|
||||
RedirectMatch 301 ^/contact(\/(index.html)?)?$ /
|
||||
Redirect 301 /@/aryion https://aryion.com/g4/user/BadManners
|
||||
Redirect 301 /@/eka https://aryion.com/g4/user/BadManners
|
||||
Redirect 301 /@/bluesky https://bsky.app/profile/badmanners.xyz
|
||||
Redirect 301 /@/bsky https://bsky.app/profile/badmanners.xyz
|
||||
Redirect 301 /@/codeberg https://codeberg.org/BadManners
|
||||
Redirect 301 /@/cohost https://cohost.org/BadManners
|
||||
Redirect 301 /@/fa https://www.furaffinity.net/user/badmanners
|
||||
Redirect 301 /@/furaffinity https://www.furaffinity.net/user/badmanners
|
||||
Redirect 301 /@/gallery https://gallery.badmanners.xyz
|
||||
|
|
|
|||
|
|
@ -10,19 +10,21 @@ import ImageSamStickerJuicebox from "../assets/images/sam_sticker_juicebox.webp"
|
|||
<article class="h-card" aria-labelledby="title-about-me">
|
||||
<h1 id="title-about-me" class="text-2xl sm:text-3xl">About me</h1>
|
||||
<section id="section-bad-manners">
|
||||
<p class="mb-4 mt-5 sm:mb-3 sm:mt-6">
|
||||
You can call me <b class="p-name">Bad Manners</b>, <b class="p-nickname">Manners</b>, <b class="p-nickname"
|
||||
><abbr>BM</abbr></b
|
||||
>, <b class="p-nickname">Bad</b>, <b class="p-nickname">Briefcase</b>... many choices to pick from! My pronouns
|
||||
are "<span class="p-pronoun">he/him</span>". The term "<em>bad manners</em>" comes from gaming, where it's used
|
||||
to refer to acting in a purposefully disrespectful and taunting manner towards other players, but I also chose
|
||||
this moniker as it has plenty of personal meanings attached to it.
|
||||
<p class="mb-4 mt-5 text-justify indent-6 sm:mb-3 sm:mt-6 sm:px-5 sm:indent-12">
|
||||
You can call me <b class="p-name font-semibold">Bad Manners</b>, <b class="p-nickname font-semibold">Manners</b
|
||||
>, <b class="p-nickname font-semibold"><abbr>BM</abbr></b>, <b class="p-nickname font-semibold">Bad</b>, <b
|
||||
class="p-nickname font-semibold">Briefcase</b
|
||||
>... many choices to pick from! My pronouns are <span class="p-pronoun font-medium">he/him</span>. The term "bad
|
||||
manners" comes from gaming, where it's used to refer to acting in a purposefully disrespectful and taunting
|
||||
manner towards other players, but I also chose this moniker as it has plenty of personal meanings attached to
|
||||
it.
|
||||
</p>
|
||||
</section>
|
||||
<section id="section-sam-brendan" class="h-card">
|
||||
<p class="my-4 sm:mb-3 sm:mt-6">
|
||||
You can also call me <b class="p-first-name">Sam</b>, which is my <span class="p-category">fursona</span>'s
|
||||
name. He is a <span class="p-note">mimic and maned wolf hybrid</span>, and you can learn more about him by
|
||||
<p class="my-4 text-justify indent-6 sm:mb-3 sm:px-5 sm:indent-12">
|
||||
You can also call me <b class="p-first-name font-semibold">Sam</b>, which is my <span class="p-category"
|
||||
>fursona</span
|
||||
>'s name. He is a <span class="p-note">mimic and maned wolf hybrid</span>, and you can learn more about him by
|
||||
clicking on him below!
|
||||
</p>
|
||||
<figure class="mt-4">
|
||||
|
|
@ -42,11 +44,11 @@ import ImageSamStickerJuicebox from "../assets/images/sam_sticker_juicebox.webp"
|
|||
<figcaption class="text-base">
|
||||
A sticker of Sam by
|
||||
<a
|
||||
class="text-link transition-colors motion-reduce:transition-none"
|
||||
class="h-card u-url text-link transition-colors motion-reduce:transition-none"
|
||||
href="https://olivecow.carrd.co/"
|
||||
target="_blank"
|
||||
>
|
||||
<span class="underline">OliveCow</span>
|
||||
<span class="p-name underline">OliveCow</span>
|
||||
<IconArrowUpRightFromSquare width="0.75rem" height="0.75rem" class="inline" />
|
||||
</a>.
|
||||
</figcaption>
|
||||
|
|
|
|||
|
|
@ -1,190 +0,0 @@
|
|||
---
|
||||
import BaseLayout from "../layouts/BaseLayout.astro";
|
||||
import IconArrowUpRightFromSquare from "../components/icons/IconArrowUpRightFromSquare.astro";
|
||||
import IconClone from "../components/icons/IconClone.astro";
|
||||
import IconEnvelope from "../components/icons/IconEnvelope.astro";
|
||||
import IconBluesky from "../components/icons/brands/IconBluesky.astro";
|
||||
import IconDiscord from "../components/icons/brands/IconDiscord.astro";
|
||||
import IconMastodon from "../components/icons/brands/IconMastodon.astro";
|
||||
import IconSignal from "../components/icons/brands/IconSignal.astro";
|
||||
import IconTelegram from "../components/icons/brands/IconTelegram.astro";
|
||||
---
|
||||
|
||||
<BaseLayout pageTitle="Contact">
|
||||
<meta slot="head-description" property="og:description" content="Where to find me." />
|
||||
<article aria-labelledby="title-contact">
|
||||
<h1 id="title-contact" class="text-2xl sm:text-3xl">Contact</h1>
|
||||
<section>
|
||||
<p class="mb-4 mt-5 sm:mb-3 sm:mt-6 sm:px-5 md:px-6">
|
||||
Feel free to reach out through my main socials below, or by
|
||||
<a href="/work" class="text-link underline transition-colors motion-reduce:transition-none"
|
||||
>messaging me on any of my galleries</a
|
||||
>, if you wanna talk about anything!
|
||||
</p>
|
||||
<ul class="h-card flex flex-col items-center">
|
||||
<li class="mb-2 w-max sm:mb-1">
|
||||
<button
|
||||
id="discord"
|
||||
class="text-link group mx-1 select-none transition-colors aria-disabled:cursor-default aria-disabled:select-text aria-disabled:text-stone-700 motion-reduce:transition-none dark:aria-disabled:text-zinc-50"
|
||||
aria-label="Copy my Discord username to clipboard"
|
||||
aria-disabled="true"
|
||||
>
|
||||
<IconDiscord width="1.75rem" height="1.75rem" class="mr-1 inline" />
|
||||
<span class="p-nickname underline group-aria-disabled:cursor-text group-aria-disabled:no-underline"
|
||||
>badmanners</span
|
||||
>
|
||||
<IconClone width="0.75rem" height="0.75rem" class="inline group-aria-disabled:hidden" />
|
||||
</button>
|
||||
</li>
|
||||
<li class="h-card mb-2 w-max sm:mb-1">
|
||||
<a
|
||||
class="u-url text-link mx-1 transition-colors motion-reduce:transition-none"
|
||||
href="https://t.me/bad_manners"
|
||||
target="_blank"
|
||||
aria-label="Add me on Telegram"
|
||||
rel="me"
|
||||
>
|
||||
<IconTelegram width="1.75rem" height="1.75rem" class="mr-1 inline" />
|
||||
<span class="p-nickname underline">@bad_manners</span>
|
||||
<IconArrowUpRightFromSquare width="0.75rem" height="0.75rem" class="inline" />
|
||||
</a>
|
||||
</li>
|
||||
<li class="h-card mb-2 w-max sm:mb-1">
|
||||
<a
|
||||
class="u-url text-link mx-1 transition-colors motion-reduce:transition-none"
|
||||
href="https://signal.me/#eu/ytt_rk0fFmAB2JAW-x2PbUiJyc_H3kYmfL_Pq4QNh5QIDsiFtjdFHaqFRs1D36tB"
|
||||
target="_blank"
|
||||
aria-label="Add me on Signal"
|
||||
rel="me"
|
||||
>
|
||||
<IconSignal width="1.75rem" height="1.75rem" class="mr-1 inline" />
|
||||
<span class="p-nickname underline">badmanners.10</span>
|
||||
<IconArrowUpRightFromSquare width="0.75rem" height="0.75rem" class="inline" />
|
||||
</a>
|
||||
</li>
|
||||
<li class="h-card mb-2 w-max sm:mb-1">
|
||||
<a
|
||||
class="u-url text-link mx-1 transition-colors motion-reduce:transition-none"
|
||||
href="https://meow.social/@BadManners"
|
||||
target="_blank"
|
||||
aria-label="Visit me on Mastodon"
|
||||
rel="me"
|
||||
>
|
||||
<IconMastodon width="1.75rem" height="1.75rem" class="mr-1 inline" />
|
||||
<span class="p-nickname underline">@BadManners@meow.social</span>
|
||||
<IconArrowUpRightFromSquare width="0.75rem" height="0.75rem" class="inline" />
|
||||
</a>
|
||||
</li>
|
||||
<li class="h-card mb-2 w-max sm:mb-1">
|
||||
<a
|
||||
class="u-url text-link mx-1 transition-colors motion-reduce:transition-none"
|
||||
href="https://bsky.app/profile/badmanners.xyz"
|
||||
target="_blank"
|
||||
aria-label="Visit me on Bluesky"
|
||||
rel="me"
|
||||
>
|
||||
<IconBluesky width="1.75rem" height="1.75rem" class="mr-1 inline" />
|
||||
<span class="p-nickname underline">@badmanners.xyz</span>
|
||||
<IconArrowUpRightFromSquare width="0.75rem" height="0.75rem" class="inline" />
|
||||
</a>
|
||||
</li>
|
||||
<li class="mb-2 w-max sm:mb-1">
|
||||
<button
|
||||
id="email"
|
||||
class="text-link group mx-1 transition-colors aria-disabled:cursor-not-allowed aria-disabled:text-stone-700 motion-reduce:transition-none dark:aria-disabled:text-zinc-50"
|
||||
aria-label="Copy my e-mail address to clipboard"
|
||||
aria-disabled="true"
|
||||
>
|
||||
<IconEnvelope width="1.75rem" height="1.75rem" class="mr-1 inline" />
|
||||
<span
|
||||
class="underline group-aria-disabled:no-underline"
|
||||
data-user="em"
|
||||
data-website="zyx.srennamdab"
|
||||
aria-label="Obfuscated e-mail address"></span>
|
||||
<IconClone width="0.75rem" height="0.75rem" class="inline group-aria-disabled:hidden" />
|
||||
</button>
|
||||
</li>
|
||||
</ul>
|
||||
</section>
|
||||
</article>
|
||||
</BaseLayout>
|
||||
|
||||
<style>
|
||||
#email span:before {
|
||||
content: attr(data-website) "\0040" attr(data-user);
|
||||
unicode-bidi: bidi-override;
|
||||
direction: rtl;
|
||||
}
|
||||
</style>
|
||||
|
||||
<script>
|
||||
import tippy, { hideAll } from "tippy.js";
|
||||
import "tippy.js/dist/tippy.css";
|
||||
|
||||
(function () {
|
||||
const discordButton = document.querySelector<HTMLElementTagNameMap["button"]>("button#discord")!;
|
||||
const discordTooltip = tippy(discordButton, {
|
||||
content: "Username copied to clipboard!",
|
||||
trigger: "manual",
|
||||
theme: "bm",
|
||||
});
|
||||
const emailButton = document.querySelector<HTMLElementTagNameMap["button"]>("button#email")!;
|
||||
const emailTooltip = tippy(emailButton, {
|
||||
content: "E-mail address copied to clipboard!",
|
||||
trigger: "manual",
|
||||
theme: "bm",
|
||||
});
|
||||
let tooltipTimeout: any = null;
|
||||
|
||||
discordButton.addEventListener("click", (ev) => {
|
||||
ev.preventDefault();
|
||||
tooltipTimeout && clearTimeout(tooltipTimeout);
|
||||
hideAll();
|
||||
const text = discordButton.querySelector("span")!.innerText;
|
||||
navigator.clipboard
|
||||
.writeText(text)
|
||||
.then(() => {
|
||||
discordTooltip.setContent("Username copied to clipboard!");
|
||||
discordTooltip.show();
|
||||
tooltipTimeout = setTimeout(() => {
|
||||
discordTooltip.hide();
|
||||
}, 2000);
|
||||
})
|
||||
.catch((e) => {
|
||||
console.error("Unable to copy Discord username to clipboard", e);
|
||||
discordTooltip.setContent("Unable to copy username!");
|
||||
discordTooltip.show();
|
||||
tooltipTimeout = setTimeout(() => {
|
||||
discordTooltip.hide();
|
||||
}, 2000);
|
||||
});
|
||||
});
|
||||
discordButton.setAttribute("aria-disabled", "false");
|
||||
|
||||
emailButton.addEventListener("click", (ev) => {
|
||||
ev.preventDefault();
|
||||
tooltipTimeout && clearTimeout(tooltipTimeout);
|
||||
hideAll();
|
||||
const emailData = emailButton.querySelector("span")!;
|
||||
const text = `${emailData.dataset.website!}@${emailData.dataset.user!}`.split("").reverse().join("");
|
||||
navigator.clipboard
|
||||
.writeText(text)
|
||||
.then(() => {
|
||||
emailTooltip.setContent("E-mail address copied to clipboard!");
|
||||
emailTooltip.show();
|
||||
tooltipTimeout = setTimeout(() => {
|
||||
emailTooltip.hide();
|
||||
}, 2000);
|
||||
})
|
||||
.catch((e) => {
|
||||
console.error("Unable to copy e-mail address to clipboard", e);
|
||||
emailTooltip.setContent("Unable to copy e-mail address!");
|
||||
emailTooltip.show();
|
||||
tooltipTimeout = setTimeout(() => {
|
||||
emailTooltip.hide();
|
||||
}, 2000);
|
||||
});
|
||||
});
|
||||
emailButton.setAttribute("aria-disabled", "false");
|
||||
})();
|
||||
</script>
|
||||
|
|
@ -1,12 +1,16 @@
|
|||
---
|
||||
import BaseLayout from "../layouts/BaseLayout.astro";
|
||||
import IconEnvelope from "../components/icons/IconEnvelope.astro";
|
||||
import IconBluesky from "../components/icons/brands/IconBluesky.astro";
|
||||
import IconCodeberg from "../components/icons/brands/IconCodeberg.astro";
|
||||
import IconCohost from "../components/icons/brands/IconCohost.astro";
|
||||
import IconDiscord from "../components/icons/brands/IconDiscord.astro";
|
||||
import IconEkasPortal from "../components/icons/brands/IconEkasPortal.astro";
|
||||
import IconFurAffinity from "../components/icons/brands/IconFurAffinity.astro";
|
||||
import IconGitHub from "../components/icons/brands/IconGitHub.astro";
|
||||
import IconGitLab from "../components/icons/brands/IconGitLab.astro";
|
||||
import IconInkbunny from "../components/icons/brands/IconInkbunny.astro";
|
||||
import IconItaku from "../components/icons/brands/IconItaku.astro";
|
||||
import IconItchIO from "../components/icons/brands/IconItchIO.astro";
|
||||
import IconKeybase from "../components/icons/brands/IconKeybase.astro";
|
||||
import IconMastodon from "../components/icons/brands/IconMastodon.astro";
|
||||
|
|
@ -20,8 +24,6 @@ import IconTelegram from "../components/icons/brands/IconTelegram.astro";
|
|||
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 IconEllipsis from "../components/icons/IconEllipsis.astro";
|
||||
import IconItaku from "../components/icons/brands/IconItaku.astro";
|
||||
---
|
||||
|
||||
<BaseLayout>
|
||||
|
|
@ -30,7 +32,7 @@ import IconItaku from "../components/icons/brands/IconItaku.astro";
|
|||
property="og:description"
|
||||
content="Safe vore enthusiast, mimic hybrid, and occasional writer."
|
||||
/>
|
||||
<article class="h-card" aria-labelledby="title-home">
|
||||
<article class="h-card" aria-label="Homepage of Bad Manners">
|
||||
<h1 id="title-home" class="pb-4 text-3xl tracking-tight sm:text-5xl">
|
||||
Hi, I'm <span class="p-name">Bad Manners</span>!
|
||||
</h1>
|
||||
|
|
@ -47,9 +49,25 @@ import IconItaku from "../components/icons/brands/IconItaku.astro";
|
|||
class="grid grid-cols-3 gap-x-4 gap-y-5 px-4 pt-8 sm:grid-cols-4 sm:px-20 md:px-32"
|
||||
aria-label="Links"
|
||||
>
|
||||
<li>
|
||||
<li id="e-mail">
|
||||
<a
|
||||
class="u-url text-link group p-2 transition-colors motion-reduce:transition-none"
|
||||
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"
|
||||
>
|
||||
<IconEnvelope
|
||||
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="p-category sr-only">E-mail address</p>
|
||||
</a>
|
||||
</li>
|
||||
<li id="bluesky">
|
||||
<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"
|
||||
|
|
@ -60,12 +78,16 @@ import IconItaku from "../components/icons/brands/IconItaku.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"
|
||||
/>
|
||||
<span class="p-nickname sr-only">@badmanners.xyz on Bluesky</span>
|
||||
<p class="sr-only">
|
||||
<span class="p-nickname">@badmanners.xyz</span>
|
||||
on
|
||||
<span class="p-category">Bluesky</span>
|
||||
</p>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<li id="codeberg">
|
||||
<a
|
||||
class="u-url text-link group p-2 transition-colors motion-reduce:transition-none"
|
||||
class="u-url text-link group block w-full transition-colors motion-reduce:transition-none"
|
||||
href="https://codeberg.org/BadManners"
|
||||
target="_blank"
|
||||
rel="me"
|
||||
|
|
@ -76,12 +98,55 @@ import IconItaku from "../components/icons/brands/IconItaku.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"
|
||||
/>
|
||||
<span class="p-nickname sr-only">BadManners on Codeberg</span>
|
||||
<p class="sr-only">
|
||||
<span class="p-nickname">BadManners</span>
|
||||
on
|
||||
<span class="p-category">Codeberg</span>
|
||||
</p>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<li id="cohost">
|
||||
<a
|
||||
class="u-url text-link group p-2 transition-colors motion-reduce:transition-none"
|
||||
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"
|
||||
>
|
||||
<IconCohost
|
||||
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">
|
||||
<span class="p-nickname">BadManners</span>
|
||||
on
|
||||
<span class="p-category">Cohost</span>
|
||||
</p>
|
||||
</a>
|
||||
</li>
|
||||
<li id="discord">
|
||||
<button
|
||||
class="text-link group block w-full transition-colors motion-reduce:transition-none"
|
||||
aria-label="Discord"
|
||||
data-username="badmanners"
|
||||
aria-disabled="true"
|
||||
>
|
||||
<IconDiscord
|
||||
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">
|
||||
<span class="p-nickname">badmanners</span>
|
||||
on
|
||||
<span class="p-category">Discord</span>
|
||||
</p>
|
||||
</button>
|
||||
</li>
|
||||
<li id="eka-s-portal">
|
||||
<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"
|
||||
|
|
@ -92,12 +157,16 @@ import IconItaku from "../components/icons/brands/IconItaku.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"
|
||||
/>
|
||||
<span class="p-nickname sr-only">BadManners on Eka's Portal</span>
|
||||
<p class="sr-only">
|
||||
<span class="p-nickname">BadManners</span>
|
||||
on
|
||||
<span class="p-category">Eka's Portal</span>
|
||||
</p>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<li id="fur-affinity">
|
||||
<a
|
||||
class="u-url text-link group p-2 transition-colors motion-reduce:transition-none"
|
||||
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"
|
||||
|
|
@ -108,12 +177,16 @@ import IconItaku from "../components/icons/brands/IconItaku.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"
|
||||
/>
|
||||
<span class="p-nickname sr-only">BadManners on Fur Affinity</span>
|
||||
<p class="sr-only">
|
||||
<span class="p-nickname">BadManners</span>
|
||||
on
|
||||
<span class="p-category">Fur Affinity</span>
|
||||
</p>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<li id="github">
|
||||
<a
|
||||
class="u-url text-link group p-2 transition-colors motion-reduce:transition-none"
|
||||
class="u-url text-link group block w-full transition-colors motion-reduce:transition-none"
|
||||
href="https://github.com/BadMannersXYZ"
|
||||
target="_blank"
|
||||
rel="me"
|
||||
|
|
@ -124,12 +197,16 @@ import IconItaku from "../components/icons/brands/IconItaku.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"
|
||||
/>
|
||||
<span class="p-nickname sr-only">BadMannersXYZ on GitHub</span>
|
||||
<p class="sr-only">
|
||||
<span class="p-nickname">BadMannersXYZ</span>
|
||||
on
|
||||
<span class="p-category">GitHub</span>
|
||||
</p>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<li id="gitlab">
|
||||
<a
|
||||
class="u-url text-link group p-2 transition-colors motion-reduce:transition-none"
|
||||
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"
|
||||
|
|
@ -140,12 +217,16 @@ import IconItaku from "../components/icons/brands/IconItaku.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"
|
||||
/>
|
||||
<span class="p-nickname sr-only">Bad_Manners on GitLab</span>
|
||||
<p class="sr-only">
|
||||
<span class="p-nickname">Bad_Manners</span>
|
||||
on
|
||||
<span class="p-category">GitLab</span>
|
||||
</p>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<li id="inkbunny">
|
||||
<a
|
||||
class="u-url text-link group p-2 transition-colors motion-reduce:transition-none"
|
||||
class="u-url text-link group block w-full transition-colors motion-reduce:transition-none"
|
||||
href="https://inkbunny.net/BadManners"
|
||||
target="_blank"
|
||||
rel="me"
|
||||
|
|
@ -156,12 +237,16 @@ import IconItaku from "../components/icons/brands/IconItaku.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"
|
||||
/>
|
||||
<span class="p-nickname sr-only">BadManners on Inkbunny</span>
|
||||
<p class="sr-only">
|
||||
<span class="p-nickname">BadManners</span>
|
||||
on
|
||||
<span class="p-category">Inkbunny</span>
|
||||
</p>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<li id="itaku">
|
||||
<a
|
||||
class="u-url text-link group p-2 transition-colors motion-reduce:transition-none"
|
||||
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"
|
||||
|
|
@ -172,12 +257,16 @@ import IconItaku from "../components/icons/brands/IconItaku.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"
|
||||
/>
|
||||
<span class="p-nickname sr-only">badmanners on Itaku</span>
|
||||
<p class="sr-only">
|
||||
<span class="p-nickname">badmanners</span>
|
||||
on
|
||||
<span class="p-category">Itaku</span>
|
||||
</p>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<li id="itch-io">
|
||||
<a
|
||||
class="u-url text-link group p-2 transition-colors motion-reduce:transition-none"
|
||||
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"
|
||||
|
|
@ -188,12 +277,16 @@ import IconItaku from "../components/icons/brands/IconItaku.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"
|
||||
/>
|
||||
<span class="p-nickname sr-only">Bad Manners on Itch.io</span>
|
||||
<p class="sr-only">
|
||||
<span class="p-nickname">Bad Manners</span>
|
||||
on
|
||||
<span class="p-category">Itch.io</span>
|
||||
</p>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<li id="keybase">
|
||||
<a
|
||||
class="u-url text-link group p-2 transition-colors motion-reduce:transition-none"
|
||||
class="u-url text-link group block w-full transition-colors motion-reduce:transition-none"
|
||||
href="https://keybase.io/badmanners"
|
||||
target="_blank"
|
||||
rel="me"
|
||||
|
|
@ -204,12 +297,16 @@ import IconItaku from "../components/icons/brands/IconItaku.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"
|
||||
/>
|
||||
<span class="p-nickname sr-only">badmanners on Keybase</span>
|
||||
<p class="sr-only">
|
||||
<span class="p-nickname">badmanners</span>
|
||||
on
|
||||
<span class="p-category">Keybase</span>
|
||||
</p>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<li id="mastodon">
|
||||
<a
|
||||
class="u-url text-link group p-2 transition-colors motion-reduce:transition-none"
|
||||
class="u-url text-link group block w-full transition-colors motion-reduce:transition-none"
|
||||
href="https://meow.social/@BadManners"
|
||||
target="_blank"
|
||||
rel="me"
|
||||
|
|
@ -220,12 +317,16 @@ import IconItaku from "../components/icons/brands/IconItaku.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"
|
||||
/>
|
||||
<span class="p-nickname sr-only">@BadManners@meow.social on Mastodon</span>
|
||||
<p class="sr-only">
|
||||
<span class="p-nickname">@BadManners@meow.social</span>
|
||||
on
|
||||
<span class="p-category">Mastodon</span>
|
||||
</p>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<li id="neocities">
|
||||
<a
|
||||
class="u-url text-link group p-2 transition-colors motion-reduce:transition-none"
|
||||
class="u-url text-link group block w-full transition-colors motion-reduce:transition-none"
|
||||
href="https://badmanners.neocities.org/"
|
||||
target="_blank"
|
||||
rel="me"
|
||||
|
|
@ -236,12 +337,16 @@ import IconItaku from "../components/icons/brands/IconItaku.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"
|
||||
/>
|
||||
<span class="p-nickname sr-only">badmanners.neocities.org on Neocities</span>
|
||||
<p class="sr-only">
|
||||
<span class="p-nickname">badmanners.neocities.org</span>
|
||||
on
|
||||
<span class="p-category">Neocities</span>
|
||||
</p>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<li id="picarto">
|
||||
<a
|
||||
class="u-url text-link group p-2 transition-colors motion-reduce:transition-none"
|
||||
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"
|
||||
|
|
@ -252,12 +357,16 @@ import IconItaku from "../components/icons/brands/IconItaku.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"
|
||||
/>
|
||||
<span class="p-nickname sr-only">BadManners on Picarto</span>
|
||||
<p class="sr-only">
|
||||
<span class="p-nickname">BadManners</span>
|
||||
on
|
||||
<span class="p-category">Picarto</span>
|
||||
</p>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<li id="signal">
|
||||
<a
|
||||
class="u-url text-link group p-2 transition-colors motion-reduce:transition-none"
|
||||
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"
|
||||
|
|
@ -268,12 +377,16 @@ import IconItaku from "../components/icons/brands/IconItaku.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"
|
||||
/>
|
||||
<span class="p-nickname sr-only">badmanners.10 on Signal</span>
|
||||
<p class="sr-only">
|
||||
<span class="p-nickname">badmanners.10</span>
|
||||
on
|
||||
<span class="p-category">Signal</span>
|
||||
</p>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<li id="sofurry">
|
||||
<a
|
||||
class="u-url text-link group p-2 transition-colors motion-reduce:transition-none"
|
||||
class="u-url text-link group block w-full transition-colors motion-reduce:transition-none"
|
||||
href="https://bad-manners.sofurry.com/"
|
||||
target="_blank"
|
||||
rel="me"
|
||||
|
|
@ -284,12 +397,16 @@ import IconItaku from "../components/icons/brands/IconItaku.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"
|
||||
/>
|
||||
<span class="p-nickname sr-only">Bad Manners on SoFurry</span>
|
||||
<p class="sr-only">
|
||||
<span class="p-nickname">Bad Manners</span>
|
||||
on
|
||||
<span class="p-category">SoFurry</span>
|
||||
</p>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<li id="steam">
|
||||
<a
|
||||
class="u-url text-link group p-2 transition-colors motion-reduce:transition-none"
|
||||
class="u-url text-link group block w-full transition-colors motion-reduce:transition-none"
|
||||
href="https://steamcommunity.com/id/badmanners_/"
|
||||
target="_blank"
|
||||
rel="me"
|
||||
|
|
@ -300,12 +417,16 @@ import IconItaku from "../components/icons/brands/IconItaku.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"
|
||||
/>
|
||||
<span class="p-nickname sr-only">badmanners_ on Steam</span>
|
||||
<p class="sr-only">
|
||||
<span class="p-nickname">badmanners_</span>
|
||||
on
|
||||
<span class="p-category">Steam</span>
|
||||
</p>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<li id="subscribestar">
|
||||
<a
|
||||
class="u-url text-link group p-2 transition-colors motion-reduce:transition-none"
|
||||
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"
|
||||
|
|
@ -316,12 +437,16 @@ import IconItaku from "../components/icons/brands/IconItaku.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"
|
||||
/>
|
||||
<span class="p-nickname sr-only">Bad Manners on SubscribeStar</span>
|
||||
<p class="sr-only">
|
||||
<span class="p-nickname">Bad Manners</span>
|
||||
on
|
||||
<span class="p-category">SubscribeStar</span>
|
||||
</p>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<li id="telegram">
|
||||
<a
|
||||
class="u-url text-link group p-2 transition-colors motion-reduce:transition-none"
|
||||
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"
|
||||
|
|
@ -332,12 +457,16 @@ import IconItaku from "../components/icons/brands/IconItaku.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"
|
||||
/>
|
||||
<span class="p-nickname sr-only">@bad_manners on Telegram</span>
|
||||
<p class="sr-only">
|
||||
<span class="p-nickname">@bad_manners</span>
|
||||
on
|
||||
<span class="p-category">Telegram</span>
|
||||
</p>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<li id="twitch">
|
||||
<a
|
||||
class="u-url text-link group p-2 transition-colors motion-reduce:transition-none"
|
||||
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"
|
||||
|
|
@ -348,12 +477,16 @@ import IconItaku from "../components/icons/brands/IconItaku.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"
|
||||
/>
|
||||
<span class="p-nickname sr-only">bad__manners on Twitch</span>
|
||||
<p class="sr-only">
|
||||
<span class="p-nickname">bad__manners</span>
|
||||
on
|
||||
<span class="p-category">Twitch</span>
|
||||
</p>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<li id="weasyl">
|
||||
<a
|
||||
class="u-url text-link group p-2 transition-colors motion-reduce:transition-none"
|
||||
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"
|
||||
|
|
@ -364,12 +497,16 @@ import IconItaku from "../components/icons/brands/IconItaku.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"
|
||||
/>
|
||||
<span class="p-nickname sr-only">BadManners on Weasyl</span>
|
||||
<p class="sr-only">
|
||||
<span class="p-nickname">BadManners</span>
|
||||
on
|
||||
<span class="p-category">Weasyl</span>
|
||||
</p>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<li id="x">
|
||||
<a
|
||||
class="u-url text-link group p-2 transition-colors motion-reduce:transition-none"
|
||||
class="u-url text-link group block w-full transition-colors motion-reduce:transition-none"
|
||||
href="https://x.com/BadManners__"
|
||||
target="_blank"
|
||||
rel="me"
|
||||
|
|
@ -380,20 +517,11 @@ import IconItaku from "../components/icons/brands/IconItaku.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"
|
||||
/>
|
||||
<span class="p-nickname sr-only">@BadManners__ on X</span>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a
|
||||
class="u-url text-link group p-2 transition-colors motion-reduce:transition-none"
|
||||
href="/contact"
|
||||
aria-label="More socials..."
|
||||
>
|
||||
<IconEllipsis
|
||||
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">
|
||||
<span class="p-nickname">@BadManners__</span>
|
||||
on
|
||||
<span class="p-category">X</span>
|
||||
</p>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
|
@ -402,13 +530,99 @@ import IconItaku from "../components/icons/brands/IconItaku.astro";
|
|||
</BaseLayout>
|
||||
|
||||
<script>
|
||||
import tippy from "tippy.js";
|
||||
import { ENABLE_VIEW_TRANSITIONS } from "astro:env/client";
|
||||
import tippy, { hideAll } from "tippy.js";
|
||||
import "tippy.js/dist/tippy.css";
|
||||
|
||||
(function () {
|
||||
tippy(document.querySelectorAll("#links a"), {
|
||||
type TimeoutTag = ReturnType<typeof setTimeout> | null;
|
||||
|
||||
const initIndexIcons = () => {
|
||||
const indexLinks = document.querySelector<HTMLElementTagNameMap["ul"]>("ul#links");
|
||||
if (!indexLinks) {
|
||||
return;
|
||||
}
|
||||
const emailAnchor = indexLinks.querySelector<HTMLElementTagNameMap["a"]>("#links li#e-mail a");
|
||||
const usernameButtons = indexLinks.querySelectorAll<HTMLElementTagNameMap["button"]>(
|
||||
"#links li button[data-username]",
|
||||
);
|
||||
if (!emailAnchor) {
|
||||
console.error("Missing e-mail anchor in #links list.");
|
||||
return;
|
||||
}
|
||||
if (!usernameButtons.length) {
|
||||
console.error("Missing username buttons in #links list.");
|
||||
return;
|
||||
}
|
||||
|
||||
// Instantiate hover tooltips
|
||||
tippy("#links li button, #links li a", {
|
||||
content: (el) => el.getAttribute("aria-label")!,
|
||||
theme: "bm",
|
||||
});
|
||||
})();
|
||||
|
||||
// Add clipboard copy logic + manual tooltips to e-mail anchor and username buttons
|
||||
let tooltipTimeoutTag: TimeoutTag = null;
|
||||
const emailTooltip = tippy(emailAnchor, {
|
||||
content: "E-mail address copied to clipboard!",
|
||||
trigger: "manual",
|
||||
theme: "bm",
|
||||
});
|
||||
emailAnchor.addEventListener("click", (ev) => {
|
||||
ev.preventDefault();
|
||||
tooltipTimeoutTag && clearTimeout(tooltipTimeoutTag);
|
||||
hideAll();
|
||||
navigator.clipboard
|
||||
.writeText(emailAnchor.getAttribute("aria-label")!)
|
||||
.then(() => {
|
||||
emailTooltip.setContent("E-mail address copied to clipboard!");
|
||||
emailTooltip.show();
|
||||
})
|
||||
.catch((e) => {
|
||||
console.error("Unable to copy e-mail address to clipboard.", e);
|
||||
emailTooltip.setContent("Unable to copy e-mail address!");
|
||||
emailTooltip.show();
|
||||
});
|
||||
});
|
||||
usernameButtons.forEach((button) => {
|
||||
const label = button.getAttribute("aria-label");
|
||||
if (!label) {
|
||||
console.warn("Missing aria-label for button, ignoring...", button);
|
||||
return;
|
||||
}
|
||||
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} 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(`Unable to copy ${label} username to clipboard.`, e);
|
||||
buttonTooltip.setContent(`Unable to copy ${label} username!`);
|
||||
buttonTooltip.show();
|
||||
});
|
||||
});
|
||||
});
|
||||
};
|
||||
if (ENABLE_VIEW_TRANSITIONS) {
|
||||
document.addEventListener("astro:page-load", initIndexIcons);
|
||||
} else {
|
||||
initIndexIcons();
|
||||
}
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -11,10 +11,9 @@ import ImageSamRefsheet from "../assets/images/sam_refsheet.webp";
|
|||
<article class="h-card" aria-labelledby="title-sam-brendan">
|
||||
<h1 id="title-sam-brendan" class="p-name text-2xl sm:text-3xl">Sam Brendan</h1>
|
||||
<section>
|
||||
<p class="my-4 text-justify sm:my-6 sm:px-5 md:px-12">
|
||||
<b><span class="p-given-name">Sam</span> <span class="p-family-name">Brendan</span></b> (or simply <b
|
||||
class="p-nickname">Sam</b
|
||||
>), also going by <b class="p-nickname">Bad Manners</b>, is a <span class="p-note"
|
||||
<p class="my-4 text-justify sm:my-6 sm:px-5">
|
||||
<b class="font-semibold"><span class="p-given-name">Sam</span> <span class="p-family-name">Brendan</span></b> (or
|
||||
simply Sam), also going by <b class="p-nickname font-semibold">Bad Manners</b>, is a <span class="p-note"
|
||||
>mimic x maned wolf hybrid</span
|
||||
>. The main color of his fur is lime green, with light teal and white details. His most noticeable feature,
|
||||
however, is the metal briefcase that he has in lieu of a face – the mimic portion of his body.
|
||||
|
|
@ -39,16 +38,16 @@ import ImageSamRefsheet from "../assets/images/sam_refsheet.webp";
|
|||
<figcaption class="text-base">
|
||||
A reference sheet of Sam Brendan, by
|
||||
<a
|
||||
class="text-link transition-colors motion-reduce:transition-none"
|
||||
class="h-card u-url text-link transition-colors motion-reduce:transition-none"
|
||||
href="https://linktr.ee/Rimmi1357"
|
||||
target="_blank"
|
||||
>
|
||||
<span class="underline">Rimmi</span>
|
||||
<span class="p-name underline">Rimmi</span>
|
||||
<IconArrowUpRightFromSquare width="0.75rem" height="0.75rem" class="inline" /></a
|
||||
>. Click to view a high quality version.
|
||||
</figcaption>
|
||||
</figure>
|
||||
<p class="mt-3 text-justify indent-6 sm:mt-2 sm:px-5 sm:indent-12 md:px-12">
|
||||
<p class="mt-3 text-justify indent-6 sm:mt-2 sm:px-5 sm:indent-12">
|
||||
He has big, pointy, forward-facing ears, with big tufts in a light teal-to-white gradient coming out from the
|
||||
inside. The rest of his head is different from a regular maned wolf's, however. Everything from the top of his
|
||||
forehead down to the front of his neck is replaced by a metal briefcase ₋ including his eyes and snout –
|
||||
|
|
@ -57,12 +56,12 @@ import ImageSamRefsheet from "../assets/images/sam_refsheet.webp";
|
|||
– all three clamp down towards the front. There is no discernible unlocking mechanism for the latches. On
|
||||
the flat sides, the briefcase has several thin ridges across the width.
|
||||
</p>
|
||||
<p class="mt-3 text-justify indent-6 sm:mt-2 sm:px-5 sm:indent-12 md:px-12">
|
||||
<p class="mt-3 text-justify indent-6 sm:mt-2 sm:px-5 sm:indent-12">
|
||||
His mimic half can split in half longitudinally to reveal his green maw, with irregular and crooked white fangs,
|
||||
muscular buccinators on the sides, and a long prehensile and sticky tongue that is pastel yellow at the tip. It
|
||||
is connected to his lime-green digestive system.
|
||||
</p>
|
||||
<p class="mb-5 mt-3 text-justify indent-6 sm:mb-4 sm:mt-2 sm:px-5 sm:indent-12 md:px-12">
|
||||
<p class="mb-5 mt-3 text-justify indent-6 sm:mb-4 sm:mt-2 sm:px-5 sm:indent-12">
|
||||
Sam's body is slim, and his claws are short and white. His extremities are also white (instead of dark like most
|
||||
maned wolves). His upper paws are similar to hands, his digitigrade feet have lime green pads, and his fluffy
|
||||
tail is medium in size. These limbs connect to the lime green on his torso with a light teal gradient. The
|
||||
|
|
@ -91,30 +90,30 @@ import ImageSamRefsheet from "../assets/images/sam_refsheet.webp";
|
|||
<figcaption class="text-base">
|
||||
A set of stickers featuring Sam Brendan, by
|
||||
<a
|
||||
class="text-link transition-colors motion-reduce:transition-none"
|
||||
class="h-card u-url text-link transition-colors motion-reduce:transition-none"
|
||||
href="https://olivecow.carrd.co/"
|
||||
target="_blank"
|
||||
>
|
||||
<span class="underline">OliveCow</span>
|
||||
<span class="p-name underline">OliveCow</span>
|
||||
<IconArrowUpRightFromSquare width="0.75rem" height="0.75rem" class="inline" /></a
|
||||
>. Click to view a high quality version.
|
||||
</figcaption>
|
||||
</figure>
|
||||
<p class="mt-3 text-justify indent-6 sm:mt-2 sm:px-5 sm:indent-12 md:px-12">
|
||||
<p class="mt-3 text-justify indent-6 sm:mt-2 sm:px-5 sm:indent-12">
|
||||
Sam is normally solitary and anxious but friendly and extremely curious, with a particular interest in sciences.
|
||||
Sometimes introverted and shy, sometimes loud and active, he's quite prone to mood swings, although he tries to
|
||||
be reasonable and act on good intentions and manners whenever possible. He is quite fond of anagrams and
|
||||
wordplay. His main weaknesses are ear scritches and constantly focusing on others' approval. His main strength
|
||||
is finding humor in little things.
|
||||
</p>
|
||||
<p class="mt-3 text-justify indent-6 sm:mt-2 sm:px-5 sm:indent-12 md:px-12">
|
||||
<p class="mt-3 text-justify indent-6 sm:mt-2 sm:px-5 sm:indent-12">
|
||||
Due to his inability to display facial expressions, he usually resorts to stereotypical conveyances of emotions
|
||||
by sticking adhesive accessories on the briefcase. For this purpose, he can make use of googly eyes (his
|
||||
favorite accessories), removable paint and powder, stickers (e.g. to simulate smiles or expressions), and more.
|
||||
He dislikes being nicknamed Briefcase or anything along those lines but is fine being called by either of his
|
||||
species. It's very rare for him to ever open his case.
|
||||
</p>
|
||||
<p class="mb-5 mt-3 text-justify indent-6 sm:mb-4 sm:mt-2 sm:px-5 sm:indent-12 md:px-12">
|
||||
<p class="mb-5 mt-3 text-justify indent-6 sm:mb-4 sm:mt-2 sm:px-5 sm:indent-12">
|
||||
He's quite self-conscious about his mimic maw and normally avoids showing it in public. These factors lead to
|
||||
him usually eating alone, as well as being confused and flustered by people who seem keenly interested in his
|
||||
maw. However, in specific moods (such as vorish ones), he has no qualms about displaying and using his maw. He
|
||||
|
|
@ -124,7 +123,7 @@ import ImageSamRefsheet from "../assets/images/sam_refsheet.webp";
|
|||
</section>
|
||||
<section aria-labelledby="title-abilities">
|
||||
<h2 id="title-abilities" class="my-4 text-lg sm:my-6 sm:text-2xl">Abilities</h2>
|
||||
<ul class="mb-5 text-justify sm:mb-4 sm:px-5 md:px-12">
|
||||
<ul class="mb-5 text-justify sm:mb-4 sm:px-5">
|
||||
<li class="mx-7 mb-1 list-disc indent-0 sm:mx-10">
|
||||
Mimicking voices or simple sounds, and speak without moving his mouth.
|
||||
</li>
|
||||
|
|
@ -147,36 +146,38 @@ import ImageSamRefsheet from "../assets/images/sam_refsheet.webp";
|
|||
</section>
|
||||
<section aria-labelledby="title-sensorial-report">
|
||||
<h2 id="title-sensorial-report" class="my-4 text-lg sm:my-6 sm:text-2xl">Sensorial report</h2>
|
||||
<p class="mb-5 mt-3 text-justify indent-6 sm:mb-4 sm:mt-2 sm:px-5 sm:indent-12 md:px-12">
|
||||
<p class="mb-5 mt-3 text-justify indent-6 sm:mb-4 sm:mt-2 sm:px-5 sm:indent-12">
|
||||
His mimic parts (henceforth referred to as 'face') are mostly organic, but still contain traces of metallic
|
||||
elements, making non-invasive examinations such as X-ray and MRI difficult. However, stimulation through short
|
||||
electrical impulses at the junction between his head and his face results in messages reaching the brain,
|
||||
indicating that there is a rich nervous network through the seam. The following data has been collected based on
|
||||
empirical observations and Sam's self-reporting.
|
||||
</p>
|
||||
<ul class="mb-5 mt-3 text-justify sm:mb-4 sm:mt-2 sm:px-5 md:px-12">
|
||||
<ul class="mb-5 mt-3 text-justify sm:mb-4 sm:mt-2 sm:px-5">
|
||||
<li class="mx-7 mb-1 list-disc indent-0 sm:mx-10">
|
||||
<b>Sense of sight:</b> Mimics' skins are photosensitive, and Sam's face similarly has almost 360° of vision, with
|
||||
minor loss of focus outside the center. This ability is restricted by perceiving the world as black and white,
|
||||
therefore minimizing sensory overload, but he's able to focus on a single object to perceive trichromatic hues.
|
||||
<b class="font-semibold">Sense of sight:</b> Mimics' skins are photosensitive, and Sam's face similarly has almost
|
||||
360° of vision, with minor loss of focus outside the center. This ability is restricted by perceiving the world
|
||||
as black and white, therefore minimizing sensory overload, but he's able to focus on a single object to perceive
|
||||
trichromatic hues.
|
||||
</li>
|
||||
<li class="mx-7 mb-1 list-disc indent-0 sm:mx-10">
|
||||
<b>Sense of hearing:</b> Excellent hearing, unaffected by the obstruction from his face. Normal sense of balance.
|
||||
<b class="font-semibold">Sense of hearing:</b> Excellent hearing, unaffected by the obstruction from his face.
|
||||
Normal sense of balance.
|
||||
</li>
|
||||
<li class="mx-7 mb-1 list-disc indent-0 sm:mx-10">
|
||||
<b>Sense of touch:</b> He's able to perceive pressure on his face, albeit with considerably diminished capacity
|
||||
than the rest of his body. The region also has even dimmer senses of temperature and pain. But being of magical
|
||||
origin, it is sensitive to such energies.
|
||||
<b class="font-semibold">Sense of touch:</b> He's able to perceive pressure on his face, albeit with considerably
|
||||
diminished capacity than the rest of his body. The region also has even dimmer senses of temperature and pain.
|
||||
But being of magical origin, it is sensitive to such energies.
|
||||
</li>
|
||||
<li class="mx-7 mb-1 list-disc indent-0 sm:mx-10">
|
||||
<b>Sense of taste:</b> With the maw that appears in front of his face, Sam is capable of tasting and consuming
|
||||
anything. He reports that "certain flavors are extremely vivid" (further clarification has been requested to amend
|
||||
this report).
|
||||
<b class="font-semibold">Sense of taste:</b> With the maw that appears in front of his face, Sam is capable of
|
||||
tasting and consuming anything. He reports that "certain flavors are extremely vivid" (further clarification has
|
||||
been requested to amend this report).
|
||||
</li>
|
||||
<li class="mx-7 mb-1 list-disc indent-0 sm:mx-10">
|
||||
<b>Sense of smell:</b> Capable of discerning strong smells with chemoreceptors in his face, while normally breathing
|
||||
through air diffusion instead of his lungs. Sam reports that most smells are quite weak, but those pertaining to
|
||||
living beings are particularly pronounced.
|
||||
<b class="font-semibold">Sense of smell:</b> Capable of discerning strong smells with chemoreceptors in his face,
|
||||
while normally breathing through air diffusion instead of his lungs. Sam reports that most smells are quite weak,
|
||||
but those pertaining to living beings are particularly pronounced.
|
||||
</li>
|
||||
</ul>
|
||||
</section>
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ import { TOS_COMMISSION_STATUS, TOS_UPDATED_AT } from "../data/tos";
|
|||
<h1 id="title-tos" class="mb-4 text-2xl sm:mb-5 sm:text-3xl">Terms of Service for story commissions</h1>
|
||||
<section aria-label="Commission status">
|
||||
<div class="my-2 flex items-center justify-end">
|
||||
<p class="mr-1 text-sm font-normal italic">
|
||||
<p class="mr-1 text-sm font-medium italic">
|
||||
Last update: <time datetime={TOS_UPDATED_AT.toISOString().slice(0, 10)}
|
||||
>{TOS_UPDATED_AT.toLocaleDateString("en-US", { dateStyle: "long" })}</time
|
||||
>
|
||||
|
|
@ -30,23 +30,23 @@ import { TOS_COMMISSION_STATUS, TOS_UPDATED_AT } from "../data/tos";
|
|||
</div>
|
||||
{
|
||||
TOS_COMMISSION_STATUS == "CLOSED" ? (
|
||||
<p class="mb-4 text-2xl font-normal uppercase sm:mb-8 sm:px-5 md:px-6">
|
||||
<p class="mb-4 text-2xl font-medium uppercase sm:mb-8 sm:px-5 md:px-6">
|
||||
Commissions are
|
||||
<span class="text-red-600 dark:text-red-500">closed</span>.
|
||||
</p>
|
||||
) : TOS_COMMISSION_STATUS == "OPEN" ? (
|
||||
<p class="mb-4 text-2xl font-normal uppercase sm:mb-8 sm:px-5 md:px-6">
|
||||
<p class="mb-4 text-2xl font-medium uppercase sm:mb-8 sm:px-5 md:px-6">
|
||||
Commissions are <span class="text-bm-500 dark:text-bm-400">open</span>.
|
||||
</p>
|
||||
) : TOS_COMMISSION_STATUS == "SEMI_OPEN" ? (
|
||||
<p class="mb-4 text-2xl font-normal sm:mb-8 sm:px-5 md:px-6">
|
||||
<p class="mb-4 text-2xl font-medium sm:mb-8 sm:px-5 md:px-6">
|
||||
<span class="uppercase">
|
||||
Commissions are <span class="text-orange-600 dark:text-orange-500">semi-open</span>
|
||||
</span>
|
||||
. I'll be more picky about which commissions to take.
|
||||
</p>
|
||||
) : TOS_COMMISSION_STATUS == "PRIVATE" ? (
|
||||
<p class="mb-4 text-2xl font-normal sm:mb-8 sm:px-5 md:px-6">
|
||||
<p class="mb-4 text-2xl font-medium sm:mb-8 sm:px-5 md:px-6">
|
||||
<span class="uppercase">
|
||||
Commissions are <span class="text-red-600 dark:text-red-500">private</span>
|
||||
</span>
|
||||
|
|
@ -58,11 +58,9 @@ import { TOS_COMMISSION_STATUS, TOS_UPDATED_AT } from "../data/tos";
|
|||
<section>
|
||||
<p class="mb-2 text-justify indent-6 sm:px-5 sm:indent-12 md:px-6">
|
||||
To stay flexible with both the word count and the deadline, I'm taking payments <em>after</em> the commission is
|
||||
done. My rate is <b>US$ 1.50 per 100 words</b>, and the final price is only set when the story is finished<a
|
||||
class="hover:underline"
|
||||
href="#note-1"
|
||||
aria-label="See note 1"><sup>[1]</sup></a
|
||||
>. The word count will be rounded to the nearest hundredth for pricing purposes, and the finished story will be
|
||||
done. My rate is <b class="font-semibold">US$ 1.50 per 100 words</b>, and the final price is only set when
|
||||
the story is finished<a class="hover:underline" href="#note-1" aria-label="See note 1"><sup>[1]</sup></a>. The
|
||||
word count will be rounded to the nearest hundredth for pricing purposes, and the finished story will be
|
||||
published in my public galleries.
|
||||
</p>
|
||||
<p class="mb-2 text-justify indent-6 sm:px-5 sm:indent-12 md:px-6">
|
||||
|
|
@ -75,7 +73,7 @@ import { TOS_COMMISSION_STATUS, TOS_UPDATED_AT } from "../data/tos";
|
|||
By asking me for a commission, you acknowledge: a) that you are 18+ years old; b) that you are readily
|
||||
committed to paying me right after the commission is done, and; c) that you agree to these terms.
|
||||
</p>
|
||||
<p id="note-1" class="mb-6 text-justify text-sm font-normal sm:px-5 md:px-6">
|
||||
<p id="note-1" class="mb-6 text-justify text-sm font-medium sm:px-5 md:px-6">
|
||||
[1] For first-time commissioners requesting a budget of 8,000+ words, a deposit equivalent to the first 4,000
|
||||
words <em>may</em> be requested. In such a case, the final payment will have that amount discounted.
|
||||
</p>
|
||||
|
|
@ -131,9 +129,9 @@ import { TOS_COMMISSION_STATUS, TOS_UPDATED_AT } from "../data/tos";
|
|||
</li>
|
||||
<li class="mx-6 mb-1 list-disc sm:mx-8">
|
||||
If you have any doubts, or are considering getting a commission from me,
|
||||
<a href="/contact" class="text-link underline transition-colors motion-reduce:transition-none"
|
||||
>please reach out</a
|
||||
>!
|
||||
<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.
|
||||
</li>
|
||||
</ul>
|
||||
</section>
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ import { SUBSCRIBESTAR_ENABLED } from "../data/subscribestar";
|
|||
<article aria-labelledby="title-my-work" class="sm:px-5 md:px-6">
|
||||
<h1 id="title-my-work" class="text-2xl sm:text-3xl">My work</h1>
|
||||
<section>
|
||||
<p class="mb-4 mt-5 sm:mb-3 sm:mt-6">
|
||||
<p class="mb-4 mt-5 text-justify indent-6 sm:mb-3 sm:mt-6 sm:px-5 sm:indent-12">
|
||||
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"
|
||||
|
|
@ -36,7 +36,7 @@ import { SUBSCRIBESTAR_ENABLED } from "../data/subscribestar";
|
|||
>, 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>
|
||||
<p class="my-4 sm:mb-3 sm:mt-6">
|
||||
<p class="my-4 text-justify indent-6 sm:mb-3 sm:mt-6 sm:px-5 sm:indent-12">
|
||||
I've also made a game called
|
||||
<a
|
||||
class="text-link transition-colors motion-reduce:transition-none"
|
||||
|
|
@ -44,9 +44,10 @@ import { SUBSCRIBESTAR_ENABLED } from "../data/subscribestar";
|
|||
target="_blank"
|
||||
><span class="underline">"Crossing Over"</span>
|
||||
<IconArrowUpRightFromSquare width="0.75rem" height="0.75rem" class="inline" /></a
|
||||
>, as part of Strawberry Jam 8 (a game jam hosted by eevee on Feb. 2024).
|
||||
>, 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!
|
||||
</p>
|
||||
<p class="my-4 sm:mb-3 sm:mt-6">
|
||||
<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>
|
||||
|
|
@ -128,7 +129,7 @@ import { SUBSCRIBESTAR_ENABLED } from "../data/subscribestar";
|
|||
<h2 id="title-story-commissions" class="my-4 text-lg sm:my-6 sm:text-2xl">Story commissions</h2>
|
||||
{
|
||||
TOS_COMMISSION_STATUS == "CLOSED" ? (
|
||||
<p class="mb-6 mt-2 sm:mt-3">
|
||||
<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
|
||||
|
|
@ -136,7 +137,7 @@ import { SUBSCRIBESTAR_ENABLED } from "../data/subscribestar";
|
|||
if interested.
|
||||
</p>
|
||||
) : TOS_COMMISSION_STATUS == "OPEN" ? (
|
||||
<p class="mb-6 mt-2 sm:mt-3">
|
||||
<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
|
||||
|
|
@ -144,7 +145,7 @@ import { SUBSCRIBESTAR_ENABLED } from "../data/subscribestar";
|
|||
if interested.
|
||||
</p>
|
||||
) : TOS_COMMISSION_STATUS == "SEMI_OPEN" ? (
|
||||
<p class="mb-6 mt-2 sm:mt-3">
|
||||
<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">
|
||||
|
|
@ -153,7 +154,7 @@ import { SUBSCRIBESTAR_ENABLED } from "../data/subscribestar";
|
|||
if interested.
|
||||
</p>
|
||||
) : TOS_COMMISSION_STATUS == "PRIVATE" ? (
|
||||
<p class="mb-6 mt-2 sm:mt-3">
|
||||
<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">
|
||||
|
|
@ -162,7 +163,7 @@ import { SUBSCRIBESTAR_ENABLED } from "../data/subscribestar";
|
|||
if interested.
|
||||
</p>
|
||||
) : (
|
||||
<p class="mb-6 mt-2 sm:mt-3">
|
||||
<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
|
||||
|
|
@ -215,7 +216,7 @@ import { SUBSCRIBESTAR_ENABLED } from "../data/subscribestar";
|
|||
target="_blank"
|
||||
class="text-link transition-colors motion-reduce:transition-none"
|
||||
>
|
||||
<span class="underline">writing code (such as both of my websites)</span>
|
||||
<span class="underline">writing code (including for my websites)</span>
|
||||
<IconArrowUpRightFromSquare width="0.75rem" height="0.75rem" class="mb-1 inline" />
|
||||
</a>, and localizing
|
||||
<a
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue