Improved a11y and SEO
This commit is contained in:
parent
651054e65f
commit
d4e8eb7dd8
10 changed files with 237 additions and 215 deletions
353
astro.config.mjs
353
astro.config.mjs
|
|
@ -1,185 +1,188 @@
|
|||
import { defineConfig, envField } from "astro/config";
|
||||
import tailwindIntegration from "@astrojs/tailwind";
|
||||
import alpinejsIntegration from "@astrojs/alpinejs";
|
||||
import htaccessIntegration from "astro-htaccess";
|
||||
import { AI_BOTS } from "./src/data/ai_bots";
|
||||
|
||||
import alpinejs from "@astrojs/alpinejs";
|
||||
|
||||
// https://astro.build/config
|
||||
export default defineConfig({
|
||||
site: "https://badmanners.xyz",
|
||||
integrations: [tailwindIntegration({
|
||||
applyBaseStyles: false,
|
||||
}), htaccessIntegration({
|
||||
generateHtaccessFile: import.meta.env.APACHE_CONFIG === "true",
|
||||
customRules: [
|
||||
// Block AI bots
|
||||
"<IfModule mod_rewrite.c>",
|
||||
" RewriteEngine on",
|
||||
" RewriteBase /",
|
||||
` RewriteCond %{HTTP_USER_AGENT} ${AI_BOTS.map((bot) => `^${bot}$`).join("|")} [NC]`,
|
||||
" RewriteRule ^ – [F]",
|
||||
"</IfModule>",
|
||||
],
|
||||
redirects: [
|
||||
{
|
||||
match: /^\/@\/(aryion|ekas?(portal)?)\b/,
|
||||
url: "https://aryion.com/g4/user/BadManners",
|
||||
},
|
||||
{
|
||||
match: /^\/@\/blog\b/,
|
||||
url: "https://gallery.badmanners.xyz/blog",
|
||||
},
|
||||
{
|
||||
match: /^\/@\/(blue[_-]?sky|bsky)\b/,
|
||||
url: "https://bsky.app/profile/badmanners.xyz",
|
||||
},
|
||||
{
|
||||
match: /^\/@\/(buymeacoffee|buy_me_a_coffee|buy-me-a-coffee|bmac)\b/,
|
||||
url: "https://www.buymeacoffee.com/BadMannersXYZ",
|
||||
},
|
||||
{
|
||||
match: /^\/@\/carrd\b/,
|
||||
url: "https://badmanners.carrd.co",
|
||||
},
|
||||
{
|
||||
match: /^\/@\/code[_-]?berg\b/,
|
||||
url: "https://codeberg.org/BadManners",
|
||||
},
|
||||
{
|
||||
match: /^\/@\/discord\b/,
|
||||
url: "/#discord",
|
||||
},
|
||||
{
|
||||
match: /^\/@\/e[_-]?mail\b/,
|
||||
url: "/#e-mail",
|
||||
},
|
||||
{
|
||||
match: /^\/@\/(fur[_-]?affinity|fa)\b/,
|
||||
url: "https://www.furaffinity.net/user/badmanners",
|
||||
},
|
||||
{
|
||||
match: /^\/@\/(gallery|stor(y|ies)|games?)\b/,
|
||||
url: "https://gallery.badmanners.xyz",
|
||||
},
|
||||
{
|
||||
match: /^\/@\/(git[_-]?hub|gh)\b/,
|
||||
url: "https://github.com/BadMannersXYZ",
|
||||
},
|
||||
{
|
||||
match: /^\/@\/git[_-]?lab\b/,
|
||||
url: "https://gitlab.com/Bad_Manners",
|
||||
},
|
||||
{
|
||||
match: /^\/@\/(git[_-]?gud|sapp?hire)\b/,
|
||||
url: "https://gitgud.io/BadMannersXYZ",
|
||||
},
|
||||
{
|
||||
match: /^\/@\/(google|g[_-]?mail)\b/,
|
||||
url: "/#gmail",
|
||||
},
|
||||
{
|
||||
match: /^\/@\/(gpg|pgp)\b/,
|
||||
url: "/gpg.pub",
|
||||
},
|
||||
{
|
||||
match: /^\/@\/gum[_-]?road\b/,
|
||||
url: "https://badmanners.gumroad.com",
|
||||
},
|
||||
{
|
||||
match: /^\/@\/(ink[_-]?bunny|ib)\b/,
|
||||
url: "https://inkbunny.net/BadManners",
|
||||
},
|
||||
{
|
||||
match: /^\/@\/itaku\b/,
|
||||
url: "https://itaku.ee/profile/badmanners",
|
||||
},
|
||||
{
|
||||
match: /^\/@\/itch\b/,
|
||||
url: "https://bad-manners.itch.io",
|
||||
},
|
||||
{
|
||||
match: /^\/@\/keybase\b/,
|
||||
url: "https://keybase.io/badmanners",
|
||||
},
|
||||
{
|
||||
match: /^\/@\/keyoxide\b/,
|
||||
url: "https://keyoxide.org/aspe:keyoxide.org:UWYBVFCBFXTVUF2U6FS6AYJHLU",
|
||||
},
|
||||
{
|
||||
match: /^\/@\/ko[._-]?fi\b/,
|
||||
url: "https://ko-fi.com/badmanners",
|
||||
},
|
||||
{
|
||||
match: /^\/@\/(mastodon|meow[._-]?social|gulp[._-]?cafe)\b/,
|
||||
url: "https://meow.social/@BadManners",
|
||||
},
|
||||
{
|
||||
match: /^\/@\/neo[_-]?cities\b/,
|
||||
url: "https://badmanners.neocities.org",
|
||||
},
|
||||
{
|
||||
match: /^\/@\/picarto\b/,
|
||||
url: "https://www.picarto.tv/BadManners",
|
||||
},
|
||||
{
|
||||
match: /^\/@\/pillow[_-]?fort\b/,
|
||||
url: "https://www.pillowfort.social/BadManners",
|
||||
},
|
||||
{
|
||||
match: /^\/@\/pronouns?\b/,
|
||||
url: "https://pronouns.cc/@BadManners",
|
||||
},
|
||||
{
|
||||
match: /^\/@\/redd\.?it\b/,
|
||||
url: "https://www.reddit.com/user/BadManners_",
|
||||
},
|
||||
{
|
||||
match: /^\/@\/resetera\b/,
|
||||
url: "https://www.resetera.com/members/bad-manners.181209/",
|
||||
},
|
||||
{
|
||||
match: /^\/@\/signal\b/,
|
||||
url: "https://signal.me/#eu/ytt_rk0fFmAB2JAW-x2PbUiJyc_H3kYmfL_Pq4QNh5QIDsiFtjdFHaqFRs1D36tB",
|
||||
},
|
||||
{
|
||||
match: /^\/@\/(so[_-]?furry|sf)\b/,
|
||||
url: "https://bad-manners.sofurry.com",
|
||||
},
|
||||
{
|
||||
match: /^\/@\/ssh\b/,
|
||||
url: "/ssh.pub",
|
||||
},
|
||||
{
|
||||
match: /^\/@\/steam(community|powered)?\b/,
|
||||
url: "https://steamcommunity.com/id/badmanners_",
|
||||
},
|
||||
{
|
||||
match: /^\/@\/subscribe[_-]?star\b/,
|
||||
url: "https://subscribestar.adult/bad-manners",
|
||||
},
|
||||
{
|
||||
match: /^\/@\/(telegram|t\.me)\b/,
|
||||
url: "https://t.me/bad_manners",
|
||||
},
|
||||
{
|
||||
match: /^\/@\/tumblr\b/,
|
||||
url: "https://www.tumblr.com/badmannersxyz",
|
||||
},
|
||||
{
|
||||
match: /^\/@\/twitch\b/,
|
||||
url: "https://www.twitch.tv/bad__manners",
|
||||
},
|
||||
{
|
||||
match: /^\/@\/weasyl\b/,
|
||||
url: "https://www.weasyl.com/~badmanners",
|
||||
},
|
||||
{
|
||||
match: /^\/@\/(you[_-]?tube|youtu\.be|yt)\b/,
|
||||
url: "https://www.youtube.com/@BadMannersXYZ",
|
||||
},
|
||||
],
|
||||
}), alpinejs()],
|
||||
integrations: [
|
||||
tailwindIntegration({
|
||||
applyBaseStyles: false,
|
||||
}),
|
||||
alpinejsIntegration(),
|
||||
htaccessIntegration({
|
||||
generateHtaccessFile: import.meta.env.APACHE_CONFIG === "true",
|
||||
customRules: [
|
||||
// Block AI bots
|
||||
"<IfModule mod_rewrite.c>",
|
||||
" RewriteEngine on",
|
||||
" RewriteBase /",
|
||||
` RewriteCond %{HTTP_USER_AGENT} ${AI_BOTS.map((bot) => `^${bot}$`).join("|")} [NC]`,
|
||||
" RewriteRule ^ – [F]",
|
||||
"</IfModule>",
|
||||
],
|
||||
redirects: [
|
||||
{
|
||||
match: /^\/@\/(aryion|ekas?(portal)?)\b/,
|
||||
url: "https://aryion.com/g4/user/BadManners",
|
||||
},
|
||||
{
|
||||
match: /^\/@\/blog\b/,
|
||||
url: "https://gallery.badmanners.xyz/blog",
|
||||
},
|
||||
{
|
||||
match: /^\/@\/(blue[_-]?sky|bsky)\b/,
|
||||
url: "https://bsky.app/profile/badmanners.xyz",
|
||||
},
|
||||
{
|
||||
match: /^\/@\/(buymeacoffee|buy_me_a_coffee|buy-me-a-coffee|bmac)\b/,
|
||||
url: "https://www.buymeacoffee.com/BadMannersXYZ",
|
||||
},
|
||||
{
|
||||
match: /^\/@\/carrd\b/,
|
||||
url: "https://badmanners.carrd.co",
|
||||
},
|
||||
{
|
||||
match: /^\/@\/code[_-]?berg\b/,
|
||||
url: "https://codeberg.org/BadManners",
|
||||
},
|
||||
{
|
||||
match: /^\/@\/discord\b/,
|
||||
url: "/#discord",
|
||||
},
|
||||
{
|
||||
match: /^\/@\/e[_-]?mail\b/,
|
||||
url: "/#e-mail",
|
||||
},
|
||||
{
|
||||
match: /^\/@\/(fur[_-]?affinity|fa)\b/,
|
||||
url: "https://www.furaffinity.net/user/badmanners",
|
||||
},
|
||||
{
|
||||
match: /^\/@\/(gallery|stor(y|ies)|games?)\b/,
|
||||
url: "https://gallery.badmanners.xyz",
|
||||
},
|
||||
{
|
||||
match: /^\/@\/(git[_-]?hub|gh)\b/,
|
||||
url: "https://github.com/BadMannersXYZ",
|
||||
},
|
||||
{
|
||||
match: /^\/@\/git[_-]?lab\b/,
|
||||
url: "https://gitlab.com/Bad_Manners",
|
||||
},
|
||||
{
|
||||
match: /^\/@\/(git[_-]?gud|sapp?hire)\b/,
|
||||
url: "https://gitgud.io/BadMannersXYZ",
|
||||
},
|
||||
{
|
||||
match: /^\/@\/(google|g[_-]?mail)\b/,
|
||||
url: "/#google",
|
||||
},
|
||||
{
|
||||
match: /^\/@\/(gpg|pgp)\b/,
|
||||
url: "/gpg.pub",
|
||||
},
|
||||
{
|
||||
match: /^\/@\/gum[_-]?road\b/,
|
||||
url: "https://badmanners.gumroad.com",
|
||||
},
|
||||
{
|
||||
match: /^\/@\/(ink[_-]?bunny|ib)\b/,
|
||||
url: "https://inkbunny.net/BadManners",
|
||||
},
|
||||
{
|
||||
match: /^\/@\/itaku\b/,
|
||||
url: "https://itaku.ee/profile/badmanners",
|
||||
},
|
||||
{
|
||||
match: /^\/@\/itch\b/,
|
||||
url: "https://bad-manners.itch.io",
|
||||
},
|
||||
{
|
||||
match: /^\/@\/keybase\b/,
|
||||
url: "https://keybase.io/badmanners",
|
||||
},
|
||||
{
|
||||
match: /^\/@\/keyoxide\b/,
|
||||
url: "https://keyoxide.org/aspe:keyoxide.org:UWYBVFCBFXTVUF2U6FS6AYJHLU",
|
||||
},
|
||||
{
|
||||
match: /^\/@\/ko[._-]?fi\b/,
|
||||
url: "https://ko-fi.com/badmanners",
|
||||
},
|
||||
{
|
||||
match: /^\/@\/(mastodon|meow[._-]?social|gulp[._-]?cafe)\b/,
|
||||
url: "https://meow.social/@BadManners",
|
||||
},
|
||||
{
|
||||
match: /^\/@\/neo[_-]?cities\b/,
|
||||
url: "https://badmanners.neocities.org",
|
||||
},
|
||||
{
|
||||
match: /^\/@\/picarto\b/,
|
||||
url: "https://www.picarto.tv/BadManners",
|
||||
},
|
||||
{
|
||||
match: /^\/@\/pillow[_-]?fort\b/,
|
||||
url: "https://www.pillowfort.social/BadManners",
|
||||
},
|
||||
{
|
||||
match: /^\/@\/pronouns?\b/,
|
||||
url: "https://pronouns.cc/@BadManners",
|
||||
},
|
||||
{
|
||||
match: /^\/@\/redd\.?it\b/,
|
||||
url: "https://www.reddit.com/user/BadManners_",
|
||||
},
|
||||
{
|
||||
match: /^\/@\/resetera\b/,
|
||||
url: "https://www.resetera.com/members/bad-manners.181209/",
|
||||
},
|
||||
{
|
||||
match: /^\/@\/signal\b/,
|
||||
url: "https://signal.me/#eu/ytt_rk0fFmAB2JAW-x2PbUiJyc_H3kYmfL_Pq4QNh5QIDsiFtjdFHaqFRs1D36tB",
|
||||
},
|
||||
{
|
||||
match: /^\/@\/(so[_-]?furry|sf)\b/,
|
||||
url: "https://bad-manners.sofurry.com",
|
||||
},
|
||||
{
|
||||
match: /^\/@\/ssh\b/,
|
||||
url: "/ssh.pub",
|
||||
},
|
||||
{
|
||||
match: /^\/@\/steam(community|powered)?\b/,
|
||||
url: "https://steamcommunity.com/id/badmanners_",
|
||||
},
|
||||
{
|
||||
match: /^\/@\/subscribe[_-]?star\b/,
|
||||
url: "https://subscribestar.adult/bad-manners",
|
||||
},
|
||||
{
|
||||
match: /^\/@\/(telegram|t\.me)\b/,
|
||||
url: "https://t.me/bad_manners",
|
||||
},
|
||||
{
|
||||
match: /^\/@\/tumblr\b/,
|
||||
url: "https://www.tumblr.com/badmannersxyz",
|
||||
},
|
||||
{
|
||||
match: /^\/@\/twitch\b/,
|
||||
url: "https://www.twitch.tv/bad__manners",
|
||||
},
|
||||
{
|
||||
match: /^\/@\/weasyl\b/,
|
||||
url: "https://www.weasyl.com/~badmanners",
|
||||
},
|
||||
{
|
||||
match: /^\/@\/(you[_-]?tube|youtu\.be|yt)\b/,
|
||||
url: "https://www.youtube.com/@BadMannersXYZ",
|
||||
},
|
||||
],
|
||||
}),
|
||||
],
|
||||
build: {
|
||||
assets: "assets",
|
||||
},
|
||||
|
|
@ -195,4 +198,4 @@ export default defineConfig({
|
|||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -21,8 +21,8 @@ const isCurrentRoute = ({ path }: NavRoute) =>
|
|||
class:list={[
|
||||
"rounded border px-6 py-2 uppercase transition-colors hover:underline focus:underline motion-reduce:transition-none sm:px-8 sm:py-3",
|
||||
isCurrentRoute(route)
|
||||
? "border-bm-500 text-bm-500 dark:border-bm-400 dark:text-bm-400"
|
||||
: "border-stone-600 text-stone-600 hover:border-bm-500 hover:text-bm-500 focus:border-bm-500 focus:text-bm-500 dark:border-zinc-300 dark:text-zinc-300 dark:hover:border-bm-400 dark:hover:text-bm-400 dark:focus:border-bm-400 dark:focus:text-bm-400",
|
||||
? "border-bm-600 text-green-700 dark:border-bm-400 dark:text-bm-400"
|
||||
: "border-stone-600 text-stone-600 hover:border-green-700 hover:text-green-700 focus:border-green-700 focus:text-green-700 dark:border-zinc-300 dark:text-zinc-300 dark:hover:border-bm-400 dark:hover:text-bm-400 dark:focus:border-bm-400 dark:focus:text-bm-400",
|
||||
]}
|
||||
aria-current={isCurrentRoute(route) ? "page" : undefined}
|
||||
>
|
||||
|
|
|
|||
|
|
@ -55,7 +55,7 @@ const title = pageTitle ? `${pageTitle} | Bad Manners` : "Bad Manners";
|
|||
<slot />
|
||||
</main>
|
||||
<footer
|
||||
class="sm:text-md flex flex-col items-center pt-9 text-sm font-medium tracking-wide text-black dark:text-white"
|
||||
class="sm:text-md flex flex-col items-center bg-bm-300/[0.01] pt-9 text-sm font-medium tracking-wide text-black dark:bg-green-950/[0.01] dark:text-white"
|
||||
>
|
||||
<div class="flex items-center">
|
||||
<span id="copyright" class="mr-2"
|
||||
|
|
|
|||
|
|
@ -3,7 +3,10 @@ import BaseLayout from "@layouts/BaseLayout.astro";
|
|||
---
|
||||
|
||||
<BaseLayout pageTitle="Not found">
|
||||
<meta slot="head" property="og:description" content="Not found." />
|
||||
<Fragment slot="head">
|
||||
<meta property="og:description" content="Not found" />
|
||||
<meta name="description" content="The requested link could not be found." />
|
||||
</Fragment>
|
||||
<article aria-labelledby="title-not-found">
|
||||
<h1 id="title-not-found" class="text-2xl sm:text-3xl">404 – Not found</h1>
|
||||
<section>
|
||||
|
|
|
|||
|
|
@ -7,11 +7,14 @@ import EnhancedTooltips from "@components/EnhancedTooltips.astro";
|
|||
---
|
||||
|
||||
<BaseLayout pageTitle="About me">
|
||||
<meta slot="head" property="og:description" content="About Bad Manners." />
|
||||
<Fragment slot="head">
|
||||
<meta property="og:description" content="About Bad Manners." />
|
||||
<meta name="description" content="More information about me, my name, and my fursona." />
|
||||
</Fragment>
|
||||
<article class="h-card" aria-labelledby="title-about-me">
|
||||
<h1 id="title-about-me" class="text-2xl sm:text-3xl">About me</h1>
|
||||
<section>
|
||||
<p class="mb-4 mt-5 text-justify indent-6 sm:mb-3 sm:mt-6 sm:px-5 sm:indent-12">
|
||||
<p class="mb-4 mt-5 text-left 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
|
||||
|
|
@ -19,7 +22,7 @@ import EnhancedTooltips from "@components/EnhancedTooltips.astro";
|
|||
class="p-pronoun font-medium underline decoration-current decoration-dotted"
|
||||
title="he/him/his/his/himself"
|
||||
data-tooltip>he/him</span
|
||||
> or <span
|
||||
> and <span
|
||||
class="p-pronoun font-medium underline decoration-current decoration-dotted"
|
||||
title="they/them/their/theirs/themself"
|
||||
data-tooltip>they/them</span
|
||||
|
|
@ -29,7 +32,7 @@ import EnhancedTooltips from "@components/EnhancedTooltips.astro";
|
|||
</p>
|
||||
</section>
|
||||
<section class="h-card">
|
||||
<p class="my-4 text-justify indent-6 sm:mb-3 sm:px-5 sm:indent-12">
|
||||
<p class="my-4 text-left 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
|
||||
|
|
@ -39,7 +42,7 @@ import EnhancedTooltips from "@components/EnhancedTooltips.astro";
|
|||
<a
|
||||
href="/sam_brendan"
|
||||
class="u-url group mx-auto mb-1 block w-max max-w-full pb-0 sm:mb-3"
|
||||
aria-label="Learn more about Sam"
|
||||
aria-label="Information about Sam"
|
||||
>
|
||||
<Image
|
||||
src={ImageSamStickerJuicebox}
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@ const [gpgKey, sshKey] = await Promise.all([
|
|||
<BaseLayout>
|
||||
<Fragment slot="head">
|
||||
<meta property="og:description" content="Safe vore enthusiast, mimic hybrid furry, and occasional writer." />
|
||||
<meta name="description" content="Safe vore enthusiast, furry, programmer, and occasional writer." />
|
||||
<link
|
||||
rel="alternate"
|
||||
type="application/rss+xml"
|
||||
|
|
@ -62,7 +63,7 @@ const [gpgKey, sshKey] = await Promise.all([
|
|||
<img
|
||||
loading="eager"
|
||||
src="/logo.webp"
|
||||
alt="A pixelated metal briefcase over a background with a green gradient."
|
||||
alt="A pixelated metal briefcase over a green gradient background."
|
||||
class="u-logo mx-auto my-4 h-screen max-h-48 rounded-full transition-transform hover:scale-110 motion-reduce:transition-none motion-reduce:hover:scale-100 sm:max-h-72"
|
||||
/>
|
||||
<p class="p-note mt-6 sm:px-5 md:px-6">
|
||||
|
|
@ -554,12 +555,10 @@ const [gpgKey, sshKey] = await Promise.all([
|
|||
return;
|
||||
}
|
||||
|
||||
interface TippyTooltipEvent extends Event {
|
||||
detail: {
|
||||
target: HTMLElement;
|
||||
content: string;
|
||||
};
|
||||
}
|
||||
type TippyTooltipEvent = CustomEvent<{
|
||||
target: HTMLElement;
|
||||
content: string;
|
||||
}>;
|
||||
|
||||
document.addEventListener("tippyTooltip", (e: Event) => {
|
||||
const { target, content } = (e as TippyTooltipEvent).detail;
|
||||
|
|
|
|||
|
|
@ -2,7 +2,13 @@ import type { APIRoute } from "astro";
|
|||
import { AI_BOTS } from "@data/ai_bots";
|
||||
|
||||
export const GET: APIRoute = async () => {
|
||||
const robots = [AI_BOTS.map((bot) => `User-agent: ${bot}`), "Disallow: /", "", "User-agent: *", "Disallow: .htaccess"]
|
||||
const robots = [
|
||||
AI_BOTS.map((bot) => `User-agent: ${bot}`),
|
||||
"Disallow: /",
|
||||
"",
|
||||
"User-agent: *",
|
||||
"Disallow: /.htaccess",
|
||||
]
|
||||
.flat()
|
||||
.join("\n");
|
||||
|
||||
|
|
|
|||
|
|
@ -7,16 +7,19 @@ import EnhancedTooltips from "@components/EnhancedTooltips.astro";
|
|||
---
|
||||
|
||||
<BaseLayout pageTitle="Sam Brendan">
|
||||
<meta slot="head" property="og:description" content="Mimic x maned wolf hybrid." />
|
||||
<Fragment slot="head">
|
||||
<meta property="og:description" content="Mimic x maned wolf hybrid." />
|
||||
<meta name="description" content="The fursona of Bad Manners, a mimic x maned wolf hybrid." />
|
||||
</Fragment>
|
||||
<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">
|
||||
<p class="my-4 text-left 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.
|
||||
simply <b class="font-semibold">Sam</b>), 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.
|
||||
</p>
|
||||
</section>
|
||||
<section aria-labelledby="title-physical-description">
|
||||
|
|
@ -48,7 +51,7 @@ import EnhancedTooltips from "@components/EnhancedTooltips.astro";
|
|||
>. 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">
|
||||
<p class="mt-3 text-left 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 +60,12 @@ import EnhancedTooltips from "@components/EnhancedTooltips.astro";
|
|||
– 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">
|
||||
<p class="mt-3 text-left 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">
|
||||
<p class="mb-5 mt-3 text-left 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
|
||||
|
|
@ -101,12 +104,12 @@ import EnhancedTooltips from "@components/EnhancedTooltips.astro";
|
|||
>. 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">
|
||||
<p class="mt-3 text-left indent-6 sm:mt-2 sm:px-5 sm:indent-12">
|
||||
Sam identifies as male, and uses <span
|
||||
class="p-pronoun underline decoration-current decoration-dotted"
|
||||
title="he/him/his/his/himself"
|
||||
data-tooltip>he/him</span
|
||||
> or <span
|
||||
> and <span
|
||||
class="p-pronoun underline decoration-current decoration-dotted"
|
||||
title="they/them/their/theirs/themself"
|
||||
data-tooltip>they/them</span
|
||||
|
|
@ -116,14 +119,14 @@ import EnhancedTooltips from "@components/EnhancedTooltips.astro";
|
|||
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">
|
||||
<p class="mt-3 text-left 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">
|
||||
<p class="mb-5 mt-3 text-left 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
|
||||
|
|
@ -133,7 +136,7 @@ import EnhancedTooltips from "@components/EnhancedTooltips.astro";
|
|||
</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">
|
||||
<ul class="mb-5 text-left 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>
|
||||
|
|
@ -156,14 +159,14 @@ import EnhancedTooltips from "@components/EnhancedTooltips.astro";
|
|||
</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">
|
||||
<p class="mb-5 mt-3 text-left 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">
|
||||
<ul class="mb-5 mt-3 text-left sm:mb-4 sm:mt-2 sm:px-5">
|
||||
<li class="mx-7 mb-1 list-disc indent-0 sm:mx-10">
|
||||
<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
|
||||
|
|
|
|||
|
|
@ -8,6 +8,10 @@ import { TOS_COMMISSION_STATUS, TOS_UPDATED_AT } from "@data/tos";
|
|||
<BaseLayout pageTitle="Terms of Service">
|
||||
<Fragment slot="head">
|
||||
<meta property="og:description" content="My Terms of Service for story commissions." />
|
||||
<meta
|
||||
name="description"
|
||||
content="My Terms of Service for story commissions, as well as my availability for commissioned work."
|
||||
/>
|
||||
<link rel="alternate" type="application/rss+xml" href={new URL("/feed.xml", Astro.site)} title="RSS feed" />
|
||||
</Fragment>
|
||||
<article aria-labelledby="title-tos">
|
||||
|
|
@ -32,23 +36,23 @@ import { TOS_COMMISSION_STATUS, TOS_UPDATED_AT } from "@data/tos";
|
|||
</div>
|
||||
{
|
||||
TOS_COMMISSION_STATUS === "CLOSED" ? (
|
||||
<p id="status" class="mb-4 text-2xl font-medium uppercase sm:mb-8 sm:px-5 md:px-6">
|
||||
<p id="status" role="status" 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 id="status" class="mb-4 text-2xl font-medium uppercase sm:mb-8 sm:px-5 md:px-6">
|
||||
<p id="status" role="status" 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 id="status" class="mb-4 text-2xl font-medium sm:mb-8 sm:px-5 md:px-6">
|
||||
<p id="status" role="status" 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 id="status" class="mb-4 text-2xl font-medium sm:mb-8 sm:px-5 md:px-6">
|
||||
<p id="status" role="status" 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>
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ import { SUBSCRIBESTAR_ENABLED } from "@data/subscribestar";
|
|||
<BaseLayout pageTitle="My work">
|
||||
<Fragment slot="head">
|
||||
<meta property="og:description" content="The things I've made." />
|
||||
<meta name="description" content="Information about the stories, game, and more that I've created." />
|
||||
<link
|
||||
rel="alternate"
|
||||
type="application/rss+xml"
|
||||
|
|
@ -33,7 +34,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 text-justify indent-6 sm:mb-3 sm:mt-6 sm:px-5 sm:indent-12">
|
||||
<p class="mb-4 mt-5 text-left 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"
|
||||
|
|
@ -50,7 +51,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 text-justify indent-6 sm:mb-3 sm:mt-6 sm:px-5 sm:indent-12">
|
||||
<p class="my-4 text-left 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"
|
||||
|
|
@ -71,7 +72,7 @@ import { SUBSCRIBESTAR_ENABLED } from "@data/subscribestar";
|
|||
>
|
||||
Crossing Over by Bad Manners
|
||||
</iframe>
|
||||
<p class="my-4 text-justify indent-6 sm:mt-6 sm:px-5 sm:indent-12">
|
||||
<p class="my-4 text-left indent-6 sm:mt-6 sm:px-5 sm:indent-12">
|
||||
You can find my galleries through any of the links below. Aside from the first link, these also include some of
|
||||
the art that I got from others (commissions, gifts, etc.).
|
||||
</p>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue