This commit is contained in:
laura 2025-11-01 23:46:32 -03:00
parent 30f2b4714d
commit 0c9f7a7822
Signed by: w
GPG key ID: BCD2117C99E69817
21 changed files with 1868 additions and 1839 deletions

View file

@ -1,552 +1,549 @@
@font-face { @font-face {
font-family: "Jersey 15"; font-family: "Jersey 15";
src: url("/fonts/jersey15.ttf") format("truetype"); src: url("/fonts/jersey15.ttf") format("truetype");
}
@font-face {
font-family: "Share Tech";
src: url("/fonts/str.ttf") format("truetype");
} }
:root { :root {
--theme-bg: #16191c; --theme-bg: #16191c;
--theme-bg-secondary: #252a2e; --theme-bg-secondary: #252a2e;
--theme-bg-tertiary: #1b1f22; --theme-bg-tertiary: #1b1f22;
--theme-fg: #a3aaaf; --theme-fg: #a3aaaf;
--theme-fg-alt-rgb: 106, 111, 121; --theme-fg-alt-rgb: 106, 111, 121;
--theme-fg-alt: rgb(var(--theme-fg-alt-rgb)); --theme-fg-alt: rgb(var(--theme-fg-alt-rgb));
--theme-accent-rgb: 163, 170, 175; /* 147, 184, 217; */ --theme-accent-rgb: 163, 170, 175; /* 147, 184, 217; */
--theme-accent: rgb(var(--theme-accent-rgb)); --theme-accent: rgb(var(--theme-accent-rgb));
--theme-accent-alt: #2c3237; /* #2a353e; */ --theme-accent-alt: #2c3237; /* #2a353e; */
--theme-accent-third: rgb(140, 155, 189); /* #2a353e; */ --theme-accent-third: rgb(140, 155, 189); /* #2a353e; */
--theme-accent-title-rgb: var(--theme-accent-rgb); --theme-accent-title-rgb: var(--theme-accent-rgb);
--theme-accent-title: rgb(var(--theme-accent-title-rgb)); --theme-accent-title: rgb(var(--theme-accent-title-rgb));
--theme-border-rgb: 56, 60, 66; --theme-border-rgb: 56, 60, 66;
--theme-border: rgb(var(--theme-border-rgb)); --theme-border: rgb(var(--theme-border-rgb));
} }
html { html {
line-height: 1.5; line-height: 1.5;
font-family: "Jersey 15", sans-serif, "Share Tech", monospace; font-family: "Jersey 15", sans-serif, monospace;
font-size: 22px; font-size: 22px;
-webkit-font-smoothing: none; -webkit-font-smoothing: none;
font-smooth: never; font-smooth: never;
scroll-behavior: smooth;
} }
body { body {
padding: 16px; padding: 16px;
margin: auto; margin: auto;
background-color: var(--theme-bg); background-color: var(--theme-bg);
color: var(--theme-fg); color: var(--theme-fg);
} }
.section { .section {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
padding: 2.4rem; padding: 2.4rem;
overflow-wrap: break-word; overflow-wrap: break-word;
clip-path: polygon( clip-path: polygon(
0px calc(100% - 8px), 0px calc(100% - 8px),
8px calc(100% - 8px), 8px calc(100% - 8px),
8px 100%, 8px 100%,
calc(100% - 8px) 100%, calc(100% - 8px) 100%,
calc(100% - 8px) calc(100% - 8px), calc(100% - 8px) calc(100% - 8px),
100% calc(100% - 8px), 100% calc(100% - 8px),
100% 8px, 100% 8px,
calc(100% - 8px) 8px, calc(100% - 8px) 8px,
calc(100% - 8px) 0px, calc(100% - 8px) 0px,
8px 0px, 8px 0px,
8px 8px, 8px 8px,
0px 8px 0px 8px
); );
box-sizing: border-box; box-sizing: border-box;
background-color: var(--theme-bg-secondary); background-color: var(--theme-bg-secondary);
gap: 1rem; gap: 1rem;
animation: fadeIn 0.4s ease-out;
}
@keyframes fadeIn {
from {
opacity: 0;
transform: translateY(10px);
}
to {
opacity: 1;
transform: translateY(0);
}
} }
.section, .section,
#header { #header {
max-width: 36rem; max-width: 36rem;
width: 100%; width: 100%;
} }
.alt { .alt {
color: var(--theme-fg-alt); color: var(--theme-fg-alt);
} }
.alt-font { /* .alt-font { */
font-size: 16px; /* font-size: 16px; */
font-family: "Share Tech", monospace; /* font-family: "Gamja Flower", monospace; */
font-weight: 700; /* font-weight: 700; */
letter-spacing: 0.05em; /* letter-spacing: 0.05em; */
} /* } */
.section p { .section p {
margin: 0; margin: 0;
} }
p { p {
hyphens: auto; -webkit-hyphens: auto;
} hyphens: auto;
.intro > .logo {
height: 1em;
margin-right: 0.5ch;
vertical-align: -4px;
} }
.centered { .centered {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
width: 100%; width: 100%;
height: 100%; height: 100%;
gap: 1em; gap: 1em;
} }
.title { .title {
color: var(--theme-accent-title); color: var(--theme-accent-title);
padding-bottom: 0.25em; padding-bottom: 0.25em;
border-bottom: 2px solid var(--theme-border); border-bottom: 2px solid var(--theme-border);
text-align: center; text-align: center;
justify-content: center; justify-content: center;
margin: 0px; margin: 0px;
padding-bottom: 0.5rem; padding-bottom: 0.5rem;
display: flex; display: flex;
align-items: center; align-items: center;
gap: 0.25em; gap: 0.25em;
} }
.title-1 { .title-1 {
font-size: 1.25rem; font-size: 1.25rem;
} }
.title-3 { .title-2 {
color: var(--theme-fg-alt); color: var(--theme-fg-alt);
padding-bottom: 0.16rem; padding-bottom: 0.16rem;
border-bottom: none; border-bottom: none;
font-size: 0.9rem; font-size: 0.9rem;
} }
.title.title-3::after { .title.title-2::after {
background-image: linear-gradient( background-image: linear-gradient(
90deg, 90deg,
rgba(var(--theme-border-rgb), 0) 0, rgba(var(--theme-border-rgb), 0) 0,
rgba(var(--theme-fg-alt-rgb), 255) rgba(var(--theme-fg-alt-rgb), 255)
); );
} }
.title::after { .title::after {
background-image: linear-gradient( background-image: linear-gradient(
90deg, 90deg,
rgba(var(--theme-accent-title-rgb), 0) 0, rgba(var(--theme-accent-title-rgb), 0) 0,
rgba(var(--theme-accent-title-rgb), 255) rgba(var(--theme-accent-title-rgb), 255)
); );
content: ""; content: "";
display: block; display: block;
flex: 1; flex: 1;
margin-left: 0.5ch; margin-left: 0.5ch;
height: 0.3rem; height: 0.3rem;
border-radius: 3px; border-radius: 3px;
} }
.title .icon { .title .icon {
height: 24px; height: 24px;
width: 24px; width: 24px;
shape-rendering: crispEdges; shape-rendering: crispEdges;
} }
.box { .box {
background-color: var(--theme-accent-alt); background-color: var(--theme-accent-alt);
color: var(--theme-accent); color: var(--theme-accent);
padding: 0.5rem 1rem; padding: 0.5rem 1rem;
line-height: 1; line-height: 1;
box-sizing: border-box; box-sizing: border-box;
width: fit-content; width: fit-content;
overflow: hidden; overflow: hidden;
text-overflow: ellipsis; text-overflow: ellipsis;
word-break: break-all; word-break: break-all;
clip-path: polygon( clip-path: polygon(
0px calc(100% - 6px), 0px calc(100% - 6px),
6px calc(100% - 6px), 6px calc(100% - 6px),
6px 100%, 6px 100%,
calc(100% - 6px) 100%, calc(100% - 6px) 100%,
calc(100% - 6px) calc(100% - 6px), calc(100% - 6px) calc(100% - 6px),
100% calc(100% - 6px), 100% calc(100% - 6px),
100% 6px, 100% 6px,
calc(100% - 6px) 6px, calc(100% - 6px) 6px,
calc(100% - 6px) 0px, calc(100% - 6px) 0px,
6px 0px, 6px 0px,
6px 6px, 6px 6px,
0px 6px 0px 6px
); );
display: flex; display: flex;
align-items: center; align-items: center;
gap: 0.35rem; gap: 0.35rem;
transition: filter 0.2s ease;
}
.box:hover {
filter: brightness(120%);
}
.box svg {
flex-shrink: 0;
} }
a, a,
a:visited, a:visited,
a:active { a:active {
color: var(--theme-accent-third); color: var(--theme-accent-third);
text-decoration: none; text-decoration: none;
} }
a:hover { a:hover {
text-decoration: 2px underline; text-decoration: 2px underline;
text-underline-offset: 3px; text-underline-offset: 3px;
} }
#header { #header {
position: relative; position: relative;
display: flex; display: flex;
flex-direction: row; flex-direction: row;
justify-content: space-between; justify-content: space-between;
z-index: 1; z-index: 1;
} }
#header, #header,
#header #left, #header #left,
#header #links { #header #links {
flex-wrap: wrap; flex-wrap: wrap;
} }
#header #left, #header #left,
#header #links { #header #links {
display: flex; display: flex;
flex-direction: row; flex-direction: row;
align-items: center; align-items: center;
gap: 0.5rem; gap: 0.5rem;
margin: 0; margin: 0;
padding: 0; padding: 0;
} }
#header img { #header img {
width: auto; width: auto;
height: 1.5em; height: 1.5em;
} }
nav .module { nav .module {
clip-path: polygon( clip-path: polygon(
0px calc(100% - 6px), 0px calc(100% - 6px),
6px calc(100% - 6px), 6px calc(100% - 6px),
6px 100%, 6px 100%,
calc(100% - 6px) 100%, calc(100% - 6px) 100%,
calc(100% - 6px) calc(100% - 6px), calc(100% - 6px) calc(100% - 6px),
100% calc(100% - 6px), 100% calc(100% - 6px),
100% 6px, 100% 6px,
calc(100% - 6px) 6px, calc(100% - 6px) 6px,
calc(100% - 6px) 0px, calc(100% - 6px) 0px,
6px 0px, 6px 0px,
6px 6px, 6px 6px,
0px 6px 0px 6px
); );
padding: 0.5em 1.25em; padding: 0.5em 1.25em;
box-sizing: border-box; box-sizing: border-box;
background-color: var(--theme-bg-secondary); background-color: var(--theme-bg-secondary);
} }
#logo { #logo {
display: flex; display: flex;
align-items: center; align-items: center;
padding: 0.5em; padding: 0.5em;
} }
.labeled-icons { .labeled-icons {
margin: 0; margin: 0;
padding: 0; padding: 0;
list-style: none; list-style: none;
display: flex; display: flex;
flex-direction: row; flex-direction: row;
flex-wrap: wrap; flex-wrap: wrap;
gap: 0.35rem; gap: 0.35rem;
margin-top: 0.25rem; margin-top: 0.25rem;
} }
.labeled-icons.full { .labeled-icons.full {
flex-direction: column; flex-direction: column;
& > * { & > * {
flex-grow: 1; flex-grow: 1;
} }
& .box { & .box {
width: 100%; width: 100%;
} }
} }
.labeled-icons.b88x31 { .labeled-icons.b88x31 {
gap: 0.35rem; gap: 0.35rem;
} }
.labeled-icons.b88x31 a { .labeled-icons.b88x31 a {
display: flex; display: flex;
width: 88px; width: 88px;
height: 31px; height: 31px;
background: var(--theme-bg-tertiary); background: var(--theme-bg-tertiary);
color: var(--theme-fg-alt); color: var(--theme-fg-alt);
justify-content: center; justify-content: center;
} }
.labeled-icons.b88x31 a, .labeled-icons.b88x31 a,
#muxiepuff { #muxiepuff {
clip-path: polygon( clip-path: polygon(
0px calc(100% - 3px), 0px calc(100% - 3px),
3px calc(100% - 3px), 3px calc(100% - 3px),
3px 100%, 3px 100%,
calc(100% - 3px) 100%, calc(100% - 3px) 100%,
calc(100% - 3px) calc(100% - 3px), calc(100% - 3px) calc(100% - 3px),
100% calc(100% - 3px), 100% calc(100% - 3px),
100% 3px, 100% 3px,
calc(100% - 3px) 3px, calc(100% - 3px) 3px,
calc(100% - 3px) 0px, calc(100% - 3px) 0px,
3px 0px, 3px 0px,
3px 3px, 3px 3px,
0px 3px 0px 3px
); );
} }
.labeled-icons.b88x31 li { .labeled-icons.b88x31 li {
transition: filter 0.2s ease; transition: filter 0.2s ease;
} }
.labeled-icons.b88x31 li:hover { .labeled-icons.b88x31 li:hover {
filter: brightness(0.5); filter: brightness(0.5);
} }
.labeled-icons.b88x31 img { .labeled-icons.b88x31 img {
image-rendering: pixelated; image-rendering: pixelated;
} }
.labeled-icons.b88x31 img { .labeled-icons.b88x31 img {
image-rendering: pixelated; image-rendering: pixelated;
} }
#extra { #extra {
display: flex; display: flex;
list-style: none; list-style: none;
flex-wrap: wrap; flex-wrap: wrap;
align-items: center; align-items: center;
justify-content: space-between; justify-content: space-between;
padding: 0; padding: 0;
} }
#extra svg { #extra svg {
width: 15rem; width: 15rem;
max-width: 100%; max-width: 100%;
height: 15rem; height: 15rem;
} }
@media (max-width: 768px) { @media (max-width: 768px) {
html { html {
font-size: 18px; font-size: 18px;
} }
.section {
padding: 1.5rem;
}
#extra {
justify-content: center;
gap: 1rem;
}
#extra svg {
width: 8rem;
height: 8rem;
}
} }
@media (max-width: 480px) { @media (max-width: 480px) {
html { html {
font-size: 16px; font-size: 16px;
} }
body { body {
padding: 8px; padding: 8px;
} }
}
@media (max-width: 768px) { .section {
.section { padding: 1rem;
padding: 1.5rem; }
}
}
@media (max-width: 480px) { .box {
.section { padding: 0.4rem 0.8rem;
padding: 1rem; font-size: 0.9em;
} }
}
@media (max-width: 480px) { .box svg {
.box { width: 20px;
padding: 0.4rem 0.8rem; height: 20px;
font-size: 0.9em; }
}
.box svg { .title {
width: 20px; font-size: 1.1rem;
height: 20px; }
}
}
@media (max-width: 480px) { #extra svg {
.title { width: 6rem;
font-size: 1.1rem; height: 6rem;
} }
}
@media (max-width: 768px) { .alt-font {
#extra { font-size: 14px;
justify-content: center; }
gap: 1rem;
}
#extra svg {
width: 8rem;
height: 8rem;
}
}
@media (max-width: 480px) {
#extra svg {
width: 6rem;
height: 6rem;
}
}
@media (max-width: 480px) {
.alt-font {
font-size: 14px;
}
} }
#muxiepuff { #muxiepuff {
display: flex; display: flex;
padding: 0; padding: 0;
background: none; background: none;
outline: none; outline: none;
border: none; border: none;
cursor: pointer; cursor: pointer;
} }
.name-scroller { .name-scroller {
display: inline-block; display: inline-block;
position: relative; position: relative;
vertical-align: middle; vertical-align: middle;
margin-top: -3px; margin-top: -3px;
overflow: hidden; overflow: hidden;
} }
.name-wrapper { .name-wrapper {
transition: transition: transform 0.3s ease-in-out, opacity 0.3s ease-in-out;
transform 0.3s ease-in-out, transform: translateY(0);
opacity 0.3s ease-in-out; opacity: 1;
transform: translateY(0);
opacity: 1;
} }
.name-wrapper.animating { .name-wrapper.animating {
transform: translateY(-100%); transform: translateY(-100%);
opacity: 0; opacity: 0;
} }
.name-wrapper:not(.animating) { .name-wrapper:not(.animating) {
transform: translateY(0); transform: translateY(0);
opacity: 1; opacity: 1;
} }
.name-text { .name-text {
position: relative; position: relative;
display: inline-block; display: inline-block;
} }
.name-underline { .name-underline {
position: absolute; position: absolute;
bottom: 2px; bottom: 2px;
left: 0; left: 0;
width: 100%; width: 100%;
height: 2px; height: 2px;
background: currentColor; background: currentColor;
box-shadow: 0 0 8px currentColor; box-shadow: 0 0 8px currentColor;
animation: pulse 2s ease-in-out infinite; animation: pulse 2s ease-in-out infinite;
} }
@keyframes pulse { @keyframes pulse {
0%, 0%,
100% { 100% {
opacity: 1; opacity: 1;
} }
50% { 50% {
opacity: 0.5; opacity: 0.5;
} }
} }
.inline-code { .inline-code {
font-family: "Share Tech Mono", "Share Tech", monospace; font-family: monospace, "Jersey 15", sans-serif;
font-size: 0.75em; font-size: 0.75em;
background-color: var(--theme-border); background-color: var(--theme-border);
padding: 1px; padding: 1px;
display: inline-block; display: inline-block;
clip-path: polygon( clip-path: polygon(
0px calc(100% - 2px), 0px calc(100% - 2px),
2px calc(100% - 2px), 2px calc(100% - 2px),
2px 100%, 2px 100%,
calc(100% - 2px) 100%, calc(100% - 2px) 100%,
calc(100% - 2px) calc(100% - 2px), calc(100% - 2px) calc(100% - 2px),
100% calc(100% - 2px), 100% calc(100% - 2px),
100% 2px, 100% 2px,
calc(100% - 2px) 2px, calc(100% - 2px) 2px,
calc(100% - 2px) 0px, calc(100% - 2px) 0px,
2px 0px, 2px 0px,
2px 2px, 2px 2px,
0px 2px 0px 2px
); );
line-height: 1.6; line-height: 1.6;
vertical-align: middle; vertical-align: middle;
cursor: pointer;
outline: none;
border: none;
} }
.inline-code > span { .inline-code > span {
display: block; display: block;
background-color: var(--theme-bg-tertiary); background-color: var(--theme-bg-tertiary);
color: var(--theme-fg); color: var(--theme-fg);
padding: 0.15em 0.4em; padding: 0.15em 0.4em;
clip-path: polygon( clip-path: polygon(
0px calc(100% - 2px), 0px calc(100% - 2px),
2px calc(100% - 2px), 2px calc(100% - 2px),
2px 100%, 2px 100%,
calc(100% - 2px) 100%, calc(100% - 2px) 100%,
calc(100% - 2px) calc(100% - 2px), calc(100% - 2px) calc(100% - 2px),
100% calc(100% - 2px), 100% calc(100% - 2px),
100% 2px, 100% 2px,
calc(100% - 2px) 2px, calc(100% - 2px) 2px,
calc(100% - 2px) 0px, calc(100% - 2px) 0px,
2px 0px, 2px 0px,
2px 2px, 2px 2px,
0px 2px 0px 2px
); );
font-weight: 500; font-weight: 500;
} }
p, p,
.title { .title {
transform: translateZ(0px); transform: translateZ(0px);
-webkit-transform: translateZ(0px); -webkit-transform: translateZ(0px);
will-change: transform; will-change: transform;
} }
hr { hr {
width: 100%; width: 100%;
border: none; border: none;
border-top: 2px solid var(--theme-border); border-top: 2px solid var(--theme-border);
} }
footer.section { footer.section {
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
gap: 1ch; gap: 1ch;
} }
footer p { footer p {
text-align: center; text-align: center;
gap: 1ch; gap: 1ch;
margin: 0; margin: 0;
padding: 0; padding: 0;
} }
footer a { footer a {
overflow-wrap: anywhere; overflow-wrap: anywhere;
word-break: break-word; word-break: break-word;
} }
footer #f-heart { footer #f-heart {
color: var(--theme-accent-third); color: var(--theme-accent-third);
vertical-align: middle; vertical-align: middle;
} }

View file

@ -7,16 +7,16 @@ import { ComponentChildren, h } from "preact";
import { LinkIcon } from "./Icon.tsx"; import { LinkIcon } from "./Icon.tsx";
interface PolygonBoxProps { interface PolygonBoxProps {
as?: keyof HTMLElementTagNameMap; as?: keyof HTMLElementTagNameMap;
children?: ComponentChildren; children?: ComponentChildren;
[key: string]: any; [key: string]: any;
} }
export default function Box( export default function Box(
{ as: Tag = "span", class: className, children, ...props }: PolygonBoxProps, { as: Tag = "span", class: className, children, ...props }: PolygonBoxProps,
) { ) {
const content = Tag === "a" const content = Tag === "a"
? [children, h(LinkIcon, { size: 16, class: "link-icon" })] ? [children, h(LinkIcon, { size: 16, class: "link-icon" })]
: children; : children;
return h(Tag, { class: `box ${className || ""}`, ...props }, content); return h(Tag, { class: `box ${className || ""}`, ...props }, content);
} }

View file

@ -7,23 +7,25 @@ import { HeartFilledIcon } from "./Icon.tsx";
import Link from "./Link.tsx"; import Link from "./Link.tsx";
export default function Footer() { export default function Footer() {
return ( return (
<footer class="section"> <footer class="section">
<p class="alt alt-font"> <p class="alt alt-font">
Made with <HeartFilledIcon id="f-heart" /> · Source code available at{" "} Made with <HeartFilledIcon id="f-heart" /> · Source code available at
<Link href="https://git.acpi.at/mux/web">git.acpi.at</Link> under the{" "} {" "}
<Link href="https://spdx.org/licenses/AGPL-3.0-or-later.html"> <Link href="https://git.acpi.at/mux/web">git.acpi.at</Link> under the
GNU Affero General Public License v3.0 {" "}
</Link> <Link href="https://spdx.org/licenses/AGPL-3.0-or-later.html">
, with all site content licensed under{" "} GNU Affero General Public License v3.0
<Link href="https://creativecommons.org/licenses/by-sa/4.0/"> </Link>
CC BY-SA 4.0 , with all site content licensed under{" "}
</Link> <Link href="https://creativecommons.org/licenses/by-sa/4.0/">
. CC BY-SA 4.0
</p> </Link>
<p class="alt alt-font"> .
© 2025 muxiepuff Powered by FreeBSD and pixels </p>
</p> <p class="alt alt-font">
</footer> © 2025 muxiepuff Powered by FreeBSD and pixels
); </p>
</footer>
);
} }

View file

@ -4,32 +4,38 @@
*/ */
export default function Header() { export default function Header() {
return ( return (
<nav id="header"> <nav id="header" aria-label="Main navigation">
<div id="left"> <div id="left">
<a id="logo" href="/" class="module"> <a
<img id="logo"
src="/bnuy.webp" href="/"
width="380" class="module"
height="260" data-current="true"
alt="acpi.at" aria-current="page"
style="filter: grayscale(0.6)" >
/> <img
</a> src="/bnuy.webp"
{ width="380"
// <ul id="links"> height="260"
// <li class="module"> alt="acpi.at"
// <a href="/projects">Projects</a> style="filter: grayscale(0.6)"
// </li> />
// <li class="module"> </a>
// <a href="/blog">Blog</a> {
// </li> // <ul id="links">
// </ul> // <li class="module">
} // <a href="/projects">Projects</a>
</div> // </li>
{ // <li class="module">
// <div id="right" class="module" /> // <a href="/blog">Blog</a>
} // </li>
</nav> // </ul>
); }
</div>
{
// <div id="right" class="module" />
}
</nav>
);
} }

View file

@ -4,439 +4,455 @@
*/ */
interface IconProps { interface IconProps {
size?: number; size?: number;
[key: string]: any; [key: string]: any;
} }
export function LinkIcon({ size = 24, ...props }: IconProps) { export function LinkIcon({ size = 24, ...props }: IconProps) {
return ( return (
<svg <svg
fill="none" fill="none"
xmlns="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24" viewBox="0 0 24 24"
width={size} width={size}
height={size} height={size}
{...props} {...props}
> >
<path <path
d="M21 11V3h-8v2h4v2h-2v2h-2v2h-2v2H9v2h2v-2h2v-2h2V9h2V7h2v4h2zM11 5H3v16h16v-8h-2v6H5V7h6V5z" d="M21 11V3h-8v2h4v2h-2v2h-2v2h-2v2H9v2h2v-2h2v-2h2V9h2V7h2v4h2zM11 5H3v16h16v-8h-2v6H5V7h6V5z"
fill="currentColor" fill="currentColor"
/> />
</svg> </svg>
); );
} }
export function PersonIcon({ size = 24, ...props }: IconProps) { export function PersonIcon({ size = 24, ...props }: IconProps) {
return ( return (
<svg <svg
fill="none" fill="none"
xmlns="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24" viewBox="0 0 24 24"
width={size} width={size}
height={size} height={size}
{...props} {...props}
> >
<path <path
d="M10 2h4v4h-4V2zM7 7h10v2h-2v13h-2v-6h-2v6H9V9H7V7zM5 5v2h2V5H5zm0 0H3V3h2v2zm14 0v2h-2V5h2zm0 0V3h2v2h-2z" d="M10 2h4v4h-4V2zM7 7h10v2h-2v13h-2v-6h-2v6H9V9H7V7zM5 5v2h2V5H5zm0 0H3V3h2v2zm14 0v2h-2V5h2zm0 0V3h2v2h-2z"
fill="currentColor" fill="currentColor"
/> />
</svg> </svg>
); );
} }
export function HeartIcon({ size = 24, ...props }: IconProps) { export function HeartIcon({ size = 24, ...props }: IconProps) {
return ( return (
<svg <svg
fill="none" fill="none"
xmlns="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24" viewBox="0 0 24 24"
width={size} width={size}
height={size} height={size}
{...props} {...props}
> >
<path <path
d="M9 2H5v2H3v2H1v6h2v2h2v2h2v2h2v2h2v2h2v-2h2v-2h2v-2h2v-2h2v-2h2V6h-2V4h-2V2h-4v2h-2v2h-2V4H9V2zm0 2v2h2v2h2V6h2V4h4v2h2v6h-2v2h-2v2h-2v2h-2v2h-2v-2H9v-2H7v-2H5v-2H3V6h2V4h4z" d="M9 2H5v2H3v2H1v6h2v2h2v2h2v2h2v2h2v2h2v-2h2v-2h2v-2h2v-2h2v-2h2V6h-2V4h-2V2h-4v2h-2v2h-2V4H9V2zm0 2v2h2v2h2V6h2V4h4v2h2v6h-2v2h-2v2h-2v2h-2v2h-2v-2H9v-2H7v-2H5v-2H3V6h2V4h4z"
fill="currentColor" fill="currentColor"
/> />
</svg> </svg>
); );
} }
export function CommentIcon({ size = 24, ...props }: IconProps) { export function CommentIcon({ size = 24, ...props }: IconProps) {
return ( return (
<svg <svg
fill="none" fill="none"
xmlns="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24" viewBox="0 0 24 24"
width={size} width={size}
height={size} height={size}
{...props} {...props}
> >
<path <path
d="M22 2H2v14h2V4h16v12h-8v2h-2v2H8v-4H2v2h4v4h4v-2h2v-2h10V2z" d="M22 2H2v14h2V4h16v12h-8v2h-2v2H8v-4H2v2h4v4h4v-2h2v-2h10V2z"
fill="currentColor" fill="currentColor"
/> />
</svg> </svg>
); );
} }
export function AttachmentIcon({ size = 24, ...props }: IconProps) { export function AttachmentIcon({ size = 24, ...props }: IconProps) {
return ( return (
<svg <svg
fill="none" fill="none"
xmlns="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24" viewBox="0 0 24 24"
width={size} width={size}
height={size} height={size}
{...props} {...props}
> >
<path <path
d="M7 5v14H5V3h14v18H9V7h6v10h-2V9h-2v10h6V5H7z" d="M7 5v14H5V3h14v18H9V7h6v10h-2V9h-2v10h6V5H7z"
fill="currentColor" fill="currentColor"
/> />
</svg> </svg>
); );
} }
export function LabelIcon({ size = 24, ...props }: IconProps) { export function LabelIcon({ size = 24, ...props }: IconProps) {
return ( return (
<svg <svg
fill="none" fill="none"
xmlns="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24" viewBox="0 0 24 24"
width={size} width={size}
height={size} height={size}
{...props} {...props}
> >
<path <path
d="M12 2H2v10h2v2h2v2h2v2h2v2h2v2h2v-2h2v-2h2v-2h2v-2h2v-2h-2v-2h-2V8h-2V6h-2V4h-2V2zm0 2v2h2v2h2v2h2v2h2v2h-2v2h-2v2h-2v2h-2v-2h-2v-2H8v-2H6v-2H4V4h8zM6 6h2v2H6V6z" d="M12 2H2v10h2v2h2v2h2v2h2v2h2v2h2v-2h2v-2h2v-2h2v-2h2v-2h-2v-2h-2V8h-2V6h-2V4h-2V2zm0 2v2h2v2h2v2h2v2h2v2h-2v2h-2v2h-2v2h-2v-2h-2v-2H8v-2H6v-2H4V4h8zM6 6h2v2H6V6z"
fill="currentColor" fill="currentColor"
/> />
</svg> </svg>
); );
} }
export function DiscordIcon({ size = 24, ...props }: IconProps) { export function DiscordIcon({ size = 24, ...props }: IconProps) {
return ( return (
<svg <svg
xmlns="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24" viewBox="0 0 24 24"
width={size} width={size}
height={size} height={size}
{...props} {...props}
> >
<title>Discord</title> <title>Discord</title>
<path <path
d="M20.317 4.3698a19.7913 19.7913 0 00-4.8851-1.5152.0741.0741 0 00-.0785.0371c-.211.3753-.4447.8648-.6083 1.2495-1.8447-.2762-3.68-.2762-5.4868 0-.1636-.3933-.4058-.8742-.6177-1.2495a.077.077 0 00-.0785-.037 19.7363 19.7363 0 00-4.8852 1.515.0699.0699 0 00-.0321.0277C.5334 9.0458-.319 13.5799.0992 18.0578a.0824.0824 0 00.0312.0561c2.0528 1.5076 4.0413 2.4228 5.9929 3.0294a.0777.0777 0 00.0842-.0276c.4616-.6304.8731-1.2952 1.226-1.9942a.076.076 0 00-.0416-.1057c-.6528-.2476-1.2743-.5495-1.8722-.8923a.077.077 0 01-.0076-.1277c.1258-.0943.2517-.1923.3718-.2914a.0743.0743 0 01.0776-.0105c3.9278 1.7933 8.18 1.7933 12.0614 0a.0739.0739 0 01.0785.0095c.1202.099.246.1981.3728.2924a.077.077 0 01-.0066.1276 12.2986 12.2986 0 01-1.873.8914.0766.0766 0 00-.0407.1067c.3604.698.7719 1.3628 1.225 1.9932a.076.076 0 00.0842.0286c1.961-.6067 3.9495-1.5219 6.0023-3.0294a.077.077 0 00.0313-.0552c.5004-5.177-.8382-9.6739-3.5485-13.6604a.061.061 0 00-.0312-.0286zM8.02 15.3312c-1.1825 0-2.1569-1.0857-2.1569-2.419 0-1.3332.9555-2.4189 2.157-2.4189 1.2108 0 2.1757 1.0952 2.1568 2.419 0 1.3332-.9555 2.4189-2.1569 2.4189zm7.9748 0c-1.1825 0-2.1569-1.0857-2.1569-2.419 0-1.3332.9554-2.4189 2.1569-2.4189 1.2108 0 2.1757 1.0952 2.1568 2.419 0 1.3332-.946 2.4189-2.1568 2.4189Z" d="M20.317 4.3698a19.7913 19.7913 0 00-4.8851-1.5152.0741.0741 0 00-.0785.0371c-.211.3753-.4447.8648-.6083 1.2495-1.8447-.2762-3.68-.2762-5.4868 0-.1636-.3933-.4058-.8742-.6177-1.2495a.077.077 0 00-.0785-.037 19.7363 19.7363 0 00-4.8852 1.515.0699.0699 0 00-.0321.0277C.5334 9.0458-.319 13.5799.0992 18.0578a.0824.0824 0 00.0312.0561c2.0528 1.5076 4.0413 2.4228 5.9929 3.0294a.0777.0777 0 00.0842-.0276c.4616-.6304.8731-1.2952 1.226-1.9942a.076.076 0 00-.0416-.1057c-.6528-.2476-1.2743-.5495-1.8722-.8923a.077.077 0 01-.0076-.1277c.1258-.0943.2517-.1923.3718-.2914a.0743.0743 0 01.0776-.0105c3.9278 1.7933 8.18 1.7933 12.0614 0a.0739.0739 0 01.0785.0095c.1202.099.246.1981.3728.2924a.077.077 0 01-.0066.1276 12.2986 12.2986 0 01-1.873.8914.0766.0766 0 00-.0407.1067c.3604.698.7719 1.3628 1.225 1.9932a.076.076 0 00.0842.0286c1.961-.6067 3.9495-1.5219 6.0023-3.0294a.077.077 0 00.0313-.0552c.5004-5.177-.8382-9.6739-3.5485-13.6604a.061.061 0 00-.0312-.0286zM8.02 15.3312c-1.1825 0-2.1569-1.0857-2.1569-2.419 0-1.3332.9555-2.4189 2.157-2.4189 1.2108 0 2.1757 1.0952 2.1568 2.419 0 1.3332-.9555 2.4189-2.1569 2.4189zm7.9748 0c-1.1825 0-2.1569-1.0857-2.1569-2.419 0-1.3332.9554-2.4189 2.1569-2.4189 1.2108 0 2.1757 1.0952 2.1568 2.419 0 1.3332-.946 2.4189-2.1568 2.4189Z"
fill="currentColor" fill="currentColor"
/> />
</svg> </svg>
); );
} }
export function SignalIcon({ size = 24, ...props }: IconProps) { export function SignalIcon({ size = 24, ...props }: IconProps) {
return ( return (
<svg <svg
xmlns="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24" viewBox="0 0 24 24"
width={size} width={size}
height={size} height={size}
{...props} {...props}
> >
<title>Signal</title> <title>Signal</title>
<path <path
d="M12 0q-.934 0-1.83.139l.17 1.111a11 11 0 0 1 3.32 0l.172-1.111A12 12 0 0 0 12 0M9.152.34A12 12 0 0 0 5.77 1.742l.584.961a10.8 10.8 0 0 1 3.066-1.27zm5.696 0-.268 1.094a10.8 10.8 0 0 1 3.066 1.27l.584-.962A12 12 0 0 0 14.848.34M12 2.25a9.75 9.75 0 0 0-8.539 14.459c.074.134.1.292.064.441l-1.013 4.338 4.338-1.013a.62.62 0 0 1 .441.064A9.7 9.7 0 0 0 12 21.75c5.385 0 9.75-4.365 9.75-9.75S17.385 2.25 12 2.25m-7.092.068a12 12 0 0 0-2.59 2.59l.909.664a11 11 0 0 1 2.345-2.345zm14.184 0-.664.909a11 11 0 0 1 2.345 2.345l.909-.664a12 12 0 0 0-2.59-2.59M1.742 5.77A12 12 0 0 0 .34 9.152l1.094.268a10.8 10.8 0 0 1 1.269-3.066zm20.516 0-.961.584a10.8 10.8 0 0 1 1.27 3.066l1.093-.268a12 12 0 0 0-1.402-3.383M.138 10.168A12 12 0 0 0 0 12q0 .934.139 1.83l1.111-.17A11 11 0 0 1 1.125 12q0-.848.125-1.66zm23.723.002-1.111.17q.125.812.125 1.66c0 .848-.042 1.12-.125 1.66l1.111.172a12.1 12.1 0 0 0 0-3.662M1.434 14.58l-1.094.268a12 12 0 0 0 .96 2.591l-.265 1.14 1.096.255.36-1.539-.188-.365a10.8 10.8 0 0 1-.87-2.35m21.133 0a10.8 10.8 0 0 1-1.27 3.067l.962.584a12 12 0 0 0 1.402-3.383zm-1.793 3.848a11 11 0 0 1-2.345 2.345l.664.909a12 12 0 0 0 2.59-2.59zm-19.959 1.1L.357 21.48a1.8 1.8 0 0 0 2.162 2.161l1.954-.455-.256-1.095-1.953.455a.675.675 0 0 1-.81-.81l.454-1.954zm16.832 1.769a10.8 10.8 0 0 1-3.066 1.27l.268 1.093a12 12 0 0 0 3.382-1.402zm-10.94.213-1.54.36.256 1.095 1.139-.266c.814.415 1.683.74 2.591.961l.268-1.094a10.8 10.8 0 0 1-2.35-.869zm3.634 1.24-.172 1.111a12.1 12.1 0 0 0 3.662 0l-.17-1.111q-.812.125-1.66.125a11 11 0 0 1-1.66-.125" d="M12 0q-.934 0-1.83.139l.17 1.111a11 11 0 0 1 3.32 0l.172-1.111A12 12 0 0 0 12 0M9.152.34A12 12 0 0 0 5.77 1.742l.584.961a10.8 10.8 0 0 1 3.066-1.27zm5.696 0-.268 1.094a10.8 10.8 0 0 1 3.066 1.27l.584-.962A12 12 0 0 0 14.848.34M12 2.25a9.75 9.75 0 0 0-8.539 14.459c.074.134.1.292.064.441l-1.013 4.338 4.338-1.013a.62.62 0 0 1 .441.064A9.7 9.7 0 0 0 12 21.75c5.385 0 9.75-4.365 9.75-9.75S17.385 2.25 12 2.25m-7.092.068a12 12 0 0 0-2.59 2.59l.909.664a11 11 0 0 1 2.345-2.345zm14.184 0-.664.909a11 11 0 0 1 2.345 2.345l.909-.664a12 12 0 0 0-2.59-2.59M1.742 5.77A12 12 0 0 0 .34 9.152l1.094.268a10.8 10.8 0 0 1 1.269-3.066zm20.516 0-.961.584a10.8 10.8 0 0 1 1.27 3.066l1.093-.268a12 12 0 0 0-1.402-3.383M.138 10.168A12 12 0 0 0 0 12q0 .934.139 1.83l1.111-.17A11 11 0 0 1 1.125 12q0-.848.125-1.66zm23.723.002-1.111.17q.125.812.125 1.66c0 .848-.042 1.12-.125 1.66l1.111.172a12.1 12.1 0 0 0 0-3.662M1.434 14.58l-1.094.268a12 12 0 0 0 .96 2.591l-.265 1.14 1.096.255.36-1.539-.188-.365a10.8 10.8 0 0 1-.87-2.35m21.133 0a10.8 10.8 0 0 1-1.27 3.067l.962.584a12 12 0 0 0 1.402-3.383zm-1.793 3.848a11 11 0 0 1-2.345 2.345l.664.909a12 12 0 0 0 2.59-2.59zm-19.959 1.1L.357 21.48a1.8 1.8 0 0 0 2.162 2.161l1.954-.455-.256-1.095-1.953.455a.675.675 0 0 1-.81-.81l.454-1.954zm16.832 1.769a10.8 10.8 0 0 1-3.066 1.27l.268 1.093a12 12 0 0 0 3.382-1.402zm-10.94.213-1.54.36.256 1.095 1.139-.266c.814.415 1.683.74 2.591.961l.268-1.094a10.8 10.8 0 0 1-2.35-.869zm3.634 1.24-.172 1.111a12.1 12.1 0 0 0 3.662 0l-.17-1.111q-.812.125-1.66.125a11 11 0 0 1-1.66-.125"
fill="currentColor" fill="currentColor"
/> />
</svg> </svg>
); );
} }
export function LastfmIcon({ size = 24, ...props }: IconProps) { export function LastfmIcon({ size = 24, ...props }: IconProps) {
return ( return (
<svg <svg
xmlns="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24" viewBox="0 0 24 24"
width={size} width={size}
height={size} height={size}
{...props} {...props}
> >
<title>Last.fm</title> <title>Last.fm</title>
<path <path
d="M10.584 17.21l-.88-2.392s-1.43 1.594-3.573 1.594c-1.897 0-3.244-1.649-3.244-4.288 0-3.382 1.704-4.591 3.381-4.591 2.42 0 3.189 1.567 3.849 3.574l.88 2.749c.88 2.666 2.529 4.81 7.285 4.81 3.409 0 5.718-1.044 5.718-3.793 0-2.227-1.265-3.381-3.63-3.931l-1.758-.385c-1.21-.275-1.567-.77-1.567-1.595 0-.934.742-1.484 1.952-1.484 1.32 0 2.034.495 2.144 1.677l2.749-.33c-.22-2.474-1.924-3.492-4.729-3.492-2.474 0-4.893.935-4.893 3.932 0 1.87.907 3.051 3.189 3.601l1.87.44c1.402.33 1.869.907 1.869 1.704 0 1.017-.99 1.43-2.86 1.43-2.776 0-3.93-1.457-4.59-3.464l-.907-2.75c-1.155-3.573-2.997-4.893-6.653-4.893C2.144 5.333 0 7.89 0 12.233c0 4.18 2.144 6.434 5.993 6.434 3.106 0 4.591-1.457 4.591-1.457z" d="M10.584 17.21l-.88-2.392s-1.43 1.594-3.573 1.594c-1.897 0-3.244-1.649-3.244-4.288 0-3.382 1.704-4.591 3.381-4.591 2.42 0 3.189 1.567 3.849 3.574l.88 2.749c.88 2.666 2.529 4.81 7.285 4.81 3.409 0 5.718-1.044 5.718-3.793 0-2.227-1.265-3.381-3.63-3.931l-1.758-.385c-1.21-.275-1.567-.77-1.567-1.595 0-.934.742-1.484 1.952-1.484 1.32 0 2.034.495 2.144 1.677l2.749-.33c-.22-2.474-1.924-3.492-4.729-3.492-2.474 0-4.893.935-4.893 3.932 0 1.87.907 3.051 3.189 3.601l1.87.44c1.402.33 1.869.907 1.869 1.704 0 1.017-.99 1.43-2.86 1.43-2.776 0-3.93-1.457-4.59-3.464l-.907-2.75c-1.155-3.573-2.997-4.893-6.653-4.893C2.144 5.333 0 7.89 0 12.233c0 4.18 2.144 6.434 5.993 6.434 3.106 0 4.591-1.457 4.591-1.457z"
fill="currentColor" fill="currentColor"
/> />
</svg> </svg>
); );
} }
export function BlueskyIcon({ size = 24, ...props }: IconProps) { export function BlueskyIcon({ size = 24, ...props }: IconProps) {
return ( return (
<svg <svg
xmlns="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24" viewBox="0 0 24 24"
width={size} width={size}
height={size} height={size}
{...props} {...props}
> >
<title>Bluesky</title> <title>Bluesky</title>
<path <path
d="M5.202 2.857C7.954 4.922 10.913 9.11 12 11.358c1.087-2.247 4.046-6.436 6.798-8.501C20.783 1.366 24 .213 24 3.883c0 .732-.42 6.156-.667 7.037-.856 3.061-3.978 3.842-6.755 3.37 4.854.826 6.089 3.562 3.422 6.299-5.065 5.196-7.28-1.304-7.847-2.97-.104-.305-.152-.448-.153-.327 0-.121-.05.022-.153.327-.568 1.666-2.782 8.166-7.847 2.97-2.667-2.737-1.432-5.473 3.422-6.3-2.777.473-5.899-.308-6.755-3.369C.42 10.04 0 4.615 0 3.883c0-3.67 3.217-2.517 5.202-1.026" d="M5.202 2.857C7.954 4.922 10.913 9.11 12 11.358c1.087-2.247 4.046-6.436 6.798-8.501C20.783 1.366 24 .213 24 3.883c0 .732-.42 6.156-.667 7.037-.856 3.061-3.978 3.842-6.755 3.37 4.854.826 6.089 3.562 3.422 6.299-5.065 5.196-7.28-1.304-7.847-2.97-.104-.305-.152-.448-.153-.327 0-.121-.05.022-.153.327-.568 1.666-2.782 8.166-7.847 2.97-2.667-2.737-1.432-5.473 3.422-6.3-2.777.473-5.899-.308-6.755-3.369C.42 10.04 0 4.615 0 3.883c0-3.67 3.217-2.517 5.202-1.026"
fill="currentColor" fill="currentColor"
/> />
</svg> </svg>
); );
} }
export function MastodonIcon({ size = 24, ...props }: IconProps) { export function MastodonIcon({ size = 24, ...props }: IconProps) {
return ( return (
<svg <svg
xmlns="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24" viewBox="0 0 24 24"
width={size} width={size}
height={size} height={size}
{...props} {...props}
> >
<title>Mastodon / Fediverse</title> <title>Mastodon / Fediverse</title>
<path <path
d="M23.268 5.313c-.35-2.578-2.617-4.61-5.304-5.004C17.51.242 15.792 0 11.813 0h-.03c-3.98 0-4.835.242-5.288.309C3.882.692 1.496 2.518.917 5.127.64 6.412.61 7.837.661 9.143c.074 1.874.088 3.745.26 5.611.118 1.24.325 2.47.62 3.68.55 2.237 2.777 4.098 4.96 4.857 2.336.792 4.849.923 7.256.38.265-.061.527-.132.786-.213.585-.184 1.27-.39 1.774-.753a.057.057 0 0 0 .023-.043v-1.809a.052.052 0 0 0-.02-.041.053.053 0 0 0-.046-.01 20.282 20.282 0 0 1-4.709.545c-2.73 0-3.463-1.284-3.674-1.818a5.593 5.593 0 0 1-.319-1.433.053.053 0 0 1 .066-.054c1.517.363 3.072.546 4.632.546.376 0 .75 0 1.125-.01 1.57-.044 3.224-.124 4.768-.422.038-.008.077-.015.11-.024 2.435-.464 4.753-1.92 4.989-5.604.008-.145.03-1.52.03-1.67.002-.512.167-3.63-.024-5.545zm-3.748 9.195h-2.561V8.29c0-1.309-.55-1.976-1.67-1.976-1.23 0-1.846.79-1.846 2.35v3.403h-2.546V8.663c0-1.56-.617-2.35-1.848-2.35-1.112 0-1.668.668-1.67 1.977v6.218H4.822V8.102c0-1.31.337-2.35 1.011-3.12.696-.77 1.608-1.164 2.74-1.164 1.311 0 2.302.5 2.962 1.498l.638 1.06.638-1.06c.66-.999 1.65-1.498 2.96-1.498 1.13 0 2.043.395 2.74 1.164.675.77 1.012 1.81 1.012 3.12z" d="M23.268 5.313c-.35-2.578-2.617-4.61-5.304-5.004C17.51.242 15.792 0 11.813 0h-.03c-3.98 0-4.835.242-5.288.309C3.882.692 1.496 2.518.917 5.127.64 6.412.61 7.837.661 9.143c.074 1.874.088 3.745.26 5.611.118 1.24.325 2.47.62 3.68.55 2.237 2.777 4.098 4.96 4.857 2.336.792 4.849.923 7.256.38.265-.061.527-.132.786-.213.585-.184 1.27-.39 1.774-.753a.057.057 0 0 0 .023-.043v-1.809a.052.052 0 0 0-.02-.041.053.053 0 0 0-.046-.01 20.282 20.282 0 0 1-4.709.545c-2.73 0-3.463-1.284-3.674-1.818a5.593 5.593 0 0 1-.319-1.433.053.053 0 0 1 .066-.054c1.517.363 3.072.546 4.632.546.376 0 .75 0 1.125-.01 1.57-.044 3.224-.124 4.768-.422.038-.008.077-.015.11-.024 2.435-.464 4.753-1.92 4.989-5.604.008-.145.03-1.52.03-1.67.002-.512.167-3.63-.024-5.545zm-3.748 9.195h-2.561V8.29c0-1.309-.55-1.976-1.67-1.976-1.23 0-1.846.79-1.846 2.35v3.403h-2.546V8.663c0-1.56-.617-2.35-1.848-2.35-1.112 0-1.668.668-1.67 1.977v6.218H4.822V8.102c0-1.31.337-2.35 1.011-3.12.696-.77 1.608-1.164 2.74-1.164 1.311 0 2.302.5 2.962 1.498l.638 1.06.638-1.06c.66-.999 1.65-1.498 2.96-1.498 1.13 0 2.043.395 2.74 1.164.675.77 1.012 1.81 1.012 3.12z"
fill="currentColor" fill="currentColor"
/> />
</svg> </svg>
); );
} }
export function ForgejoIcon({ size = 24, ...props }: IconProps) { export function ForgejoIcon({ size = 24, ...props }: IconProps) {
return ( return (
<svg <svg
xmlns="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24" viewBox="0 0 24 24"
width={size} width={size}
height={size} height={size}
{...props} {...props}
> >
<title>Forgejo</title> <title>Forgejo</title>
<path <path
d="M16.7773 0c1.6018 0 2.9004 1.2986 2.9004 2.9005s-1.2986 2.9004-2.9004 2.9004c-1.0854 0-2.0315-.596-2.5288-1.4787H12.91c-2.3322 0-4.2272 1.8718-4.2649 4.195l-.0007 2.1175a7.0759 7.0759 0 0 1 4.148-1.4205l.1176-.001 1.3385.0002c.4973-.8827 1.4434-1.4788 2.5288-1.4788 1.6018 0 2.9004 1.2986 2.9004 2.9005s-1.2986 2.9004-2.9004 2.9004c-1.0854 0-2.0315-.596-2.5288-1.4787H12.91c-2.3322 0-4.2272 1.8718-4.2649 4.195l-.0007 2.319c.8827.4973 1.4788 1.4434 1.4788 2.5287 0 1.602-1.2986 2.9005-2.9005 2.9005-1.6018 0-2.9004-1.2986-2.9004-2.9005 0-1.0853.596-2.0314 1.4788-2.5287l-.0002-9.9831c0-3.887 3.1195-7.0453 6.9915-7.108l.1176-.001h1.3385C14.7458.5962 15.692 0 16.7773 0ZM7.2227 19.9052c-.6596 0-1.1943.5347-1.1943 1.1943s.5347 1.1943 1.1943 1.1943 1.1944-.5347 1.1944-1.1943-.5348-1.1943-1.1944-1.1943Zm9.5546-10.4644c-.6596 0-1.1944.5347-1.1944 1.1943s.5348 1.1943 1.1944 1.1943c.6596 0 1.1943-.5347 1.1943-1.1943s-.5347-1.1943-1.1943-1.1943Zm0-7.7346c-.6596 0-1.1944.5347-1.1944 1.1943s.5348 1.1943 1.1944 1.1943c.6596 0 1.1943-.5347 1.1943-1.1943s-.5347-1.1943-1.1943-1.1943Z" d="M16.7773 0c1.6018 0 2.9004 1.2986 2.9004 2.9005s-1.2986 2.9004-2.9004 2.9004c-1.0854 0-2.0315-.596-2.5288-1.4787H12.91c-2.3322 0-4.2272 1.8718-4.2649 4.195l-.0007 2.1175a7.0759 7.0759 0 0 1 4.148-1.4205l.1176-.001 1.3385.0002c.4973-.8827 1.4434-1.4788 2.5288-1.4788 1.6018 0 2.9004 1.2986 2.9004 2.9005s-1.2986 2.9004-2.9004 2.9004c-1.0854 0-2.0315-.596-2.5288-1.4787H12.91c-2.3322 0-4.2272 1.8718-4.2649 4.195l-.0007 2.319c.8827.4973 1.4788 1.4434 1.4788 2.5287 0 1.602-1.2986 2.9005-2.9005 2.9005-1.6018 0-2.9004-1.2986-2.9004-2.9005 0-1.0853.596-2.0314 1.4788-2.5287l-.0002-9.9831c0-3.887 3.1195-7.0453 6.9915-7.108l.1176-.001h1.3385C14.7458.5962 15.692 0 16.7773 0ZM7.2227 19.9052c-.6596 0-1.1943.5347-1.1943 1.1943s.5347 1.1943 1.1943 1.1943 1.1944-.5347 1.1944-1.1943-.5348-1.1943-1.1944-1.1943Zm9.5546-10.4644c-.6596 0-1.1944.5347-1.1944 1.1943s.5348 1.1943 1.1944 1.1943c.6596 0 1.1943-.5347 1.1943-1.1943s-.5347-1.1943-1.1943-1.1943Zm0-7.7346c-.6596 0-1.1944.5347-1.1944 1.1943s.5348 1.1943 1.1944 1.1943c.6596 0 1.1943-.5347 1.1943-1.1943s-.5347-1.1943-1.1943-1.1943Z"
fill="currentColor" fill="currentColor"
/> />
</svg> </svg>
); );
} }
export function CodebergIcon({ size = 24, ...props }: IconProps) { export function CodebergIcon({ size = 24, ...props }: IconProps) {
return ( return (
<svg <svg
xmlns="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24" viewBox="0 0 24 24"
width={size} width={size}
height={size} height={size}
{...props} {...props}
> >
<title>Codeberg</title> <title>Codeberg</title>
<path <path
d="M11.999.747A11.974 11.974 0 0 0 0 12.75c0 2.254.635 4.465 1.833 6.376L11.837 6.19c.072-.092.251-.092.323 0l4.178 5.402h-2.992l.065.239h3.113l.882 1.138h-3.674l.103.374h3.86l.777 1.003h-4.358l.135.483h4.593l.695.894h-5.038l.165.589h5.326l.609.785h-5.717l.182.65h6.038l.562.727h-6.397l.183.65h6.717A12.003 12.003 0 0 0 24 12.75 11.977 11.977 0 0 0 11.999.747zm3.654 19.104.182.65h5.326c.173-.204.353-.433.513-.65zm.385 1.377.18.65h3.563c.233-.198.485-.428.712-.65zm.383 1.377.182.648h1.203c.356-.204.685-.412 1.042-.648zz" d="M11.999.747A11.974 11.974 0 0 0 0 12.75c0 2.254.635 4.465 1.833 6.376L11.837 6.19c.072-.092.251-.092.323 0l4.178 5.402h-2.992l.065.239h3.113l.882 1.138h-3.674l.103.374h3.86l.777 1.003h-4.358l.135.483h4.593l.695.894h-5.038l.165.589h5.326l.609.785h-5.717l.182.65h6.038l.562.727h-6.397l.183.65h6.717A12.003 12.003 0 0 0 24 12.75 11.977 11.977 0 0 0 11.999.747zm3.654 19.104.182.65h5.326c.173-.204.353-.433.513-.65zm.385 1.377.18.65h3.563c.233-.198.485-.428.712-.65zm.383 1.377.182.648h1.203c.356-.204.685-.412 1.042-.648zz"
fill="currentColor" fill="currentColor"
/> />
</svg> </svg>
); );
} }
export function GitHubIcon({ size = 24, ...props }: IconProps) { export function GitHubIcon({ size = 24, ...props }: IconProps) {
return ( return (
<svg <svg
xmlns="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24" viewBox="0 0 24 24"
width={size} width={size}
height={size} height={size}
{...props} {...props}
> >
<title>GitHub</title> <title>GitHub</title>
<path <path
d="M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12" d="M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12"
fill="currentColor" fill="currentColor"
/> />
</svg> </svg>
); );
} }
export function MailIcon({ size = 24, ...props }: IconProps) { export function MailIcon({ size = 24, ...props }: IconProps) {
return ( return (
<svg <svg
xmlns="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 20 20" viewBox="0 0 20 20"
width={size} width={size}
height={size} height={size}
{...props} {...props}
> >
<path <path
d="M3 4a2 2 0 0 0-2 2v1.161l8.441 4.221a1.25 1.25 0 0 0 1.118 0L19 7.162V6a2 2 0 0 0-2-2H3Z" d="M3 4a2 2 0 0 0-2 2v1.161l8.441 4.221a1.25 1.25 0 0 0 1.118 0L19 7.162V6a2 2 0 0 0-2-2H3Z"
fill="currentColor" fill="currentColor"
/> />
<path <path
d="m19 8.839-7.77 3.885a2.75 2.75 0 0 1-2.46 0L1 8.839V14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V8.839Z" d="m19 8.839-7.77 3.885a2.75 2.75 0 0 1-2.46 0L1 8.839V14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V8.839Z"
fill="currentColor" fill="currentColor"
/> />
</svg> </svg>
); );
} }
export function TwitterIcon({ size = 24, ...props }: IconProps) { export function TwitterIcon({ size = 24, ...props }: IconProps) {
return ( return (
<svg <svg
xmlns="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24" viewBox="0 0 24 24"
width={size} width={size}
height={size} height={size}
{...props} {...props}
> >
<path <path
d="M21.543 7.104c.015.211.015.423.015.636 0 6.507-4.954 14.01-14.01 14.01v-.003A13.94 13.94 0 0 1 0 19.539a9.88 9.88 0 0 0 7.287-2.041 4.93 4.93 0 0 1-4.6-3.42 4.916 4.916 0 0 0 2.223-.084A4.926 4.926 0 0 1 .96 9.167v-.062a4.887 4.887 0 0 0 2.235.616A4.928 4.928 0 0 1 1.67 3.148 13.98 13.98 0 0 0 11.82 8.292a4.929 4.929 0 0 1 8.39-4.49 9.868 9.868 0 0 0 3.128-1.196 4.941 4.941 0 0 1-2.165 2.724A9.828 9.828 0 0 0 24 4.555a10.019 10.019 0 0 1-2.457 2.549z" d="M21.543 7.104c.015.211.015.423.015.636 0 6.507-4.954 14.01-14.01 14.01v-.003A13.94 13.94 0 0 1 0 19.539a9.88 9.88 0 0 0 7.287-2.041 4.93 4.93 0 0 1-4.6-3.42 4.916 4.916 0 0 0 2.223-.084A4.926 4.926 0 0 1 .96 9.167v-.062a4.887 4.887 0 0 0 2.235.616A4.928 4.928 0 0 1 1.67 3.148 13.98 13.98 0 0 0 11.82 8.292a4.929 4.929 0 0 1 8.39-4.49 9.868 9.868 0 0 0 3.128-1.196 4.941 4.941 0 0 1-2.165 2.724A9.828 9.828 0 0 0 24 4.555a10.019 10.019 0 0 1-2.457 2.549z"
fill="currentColor" fill="currentColor"
/> />
</svg> </svg>
); );
} }
export function KofiIcon({ size = 24, ...props }: IconProps) { export function KofiIcon({ size = 24, ...props }: IconProps) {
return ( return (
<svg <svg
role="img" role="img"
xmlns="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24" viewBox="0 0 24 24"
width={size} width={size}
height={size} height={size}
{...props} {...props}
> >
<title>Ko-fi</title> <title>Ko-fi</title>
<path <path
d="M11.351 2.715c-2.7 0-4.986.025-6.83.26C2.078 3.285 0 5.154 0 8.61c0 3.506.182 6.13 1.585 8.493 1.584 2.701 4.233 4.182 7.662 4.182h.83c4.209 0 6.494-2.234 7.637-4a9.5 9.5 0 0 0 1.091-2.338C21.792 14.688 24 12.22 24 9.208v-.415c0-3.247-2.13-5.507-5.792-5.87-1.558-.156-2.65-.208-6.857-.208m0 1.947c4.208 0 5.09.052 6.571.182 2.624.311 4.13 1.584 4.13 4v.39c0 2.156-1.792 3.844-3.87 3.844h-.935l-.156.649c-.208 1.013-.597 1.818-1.039 2.546-.909 1.428-2.545 3.064-5.922 3.064h-.805c-2.571 0-4.831-.883-6.078-3.195-1.09-2-1.298-4.155-1.298-7.506 0-2.181.857-3.402 3.012-3.714 1.533-.233 3.559-.26 6.39-.26m6.547 2.287c-.416 0-.65.234-.65.546v2.935c0 .311.234.545.65.545 1.324 0 2.051-.754 2.051-2s-.727-2.026-2.052-2.026m-10.39.182c-1.818 0-3.013 1.48-3.013 3.142 0 1.533.858 2.857 1.949 3.897.727.701 1.87 1.429 2.649 1.896a1.47 1.47 0 0 0 1.507 0c.78-.467 1.922-1.195 2.623-1.896 1.117-1.039 1.974-2.364 1.974-3.897 0-1.662-1.247-3.142-3.039-3.142-1.065 0-1.792.545-2.338 1.298-.493-.753-1.246-1.298-2.312-1.298" d="M11.351 2.715c-2.7 0-4.986.025-6.83.26C2.078 3.285 0 5.154 0 8.61c0 3.506.182 6.13 1.585 8.493 1.584 2.701 4.233 4.182 7.662 4.182h.83c4.209 0 6.494-2.234 7.637-4a9.5 9.5 0 0 0 1.091-2.338C21.792 14.688 24 12.22 24 9.208v-.415c0-3.247-2.13-5.507-5.792-5.87-1.558-.156-2.65-.208-6.857-.208m0 1.947c4.208 0 5.09.052 6.571.182 2.624.311 4.13 1.584 4.13 4v.39c0 2.156-1.792 3.844-3.87 3.844h-.935l-.156.649c-.208 1.013-.597 1.818-1.039 2.546-.909 1.428-2.545 3.064-5.922 3.064h-.805c-2.571 0-4.831-.883-6.078-3.195-1.09-2-1.298-4.155-1.298-7.506 0-2.181.857-3.402 3.012-3.714 1.533-.233 3.559-.26 6.39-.26m6.547 2.287c-.416 0-.65.234-.65.546v2.935c0 .311.234.545.65.545 1.324 0 2.051-.754 2.051-2s-.727-2.026-2.052-2.026m-10.39.182c-1.818 0-3.013 1.48-3.013 3.142 0 1.533.858 2.857 1.949 3.897.727.701 1.87 1.429 2.649 1.896a1.47 1.47 0 0 0 1.507 0c.78-.467 1.922-1.195 2.623-1.896 1.117-1.039 1.974-2.364 1.974-3.897 0-1.662-1.247-3.142-3.039-3.142-1.065 0-1.792.545-2.338 1.298-.493-.753-1.246-1.298-2.312-1.298"
fill="currentColor" fill="currentColor"
/> />
</svg> </svg>
); );
} }
export function BitcoinIcon({ size = 24, ...props }: IconProps) { export function BitcoinIcon({ size = 24, ...props }: IconProps) {
return ( return (
<svg <svg
role="img" role="img"
xmlns="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24" viewBox="0 0 24 24"
width={size} width={size}
height={size} height={size}
{...props} {...props}
> >
<title>Bitcoin</title> <title>Bitcoin</title>
<path <path
d="M23.638 14.904c-1.602 6.43-8.113 10.34-14.542 8.736C2.67 22.05-1.244 15.525.362 9.105 1.962 2.67 8.475-1.243 14.9.358c6.43 1.605 10.342 8.115 8.738 14.548v-.002zm-6.35-4.613c.24-1.59-.974-2.45-2.64-3.03l.54-2.153-1.315-.33-.525 2.107c-.345-.087-.705-.167-1.064-.25l.526-2.127-1.32-.33-.54 2.165c-.285-.067-.565-.132-.84-.2l-1.815-.45-.35 1.407s.975.225.955.236c.535.136.63.486.615.766l-1.477 5.92c-.075.166-.24.406-.614.314.015.02-.96-.24-.96-.24l-.66 1.51 1.71.426.93.242-.54 2.19 1.32.327.54-2.17c.36.1.705.19 1.05.273l-.51 2.154 1.32.33.545-2.19c2.24.427 3.93.257 4.64-1.774.57-1.637-.03-2.58-1.217-3.196.854-.193 1.5-.76 1.68-1.93h.01zm-3.01 4.22c-.404 1.64-3.157.75-4.05.53l.72-2.9c.896.23 3.757.67 3.33 2.37zm.41-4.24c-.37 1.49-2.662.735-3.405.55l.654-2.64c.744.18 3.137.524 2.75 2.084v.006z" d="M23.638 14.904c-1.602 6.43-8.113 10.34-14.542 8.736C2.67 22.05-1.244 15.525.362 9.105 1.962 2.67 8.475-1.243 14.9.358c6.43 1.605 10.342 8.115 8.738 14.548v-.002zm-6.35-4.613c.24-1.59-.974-2.45-2.64-3.03l.54-2.153-1.315-.33-.525 2.107c-.345-.087-.705-.167-1.064-.25l.526-2.127-1.32-.33-.54 2.165c-.285-.067-.565-.132-.84-.2l-1.815-.45-.35 1.407s.975.225.955.236c.535.136.63.486.615.766l-1.477 5.92c-.075.166-.24.406-.614.314.015.02-.96-.24-.96-.24l-.66 1.51 1.71.426.93.242-.54 2.19 1.32.327.54-2.17c.36.1.705.19 1.05.273l-.51 2.154 1.32.33.545-2.19c2.24.427 3.93.257 4.64-1.774.57-1.637-.03-2.58-1.217-3.196.854-.193 1.5-.76 1.68-1.93h.01zm-3.01 4.22c-.404 1.64-3.157.75-4.05.53l.72-2.9c.896.23 3.757.67 3.33 2.37zm.41-4.24c-.37 1.49-2.662.735-3.405.55l.654-2.64c.744.18 3.137.524 2.75 2.084v.006z"
fill="currentColor" fill="currentColor"
/> />
</svg> </svg>
); );
} }
export function BitcoinCashIcon({ size = 24, ...props }: IconProps) { export function BitcoinCashIcon({ size = 24, ...props }: IconProps) {
return ( return (
<svg <svg
role="img" role="img"
xmlns="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24" viewBox="0 0 24 24"
width={size} width={size}
height={size} height={size}
{...props} {...props}
> >
<title>Bitcoin Cash</title> <title>Bitcoin Cash</title>
<path <path
d="m10.84 11.22-.688-2.568c.728-.18 2.839-1.051 3.39.506.27 1.682-1.978 1.877-2.702 2.062zm.289 1.313.755 2.829c.868-.228 3.496-.46 3.241-2.351-.433-1.666-3.125-.706-3.996-.478zM24 12c0 6.627-5.373 12-12 12S0 18.627 0 12 5.373 0 12 0s12 5.373 12 12zm-6.341.661c-.183-1.151-1.441-2.095-2.485-2.202.643-.57.969-1.401.57-2.488-.603-1.368-1.989-1.66-3.685-1.377l-.546-2.114-1.285.332.536 2.108c-.338.085-.685.158-1.029.256L9.198 5.08l-1.285.332.545 2.114c-.277.079-2.595.673-2.595.673l.353 1.377s.944-.265.935-.244c.524-.137.771.125.886.372l1.498 5.793c.018.168-.012.454-.372.551.021.012-.935.241-.935.241l.14 1.605s2.296-.588 2.598-.664l.551 2.138 1.285-.332-.551-2.153c.353-.082.697-.168 1.032-.256l.548 2.141 1.285-.332-.551-2.135c1.982-.482 3.38-1.73 3.094-3.64z" d="m10.84 11.22-.688-2.568c.728-.18 2.839-1.051 3.39.506.27 1.682-1.978 1.877-2.702 2.062zm.289 1.313.755 2.829c.868-.228 3.496-.46 3.241-2.351-.433-1.666-3.125-.706-3.996-.478zM24 12c0 6.627-5.373 12-12 12S0 18.627 0 12 5.373 0 12 0s12 5.373 12 12zm-6.341.661c-.183-1.151-1.441-2.095-2.485-2.202.643-.57.969-1.401.57-2.488-.603-1.368-1.989-1.66-3.685-1.377l-.546-2.114-1.285.332.536 2.108c-.338.085-.685.158-1.029.256L9.198 5.08l-1.285.332.545 2.114c-.277.079-2.595.673-2.595.673l.353 1.377s.944-.265.935-.244c.524-.137.771.125.886.372l1.498 5.793c.018.168-.012.454-.372.551.021.012-.935.241-.935.241l.14 1.605s2.296-.588 2.598-.664l.551 2.138 1.285-.332-.551-2.153c.353-.082.697-.168 1.032-.256l.548 2.141 1.285-.332-.551-2.135c1.982-.482 3.38-1.73 3.094-3.64z"
fill="currentColor" fill="currentColor"
/> />
</svg> </svg>
); );
} }
export function MoneroIcon({ size = 24, ...props }: IconProps) { export function MoneroIcon({ size = 24, ...props }: IconProps) {
return ( return (
<svg <svg
role="img" role="img"
xmlns="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24" viewBox="0 0 24 24"
width={size} width={size}
height={size} height={size}
{...props} {...props}
> >
<title>Monero</title> <title>Monero</title>
<path <path
d="M12 0C5.365 0 0 5.373 0 12.015c0 1.335.228 2.607.618 3.81h3.577V5.729L12 13.545l7.805-7.815v10.095h3.577c.389-1.203.618-2.475.618-3.81C24 5.375 18.635 0 12 0zm-1.788 15.307l-3.417-3.421v6.351H1.758C3.87 21.689 7.678 24 12 24s8.162-2.311 10.245-5.764h-5.04v-6.351l-3.386 3.421-1.788 1.79-1.814-1.79h-.005z" d="M12 0C5.365 0 0 5.373 0 12.015c0 1.335.228 2.607.618 3.81h3.577V5.729L12 13.545l7.805-7.815v10.095h3.577c.389-1.203.618-2.475.618-3.81C24 5.375 18.635 0 12 0zm-1.788 15.307l-3.417-3.421v6.351H1.758C3.87 21.689 7.678 24 12 24s8.162-2.311 10.245-5.764h-5.04v-6.351l-3.386 3.421-1.788 1.79-1.814-1.79h-.005z"
fill="currentColor" fill="currentColor"
/> />
</svg> </svg>
); );
} }
export function NanoIcon({ size = 24, ...props }: IconProps) { export function NanoIcon({ size = 24, ...props }: IconProps) {
return ( return (
<svg <svg
role="img" role="img"
xmlns="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24" viewBox="0 0 24 24"
width={size} width={size}
height={size} height={size}
{...props} {...props}
> >
<title>Nano</title> <title>Nano</title>
<path <path
d="m3.723 0 6.875 10.76H4.775v1.365h5.881l-1.76 2.73h-4.12v1.364h3.242L3.006 24h1.85l5.068-7.781h4.215L19.129 24h1.865l-4.941-7.781h3.232v-1.364h-4.1l-1.732-2.73h5.832V10.76h-5.803L20.45 0h-1.785l-6.588 10.107L5.627 0H3.723zm8.324 12.959 1.217 1.896h-2.451l1.234-1.896z" d="m3.723 0 6.875 10.76H4.775v1.365h5.881l-1.76 2.73h-4.12v1.364h3.242L3.006 24h1.85l5.068-7.781h4.215L19.129 24h1.865l-4.941-7.781h3.232v-1.364h-4.1l-1.732-2.73h5.832V10.76h-5.803L20.45 0h-1.785l-6.588 10.107L5.627 0H3.723zm8.324 12.959 1.217 1.896h-2.451l1.234-1.896z"
fill="currentColor" fill="currentColor"
/> />
</svg> </svg>
); );
} }
export function LitecoinIcon({ size = 24, ...props }: IconProps) { export function LitecoinIcon({ size = 24, ...props }: IconProps) {
return ( return (
<svg <svg
role="img" role="img"
xmlns="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24" viewBox="0 0 24 24"
width={size} width={size}
height={size} height={size}
{...props} {...props}
> >
<title>Litecoin</title> <title>Litecoin</title>
<path <path
d="M12 0a12 12 0 1012 12A12 12 0 0012 0zm-.2617 3.6777h2.584a.3425.3425 0 01.33.4356l-2.0312 6.918 1.9062-.582-.4082 1.3847-1.9238.5605-1.248 4.213h6.6757a.3425.3425 0 01.3282.4374l-.582 2a.4586.4586 0 01-.4395.3301H6.7324l1.7227-5.8223-1.9063.5801.42-1.3613 1.9101-.58 2.4219-8.1798a.4557.4557 0 01.4375-.334Z" d="M12 0a12 12 0 1012 12A12 12 0 0012 0zm-.2617 3.6777h2.584a.3425.3425 0 01.33.4356l-2.0312 6.918 1.9062-.582-.4082 1.3847-1.9238.5605-1.248 4.213h6.6757a.3425.3425 0 01.3282.4374l-.582 2a.4586.4586 0 01-.4395.3301H6.7324l1.7227-5.8223-1.9063.5801.42-1.3613 1.9101-.58 2.4219-8.1798a.4557.4557 0 01.4375-.334Z"
fill="currentColor" fill="currentColor"
/> />
</svg> </svg>
); );
} }
export function EthereumIcon({ size = 24, ...props }: IconProps) { export function EthereumIcon({ size = 24, ...props }: IconProps) {
return ( return (
<svg <svg
role="img" role="img"
xmlns="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24" viewBox="0 0 24 24"
width={size} width={size}
height={size} height={size}
{...props} {...props}
> >
<title>Ethereum</title> <title>Ethereum</title>
<path <path
d="M11.944 17.97L4.58 13.62 11.943 24l7.37-10.38-7.372 4.35h.003zM12.056 0L4.69 12.223l7.365 4.354 7.365-4.35L12.056 0z" d="M11.944 17.97L4.58 13.62 11.943 24l7.37-10.38-7.372 4.35h.003zM12.056 0L4.69 12.223l7.365 4.354 7.365-4.35L12.056 0z"
fill="currentColor" fill="currentColor"
/> />
</svg> </svg>
); );
} }
export function HeartFilledIcon({ size = 24, ...props }: IconProps) { export function HeartFilledIcon({ size = 24, ...props }: IconProps) {
return ( return (
<svg <svg
fill="currentColor" fill="currentColor"
xmlns="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24" viewBox="0 0 24 24"
width={size} width={size}
height={size} height={size}
{...props} {...props}
> >
<path d="M9 2H5v2H3v2H1v6h2v2h2v2h2v2h2v2h2v2h2v-2h2v-2h2v-2h2v-2h2v-2h2V6h-2V4h-2V2h-4v2h-2v2h-2V4H9V2z" /> <path d="M9 2H5v2H3v2H1v6h2v2h2v2h2v2h2v2h2v2h2v-2h2v-2h2v-2h2v-2h2v-2h2V6h-2V4h-2V2h-4v2h-2v2h-2V4H9V2z" />
</svg> </svg>
); );
}
export function GitHubSponsorsIcon({ size = 24, ...props }: IconProps) {
return (
<svg
fill="currentColor"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
width={size}
height={size}
{...props}
>
<title>GitHub Sponsors</title>
<path d="M17.625 1.499c-2.32 0-4.354 1.203-5.625 3.03-1.271-1.827-3.305-3.03-5.625-3.03C3.129 1.499 0 4.253 0 8.249c0 4.275 3.068 7.847 5.828 10.227a33.14 33.14 0 0 0 5.616 3.876l.028.017.008.003-.001.003c.163.085.342.126.521.125.179.001.358-.041.521-.125l-.001-.003.008-.003.028-.017a33.14 33.14 0 0 0 5.616-3.876C20.932 16.096 24 12.524 24 8.249c0-3.996-3.129-6.75-6.375-6.75zm-.919 15.275a30.766 30.766 0 0 1-4.703 3.316l-.004-.002-.004.002a30.955 30.955 0 0 1-4.703-3.316c-2.677-2.307-5.047-5.298-5.047-8.523 0-2.754 2.121-4.5 4.125-4.5 2.06 0 3.914 1.479 4.544 3.684.143.495.596.797 1.086.796.49.001.943-.302 1.085-.796.63-2.205 2.484-3.684 4.544-3.684 2.004 0 4.125 1.746 4.125 4.5 0 3.225-2.37 6.216-5.048 8.523z" />
</svg>
);
} }

View file

@ -6,27 +6,27 @@
import { ComponentChildren } from "preact"; import { ComponentChildren } from "preact";
interface LayoutProps { interface LayoutProps {
children: ComponentChildren; children: ComponentChildren;
[key: string]: any; [key: string]: any;
} }
export function Section({ children, class: className, ...props }: LayoutProps) { export function Section({ children, class: className, ...props }: LayoutProps) {
return ( return (
<div <div
{...props} {...props}
class={`section ${className || ""}`} class={`section ${className || ""}`}
> >
{children} {children}
</div> </div>
); );
} }
export function Centered( export function Centered(
{ children, class: className, ...props }: LayoutProps, { children, class: className, ...props }: LayoutProps,
) { ) {
return ( return (
<div class={`centered ${className || ""}`} {...props}> <main class={`centered ${className || ""}`} {...props}>
{children} {children}
</div> </main>
); );
} }

View file

@ -7,18 +7,18 @@ import { HTMLAttributes, JSX } from "preact";
import { LinkIcon } from "./Icon.tsx"; import { LinkIcon } from "./Icon.tsx";
interface LinkProps extends HTMLAttributes<HTMLAnchorElement> { interface LinkProps extends HTMLAttributes<HTMLAnchorElement> {
href: string; href: string;
children: JSX.Element | JSX.Element[] | string; children: JSX.Element | JSX.Element[] | string;
noIcon?: boolean; noIcon?: boolean;
} }
export default function Link( export default function Link(
{ children, noIcon = false, ...props }: LinkProps, { children, noIcon = false, ...props }: LinkProps,
) { ) {
return ( return (
<a {...props}> <a {...props}>
{children} {children}
{!noIcon && <LinkIcon size={16} class="link-icon" />} {!noIcon && <LinkIcon size={16} class="link-icon" />}
</a> </a>
); );
} }

View file

@ -4,57 +4,57 @@
*/ */
interface TintedImageProps { interface TintedImageProps {
src: string; src: string;
colour: string; colour: string;
[key: string]: any; [key: string]: any;
} }
export default function TintedImage({ export default function TintedImage({
colour, colour,
src, src,
...props ...props
}: TintedImageProps) { }: TintedImageProps) {
return ( return (
<svg <svg
width="100%" width="100%"
height="100%" height="100%"
{...props} {...props}
> >
<defs> <defs>
<filter <filter
id="tint" id="tint"
x="0%" x="0%"
y="0%" y="0%"
width="100%" width="100%"
height="100%" height="100%"
colorInterpolationFilters="sRGB" colorInterpolationFilters="sRGB"
> >
<feColorMatrix <feColorMatrix
type="saturate" type="saturate"
values="0" values="0"
result="grayscale" result="grayscale"
/> />
<feFlood flood-color={colour} result="tint" /> <feFlood flood-color={colour} result="tint" />
<feComposite <feComposite
in="tint" in="tint"
in2="grayscale" in2="grayscale"
operator="arithmetic" operator="arithmetic"
k1="1" k1="1"
k2="0" k2="0"
k3="0" k3="0"
k4="0" k4="0"
/> />
</filter> </filter>
</defs> </defs>
<image <image
x="0" x="0"
y="0" y="0"
width="100%" width="100%"
height="100%" height="100%"
preserveAspectRatio="xMidYMid meet" preserveAspectRatio="xMidYMid meet"
filter={`url(#tint)`} filter={`url(#tint)`}
href={src} href={src}
/> />
</svg> </svg>
); );
} }

View file

@ -6,24 +6,24 @@
import { ComponentChildren, h } from "preact"; import { ComponentChildren, h } from "preact";
interface TitleProps { interface TitleProps {
level?: 1 | 2 | 3 | 4 | 5 | 6; level?: 1 | 2 | 3 | 4 | 5 | 6;
children: ComponentChildren; children: ComponentChildren;
[key: string]: any; [key: string]: any;
} }
export default function Title({ export default function Title({
level = 1, level = 1,
children, children,
class: className, class: className,
...props ...props
}: TitleProps) { }: TitleProps) {
const Heading = `h${Math.min(Math.max(level, 1), 6)}`; const Heading = `h${Math.min(Math.max(level, 1), 6)}`;
return h( return h(
Heading, Heading,
{ {
class: `title title-${level} ${className || ""}`, class: `title title-${level} ${className || ""}`,
...props, ...props,
}, },
children, children,
); );
} }

120
deno.json
View file

@ -1,58 +1,66 @@
{ {
"nodeModulesDir": "auto", "nodeModulesDir": "auto",
"tasks": { "tasks": {
"check": "deno fmt --check . && deno lint . && deno check", "check": "deno fmt --check . && deno lint . && deno check",
"dev": "vite", "dev": "vite",
"build": "vite build", "build": "vite build",
"start": "deno serve -A _fresh/server.js", "start": "deno serve -A _fresh/server.js",
"update": "deno run -A -r jsr:@fresh/update ." "update": "deno run -A -r jsr:@fresh/update ."
}, },
"lint": { "fmt": {
"rules": { "useTabs": true
"tags": [ },
"fresh", "lint": {
"recommended" "rules": {
], "tags": [
"exclude": ["no-explicit-any", "no-window", "no-window-prefix"] "fresh",
} "recommended"
}, ],
"exclude": [ "exclude": [
"**/_fresh/*" "no-explicit-any",
], "no-window",
"imports": { "no-window-prefix",
"fresh": "jsr:@fresh/core@^2.1.2", "no-unused-vars"
"preact": "npm:preact@^10.27.2", ]
"@preact/signals": "npm:@preact/signals@^2.3.1", }
"@fresh/plugin-vite": "jsr:@fresh/plugin-vite@^1.0.5", },
"vite": "npm:vite@^7.1.3" "exclude": [
}, "**/_fresh/*"
"compilerOptions": { ],
"lib": [ "imports": {
"dom", "fresh": "jsr:@fresh/core@^2.1.2",
"dom.asynciterable", "preact": "npm:preact@^10.27.2",
"dom.iterable", "@preact/signals": "npm:@preact/signals@^2.3.1",
"deno.ns" "@fresh/plugin-vite": "jsr:@fresh/plugin-vite@^1.0.5",
], "vite": "npm:vite@^7.1.3"
"jsx": "precompile", },
"jsxImportSource": "preact", "compilerOptions": {
"jsxPrecompileSkipElements": [ "lib": [
"a", "dom",
"img", "dom.asynciterable",
"source", "dom.iterable",
"body", "deno.ns"
"html", ],
"head", "jsx": "precompile",
"title", "jsxImportSource": "preact",
"meta", "jsxPrecompileSkipElements": [
"script", "a",
"link", "img",
"style", "source",
"base", "body",
"noscript", "html",
"template" "head",
], "title",
"types": [ "meta",
"vite/client" "script",
] "link",
} "style",
"base",
"noscript",
"template"
],
"types": [
"vite/client"
]
}
} }

View file

@ -6,25 +6,24 @@
import { ComponentChildren } from "preact"; import { ComponentChildren } from "preact";
interface CodeProps { interface CodeProps {
children: ComponentChildren; children: ComponentChildren;
[key: string]: any; [key: string]: any;
} }
export default function Code({ children, ...props }: CodeProps) { export default function Code({ children, ...props }: CodeProps) {
const handleClick = () => { const handleClick = () => {
if (typeof children === "string") { if (typeof children === "string") {
navigator.clipboard.writeText(children); navigator.clipboard.writeText(children);
} }
}; };
return ( return (
<code <button
class="inline-code" class="inline-code"
onClick={handleClick} onClick={handleClick}
style={{ cursor: "pointer" }} title="Click to copy"
title={"Click to copy"} {...props}
{...props} >
> <span>{children}</span>
<span>{children}</span> </button>
</code> );
);
} }

View file

@ -4,16 +4,20 @@
*/ */
export default function Meow() { export default function Meow() {
return ( return (
<button <button
type="button" type="button"
id="muxiepuff" id="muxiepuff"
onClick={() => onClick={() =>
navigator.clipboard.writeText( navigator.clipboard.writeText(
'<a href="https://acpi.at"><img src="https://acpi.at/88x31.gif" title="muxiepuff" alt="acpi.at" /></a>', '<a href="https://acpi.at"><img src="https://acpi.at/88x31.gif" title="muxiepuff" alt="acpi.at" /></a>',
)} )}
> >
<img src="/88x31.gif" title="muxiepuff (Click to copy to clipboard!)" alt="acpi.at" /> <img
</button> src="/88x31.gif"
); title="muxiepuff (Click to copy to clipboard!)"
alt="acpi.at"
/>
</button>
);
} }

View file

@ -6,32 +6,31 @@
import { useEffect, useState } from "preact/hooks"; import { useEffect, useState } from "preact/hooks";
export default function Name() { export default function Name() {
const names = ["muxiepuff", "lívia", "aury"]; const names = ["muxiepuff", "lívia", "aury"];
const ipas = ["/ˈmuˌksipʌf/", "/li.vjɐ/", "/ˈaʊ̯ˌɾi/"] const ipas = ["/ˈmuˌksipʌf/", "/li.vjɐ/", "/ˈaʊ̯ˌɾi/"];
; const [currentIndex, setCurrentIndex] = useState(0);
const [currentIndex, setCurrentIndex] = useState(0); const [isAnimating, setIsAnimating] = useState(false);
const [isAnimating, setIsAnimating] = useState(false);
useEffect(() => { useEffect(() => {
const interval = setInterval(() => { const interval = setInterval(() => {
setIsAnimating(true); setIsAnimating(true);
setTimeout(() => { setTimeout(() => {
setCurrentIndex((prev) => (prev + 1) % names.length); setCurrentIndex((prev) => (prev + 1) % names.length);
setIsAnimating(false); setIsAnimating(false);
}, 200); }, 200);
}, 2000); }, 2000);
return () => clearInterval(interval); return () => clearInterval(interval);
}, []); }, []);
return ( return (
<span class="name-scroller"> <span class="name-scroller">
<span class={`name-wrapper ${isAnimating ? "animating" : ""}`}> <span class={`name-wrapper ${isAnimating ? "animating" : ""}`}>
<span class="name-text"> <span class="name-text">
{names[currentIndex]} {names[currentIndex]}
<span class="name-underline"></span> <span class="name-underline"></span>
</span>{" "} </span>{" "}
<span class="alt alt-font">({ipas[currentIndex]}, she/her)</span> <span class="alt alt-font">({ipas[currentIndex]}, she/her)</span>
</span> </span>
</span> </span>
); );
} }

View file

@ -6,41 +6,41 @@
import { useEffect, useRef } from "preact/hooks"; import { useEffect, useRef } from "preact/hooks";
interface Particle { interface Particle {
offsetX: number; offsetX: number;
offsetY: number; offsetY: number;
velocityX: number; velocityX: number;
velocityY: number; velocityY: number;
} }
interface Raindrop { interface Raindrop {
x: number; x: number;
y: number; y: number;
length: number; length: number;
speed: number; speed: number;
opacity: number; opacity: number;
floorHeight: number; floorHeight: number;
} }
interface Splash { interface Splash {
x: number; x: number;
y: number; y: number;
age: number; age: number;
maxAge: number; maxAge: number;
particles: Particle[]; particles: Particle[];
} }
interface Star { interface Star {
x: number; x: number;
y: number; y: number;
size: number; size: number;
brightness: number; brightness: number;
twinkleSpeed: number; twinkleSpeed: number;
twinkleOffset: number; twinkleOffset: number;
age: number; age: number;
maxAge: number; maxAge: number;
canVanish: boolean; canVanish: boolean;
color: { r: number; g: number; b: number }; color: { r: number; g: number; b: number };
colorIndex: number; colorIndex: number;
} }
const PIXEL_SIZE = 4; const PIXEL_SIZE = 4;
@ -82,293 +82,299 @@ const ALPHA_STAR_COLORS: string[] = [];
const NUM_COLOR_VARIATIONS = 20; const NUM_COLOR_VARIATIONS = 20;
for (let i = 0; i < NUM_COLOR_VARIATIONS; i++) { for (let i = 0; i < NUM_COLOR_VARIATIONS; i++) {
const brightness = 1 - (i / NUM_COLOR_VARIATIONS) * 0.5; const brightness = 1 - (i / NUM_COLOR_VARIATIONS) * 0.5;
RAIN_COLORS.push( RAIN_COLORS.push(
`rgb(${Math.floor(RAIN_COLOR.r * brightness)},${ `rgb(${Math.floor(RAIN_COLOR.r * brightness)},${
Math.floor(RAIN_COLOR.g * brightness) Math.floor(
},${Math.floor(RAIN_COLOR.b * brightness)})`, RAIN_COLOR.g * brightness,
); )
},${Math.floor(RAIN_COLOR.b * brightness)})`,
);
} }
for (let i = 0; i < NUM_COLOR_VARIATIONS; i++) { for (let i = 0; i < NUM_COLOR_VARIATIONS; i++) {
const brightness = STAR_BRIGHTNESS_MIN + const brightness = STAR_BRIGHTNESS_MIN +
(i / NUM_COLOR_VARIATIONS) * STAR_BRIGHTNESS_RANGE; (i / NUM_COLOR_VARIATIONS) * STAR_BRIGHTNESS_RANGE;
STAR_COLORS.push( STAR_COLORS.push(
`rgb(${Math.floor(RAIN_COLOR.r * brightness)},${ `rgb(${Math.floor(RAIN_COLOR.r * brightness)},${
Math.floor(RAIN_COLOR.g * brightness) Math.floor(
},${Math.floor(RAIN_COLOR.b * brightness)})`, RAIN_COLOR.g * brightness,
); )
ALPHA_STAR_COLORS.push( },${Math.floor(RAIN_COLOR.b * brightness)})`,
`rgba(${Math.floor(RAIN_COLOR.r * brightness)},${ );
Math.floor(RAIN_COLOR.g * brightness) ALPHA_STAR_COLORS.push(
},${Math.floor(RAIN_COLOR.b * brightness)},`, `rgba(${Math.floor(RAIN_COLOR.r * brightness)},${
); Math.floor(
RAIN_COLOR.g * brightness,
)
},${Math.floor(RAIN_COLOR.b * brightness)},`,
);
} }
const SPLASH_PARTICLE_COLOR = `rgb(${RAIN_COLOR.r * 0.9},${ const SPLASH_PARTICLE_COLOR = `rgb(${RAIN_COLOR.r * 0.9},${
RAIN_COLOR.g * 0.95 RAIN_COLOR.g * 0.95
},${RAIN_COLOR.b * 1.1})`; },${RAIN_COLOR.b * 1.1})`;
const SPLASH_RIPPLE_COLOR = `rgb(${RAIN_COLOR.r * 0.7},${RAIN_COLOR.g * 0.8},${ const SPLASH_RIPPLE_COLOR = `rgb(${RAIN_COLOR.r * 0.7},${RAIN_COLOR.g * 0.8},${
RAIN_COLOR.b * 0.95 RAIN_COLOR.b * 0.95
})`; })`;
function createParticle(): Particle { function createParticle(): Particle {
return { return {
offsetX: (Math.random() - 0.5) * PARTICLE_OFFSET_RANGE, offsetX: (Math.random() - 0.5) * PARTICLE_OFFSET_RANGE,
offsetY: -(Math.random() * PARTICLE_Y_RANGE + PARTICLE_Y_MIN), offsetY: -(Math.random() * PARTICLE_Y_RANGE + PARTICLE_Y_MIN),
velocityX: (Math.random() - 0.5) * PARTICLE_VX_RANGE, velocityX: (Math.random() - 0.5) * PARTICLE_VX_RANGE,
velocityY: -(Math.random() * PARTICLE_VY_RANGE + PARTICLE_VY_MIN), velocityY: -(Math.random() * PARTICLE_VY_RANGE + PARTICLE_VY_MIN),
}; };
} }
function createSplash(x: number, y: number): Splash { function createSplash(x: number, y: number): Splash {
return { return {
x, x,
y, y,
age: 0, age: 0,
maxAge: 12, maxAge: 12,
particles: Array.from( particles: Array.from(
{ length: Math.floor(Math.random() * 3) + 3 }, { length: Math.floor(Math.random() * 3) + 3 },
createParticle, createParticle,
), ),
}; };
} }
function createRaindrop(gridWidth: number, gridHeight: number): Raindrop { function createRaindrop(gridWidth: number, gridHeight: number): Raindrop {
const bias = Math.random() * Math.random(); const bias = Math.random() * Math.random();
return { return {
x: Math.floor(Math.random() * gridWidth), x: Math.floor(Math.random() * gridWidth),
y: Math.floor(Math.random() * gridHeight) - gridHeight, y: Math.floor(Math.random() * gridHeight) - gridHeight,
length: Math.floor(Math.random() * 4) + 2, length: Math.floor(Math.random() * 4) + 2,
speed: RAIN_SPEED * (Math.random() * 2 + 1), speed: RAIN_SPEED * (Math.random() * 2 + 1),
opacity: Math.random() * 0.3 + 0.6, opacity: Math.random() * 0.3 + 0.6,
floorHeight: window.innerHeight * floorHeight: window.innerHeight *
(FLOOR_HEIGHT_MIN + bias * FLOOR_HEIGHT_RANGE), (FLOOR_HEIGHT_MIN + bias * FLOOR_HEIGHT_RANGE),
}; };
} }
function createStar(): Star { function createStar(): Star {
const brightness = Math.random() * STAR_BRIGHTNESS_RANGE + const brightness = Math.random() * STAR_BRIGHTNESS_RANGE +
STAR_BRIGHTNESS_MIN; STAR_BRIGHTNESS_MIN;
const colorIndex = Math.floor( const colorIndex = Math.floor(
(brightness - STAR_BRIGHTNESS_MIN) / STAR_BRIGHTNESS_RANGE * ((brightness - STAR_BRIGHTNESS_MIN) / STAR_BRIGHTNESS_RANGE) *
(NUM_COLOR_VARIATIONS - 1), (NUM_COLOR_VARIATIONS - 1),
); );
return { return {
x: Math.random() * window.innerWidth, x: Math.random() * window.innerWidth,
y: Math.random() * window.innerHeight, y: Math.random() * window.innerHeight,
size: Math.random() > STAR_LARGE_THRESHOLD size: Math.random() > STAR_LARGE_THRESHOLD
? STAR_SIZE_LARGE ? STAR_SIZE_LARGE
: STAR_SIZE_SMALL, : STAR_SIZE_SMALL,
twinkleSpeed: Math.random() * STAR_TWINKLE_RANGE + STAR_TWINKLE_MIN, twinkleSpeed: Math.random() * STAR_TWINKLE_RANGE + STAR_TWINKLE_MIN,
twinkleOffset: Math.random() * Math.PI * 2, twinkleOffset: Math.random() * Math.PI * 2,
brightness, brightness,
age: 0, age: 0,
maxAge: STAR_AGE_MIN + Math.random() * STAR_AGE_RANGE, maxAge: STAR_AGE_MIN + Math.random() * STAR_AGE_RANGE,
canVanish: false, canVanish: false,
colorIndex, colorIndex,
}; };
} }
function updateParticle(p: Particle) { function updateParticle(p: Particle) {
p.offsetX += p.velocityX; p.offsetX += p.velocityX;
p.offsetY += p.velocityY; p.offsetY += p.velocityY;
p.velocityY += PARTICLE_GRAVITY; p.velocityY += PARTICLE_GRAVITY;
} }
function updateSplash(splash: Splash) { function updateSplash(splash: Splash) {
splash.age++; splash.age++;
splash.particles.forEach(updateParticle); splash.particles.forEach(updateParticle);
} }
function updateRaindrop( function updateRaindrop(
drop: Raindrop, drop: Raindrop,
splashes: Splash[], splashes: Splash[],
gridWidth: number, gridWidth: number,
gridHeight: number, gridHeight: number,
) { ) {
drop.y += drop.speed; drop.y += drop.speed;
const dropY = drop.y * PIXEL_SIZE; const dropY = drop.y * PIXEL_SIZE;
if (dropY >= drop.floorHeight && Math.random() < SPLASH_CHANCE) { if (dropY >= drop.floorHeight && Math.random() < SPLASH_CHANCE) {
splashes.push(createSplash(drop.x, Math.floor(dropY / PIXEL_SIZE))); splashes.push(createSplash(drop.x, Math.floor(dropY / PIXEL_SIZE)));
Object.assign(drop, createRaindrop(gridWidth, gridHeight)); Object.assign(drop, createRaindrop(gridWidth, gridHeight));
} else if (dropY > window.innerHeight) { } else if (dropY > window.innerHeight) {
Object.assign(drop, createRaindrop(gridWidth, gridHeight)); Object.assign(drop, createRaindrop(gridWidth, gridHeight));
} }
} }
function updateStar(star: Star): void { function updateStar(star: Star): void {
star.age++; star.age++;
const phase = (star.age * star.twinkleSpeed + star.twinkleOffset) % const phase = (star.age * star.twinkleSpeed + star.twinkleOffset) %
(2 * Math.PI); (2 * Math.PI);
if (!star.canVanish && phase < star.twinkleSpeed) { if (!star.canVanish && phase < star.twinkleSpeed) {
star.canVanish = true; star.canVanish = true;
} }
if (star.canVanish && star.age > star.maxAge) { if (star.canVanish && star.age > star.maxAge) {
Object.assign(star, createStar()); Object.assign(star, createStar());
} else if (star.x > window.innerWidth || star.y > window.innerHeight) { } else if (star.x > window.innerWidth || star.y > window.innerHeight) {
Object.assign(star, createStar()); Object.assign(star, createStar());
} }
} }
const isSplashDead = (splash: Splash): boolean => splash.age >= splash.maxAge; const isSplashDead = (splash: Splash): boolean => splash.age >= splash.maxAge;
const drawRaindrop = (ctx: CanvasRenderingContext2D, drop: Raindrop): void => { const drawRaindrop = (ctx: CanvasRenderingContext2D, drop: Raindrop): void => {
ctx.globalAlpha = drop.opacity; ctx.globalAlpha = drop.opacity;
const xPos = drop.x * PIXEL_SIZE; const xPos = drop.x * PIXEL_SIZE;
for (let i = 0; i < drop.length; i++) { for (let i = 0; i < drop.length; i++) {
const colorIndex = Math.floor( const colorIndex = Math.floor(
(i / drop.length) * NUM_COLOR_VARIATIONS * 0.5, (i / drop.length) * NUM_COLOR_VARIATIONS * 0.5,
); );
ctx.fillStyle = RAIN_COLORS[colorIndex]; ctx.fillStyle = RAIN_COLORS[colorIndex];
ctx.fillRect(xPos, (drop.y - i) * PIXEL_SIZE, PIXEL_SIZE, PIXEL_SIZE); ctx.fillRect(xPos, (drop.y - i) * PIXEL_SIZE, PIXEL_SIZE, PIXEL_SIZE);
} }
ctx.globalAlpha = 1; ctx.globalAlpha = 1;
}; };
function drawSplash(ctx: CanvasRenderingContext2D, splash: Splash) { function drawSplash(ctx: CanvasRenderingContext2D, splash: Splash) {
if (splash.age >= splash.maxAge) return; if (splash.age >= splash.maxAge) return;
const progress = splash.age / splash.maxAge; const progress = splash.age / splash.maxAge;
ctx.globalAlpha = 1 - progress; ctx.globalAlpha = 1 - progress;
ctx.fillStyle = SPLASH_PARTICLE_COLOR; ctx.fillStyle = SPLASH_PARTICLE_COLOR;
splash.particles.forEach((p) => { splash.particles.forEach((p) => {
const px = Math.floor(splash.x + p.offsetX) * PIXEL_SIZE; const px = Math.floor(splash.x + p.offsetX) * PIXEL_SIZE;
const py = Math.floor(splash.y + p.offsetY) * PIXEL_SIZE; const py = Math.floor(splash.y + p.offsetY) * PIXEL_SIZE;
ctx.fillRect(px, py, PIXEL_SIZE, PIXEL_SIZE); ctx.fillRect(px, py, PIXEL_SIZE, PIXEL_SIZE);
}); });
if (splash.age < 6) { if (splash.age < 6) {
const rippleSize = Math.floor(splash.age / 2) + 1; const rippleSize = Math.floor(splash.age / 2) + 1;
const splashY = splash.y * PIXEL_SIZE; const splashY = splash.y * PIXEL_SIZE;
ctx.fillStyle = SPLASH_RIPPLE_COLOR; ctx.fillStyle = SPLASH_RIPPLE_COLOR;
ctx.fillRect( ctx.fillRect(
(splash.x - rippleSize) * PIXEL_SIZE, (splash.x - rippleSize) * PIXEL_SIZE,
splashY, splashY,
PIXEL_SIZE, PIXEL_SIZE,
PIXEL_SIZE, PIXEL_SIZE,
); );
ctx.fillRect( ctx.fillRect(
(splash.x + rippleSize) * PIXEL_SIZE, (splash.x + rippleSize) * PIXEL_SIZE,
splashY, splashY,
PIXEL_SIZE, PIXEL_SIZE,
PIXEL_SIZE, PIXEL_SIZE,
); );
} }
ctx.globalAlpha = 1; ctx.globalAlpha = 1;
} }
function drawStar( function drawStar(ctx: CanvasRenderingContext2D, star: Star, time: number) {
ctx: CanvasRenderingContext2D, const twinkle = Math.sin(time * star.twinkleSpeed + star.twinkleOffset) *
star: Star, STAR_TWINKLE_AMPLITUDE +
time: number, STAR_TWINKLE_BASE;
) { const alpha = star.brightness * twinkle;
const twinkle = Math.sin(time * star.twinkleSpeed + star.twinkleOffset) *
STAR_TWINKLE_AMPLITUDE + STAR_TWINKLE_BASE;
const alpha = star.brightness * twinkle;
const x = Math.floor(star.x); const x = Math.floor(star.x);
const y = Math.floor(star.y); const y = Math.floor(star.y);
const color = ALPHA_STAR_COLORS[star.colorIndex]; const color = ALPHA_STAR_COLORS[star.colorIndex];
ctx.fillStyle = color + alpha; ctx.fillStyle = color + alpha;
ctx.fillRect(x, y, star.size, star.size); ctx.fillRect(x, y, star.size, star.size);
if (star.size === STAR_SIZE_LARGE && alpha > STAR_GLOW_THRESHOLD) { if (star.size === STAR_SIZE_LARGE && alpha > STAR_GLOW_THRESHOLD) {
ctx.fillStyle = color + (alpha * STAR_GLOW_ALPHA); ctx.fillStyle = color + alpha * STAR_GLOW_ALPHA;
ctx.fillRect(x - 4, y + 2, 4, 4); ctx.fillRect(x - 4, y + 2, 4, 4);
ctx.fillRect(x + 8, y + 2, 4, 4); ctx.fillRect(x + 8, y + 2, 4, 4);
ctx.fillRect(x + 2, y - 4, 4, 4); ctx.fillRect(x + 2, y - 4, 4, 4);
ctx.fillRect(x + 2, y + 8, 4, 4); ctx.fillRect(x + 2, y + 8, 4, 4);
} }
} }
export default function Rain() { export default function Rain() {
const canvasRef = useRef<HTMLCanvasElement>(null); const canvasRef = useRef<HTMLCanvasElement>(null);
useEffect(() => { useEffect(() => {
const prefersReducedMotion = const prefersReducedMotion = window.matchMedia(
window.matchMedia("(prefers-reduced-motion: reduce)").matches; "(prefers-reduced-motion: reduce)",
if (prefersReducedMotion) return; ).matches;
if (prefersReducedMotion) return;
const canvas = canvasRef.current; const canvas = canvasRef.current;
if (!canvas) return; if (!canvas) return;
const ctx = canvas.getContext("2d"); const ctx = canvas.getContext("2d");
if (!ctx) return; if (!ctx) return;
let gridWidth = 0; let gridWidth = 0;
let gridHeight = 0; let gridHeight = 0;
const resizeCanvas = () => { const resizeCanvas = () => {
canvas.width = window.innerWidth; canvas.width = window.innerWidth;
canvas.height = window.innerHeight; canvas.height = window.innerHeight;
gridWidth = Math.floor(window.innerWidth / PIXEL_SIZE); gridWidth = Math.floor(window.innerWidth / PIXEL_SIZE);
gridHeight = Math.floor(window.innerHeight / PIXEL_SIZE); gridHeight = Math.floor(window.innerHeight / PIXEL_SIZE);
}; };
resizeCanvas(); resizeCanvas();
window.addEventListener("resize", resizeCanvas); window.addEventListener("resize", resizeCanvas);
const stars = Array.from({ length: STAR_COUNT }, createStar); const stars = Array.from({ length: STAR_COUNT }, createStar);
const raindrops = Array.from( const raindrops = Array.from(
{ length: DROP_COUNT }, { length: DROP_COUNT },
() => createRaindrop(gridWidth, gridHeight), () => createRaindrop(gridWidth, gridHeight),
); );
const splashes: Splash[] = []; const splashes: Splash[] = [];
const startTime = performance.now(); const startTime = performance.now();
const animate = (time: number) => { const animate = (time: number) => {
ctx.fillStyle = BACKGROUND_COLOUR; ctx.fillStyle = BACKGROUND_COLOUR;
ctx.fillRect(0, 0, canvas.width, canvas.height); ctx.fillRect(0, 0, canvas.width, canvas.height);
for (let i = 0; i < stars.length; i++) { for (let i = 0; i < stars.length; i++) {
updateStar(stars[i]); updateStar(stars[i]);
drawStar(ctx, stars[i], time - startTime); drawStar(ctx, stars[i], time - startTime);
} }
raindrops.forEach((drop) => raindrops.forEach((drop) =>
updateRaindrop(drop, splashes, gridWidth, gridHeight) updateRaindrop(drop, splashes, gridWidth, gridHeight)
); );
for (let i = splashes.length - 1; i >= 0; i--) { for (let i = splashes.length - 1; i >= 0; i--) {
updateSplash(splashes[i]); updateSplash(splashes[i]);
if (isSplashDead(splashes[i])) { if (isSplashDead(splashes[i])) {
splashes.splice(i, 1); splashes.splice(i, 1);
} }
} }
for (let i = 0; i < stars.length; i++) { for (let i = 0; i < stars.length; i++) {
updateStar(stars[i]); updateStar(stars[i]);
drawStar(ctx, stars[i], performance.now() - startTime); drawStar(ctx, stars[i], performance.now() - startTime);
} }
raindrops.forEach((drop) => drawRaindrop(ctx, drop)); raindrops.forEach((drop) => drawRaindrop(ctx, drop));
splashes.forEach((splash) => drawSplash(ctx, splash)); splashes.forEach((splash) => drawSplash(ctx, splash));
requestAnimationFrame(animate); requestAnimationFrame(animate);
}; };
animate(0); animate(0);
}, []); }, []);
return ( return (
<canvas <canvas
ref={canvasRef} ref={canvasRef}
style={{ aria-hidden="true"
position: "fixed", role="presentation"
top: 0, style={{
left: 0, position: "fixed",
width: "100vw", top: 0,
height: "100vh", left: 0,
imageRendering: "pixelated", width: "100vw",
background: BACKGROUND_COLOUR, height: "100vh",
}} imageRendering: "pixelated",
/> background: BACKGROUND_COLOUR,
); }}
/>
);
} }

View file

@ -7,43 +7,43 @@ import { useEffect, useState } from "preact/hooks";
import Box from "../components/Box.tsx"; import Box from "../components/Box.tsx";
export default function Time() { export default function Time() {
const formatter = new Intl.DateTimeFormat("en-US", { const formatter = new Intl.DateTimeFormat("en-US", {
hour: "numeric", hour: "numeric",
minute: "numeric", minute: "numeric",
hour12: true, hour12: true,
timeZone: "America/Sao_Paulo", timeZone: "America/Sao_Paulo",
}); });
const now = new Date(); const now = new Date();
const time = formatter.format(now); const time = formatter.format(now);
const [offset, setOffset] = useState(""); const [offset, setOffset] = useState("");
useEffect(() => { useEffect(() => {
const br = new Date( const br = new Date(
now.toLocaleString("en-US", { now.toLocaleString("en-US", {
timeZone: "America/Sao_Paulo", timeZone: "America/Sao_Paulo",
}), }),
); );
const local = new Date(now.toLocaleString("en-US")); const local = new Date(now.toLocaleString("en-US"));
const diff = br.getTime() - local.getTime(); const diff = br.getTime() - local.getTime();
const ms = Math.abs(diff); const ms = Math.abs(diff);
const hours = ~~(ms / 36e5); const hours = ~~(ms / 36e5);
const minutes = ~~((ms / 6e4) % 60); const minutes = ~~((ms / 6e4) % 60);
let output = " · "; let output = " · ";
if (hours) output += `You're ${hours} hour${hours > 1 ? "s" : ""} `; if (hours) output += `You're ${hours} hour${hours > 1 ? "s" : ""} `;
if (hours && minutes) output += "and "; if (hours && minutes) output += "and ";
if (minutes) output += `${minutes} minute${minutes > 1 ? "s" : ""} `; if (minutes) output += `${minutes} minute${minutes > 1 ? "s" : ""} `;
if (hours || minutes) output += diff > 0 ? "behind" : "ahead"; if (hours || minutes) output += diff > 0 ? "behind" : "ahead";
else output = " · Hey, we're in the same time zone!"; else output = " · Hey, we're in the same time zone!";
setOffset(output); setOffset(output);
}, []); }, []);
return ( return (
<Box> <Box>
Brasília Time, {time} Brasília Time, {time}
{offset} {offset}
</Box> </Box>
); );
} }

View file

@ -6,26 +6,26 @@
import { define } from "../utils.ts"; import { define } from "../utils.ts";
export default define.page(function App({ Component }) { export default define.page(function App({ Component }) {
return ( return (
<html lang="en"> <html lang="en">
<head> <head>
<meta charset="utf-8" /> <meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="icon" type="image/png" href="/favicon.png" /> <link rel="icon" type="image/png" href="/favicon.png" />
<meta property="og:site_name" content="acpi.at" /> <meta property="og:site_name" content="acpi.at" />
<meta property="og:type" content="profile" /> <meta property="og:type" content="profile" />
<meta <meta
property="og:description" property="og:description"
content="one of the girls of all time" content="one of the girls of all time"
/> />
<meta property="og:image" content="https://acpi.at/bnuy.webp" /> <meta property="og:image" content="https://acpi.at/bnuy.webp" />
<meta property="og:title" content="mux's winterhouse" /> <meta property="og:title" content="mux's winterhouse" />
<meta name="theme-color" content="#a0bdfc" /> <meta name="theme-color" content="#a0bdfc" />
<title>mux's winterhouse</title> <title>mux's winterhouse</title>
</head> </head>
<body> <body>
<Component /> <Component />
</body> </body>
</html> </html>
); );
}); });

View file

@ -17,292 +17,284 @@ import Meow from "../islands/Meow.tsx";
import Name from "../islands/Name.tsx"; import Name from "../islands/Name.tsx";
import Code from "../islands/Code.tsx"; import Code from "../islands/Code.tsx";
import { import {
AttachmentIcon, AttachmentIcon,
BlueskyIcon, BitcoinCashIcon,
CodebergIcon, BitcoinIcon,
DiscordIcon, BlueskyIcon,
ForgejoIcon, CodebergIcon,
GitHubIcon, CommentIcon,
LabelIcon, DiscordIcon,
LastfmIcon, EthereumIcon,
MailIcon, ForgejoIcon,
SignalIcon, GitHubIcon,
TwitterIcon, GitHubSponsorsIcon,
CommentIcon, HeartIcon,
HeartIcon, KofiIcon,
KofiIcon, LabelIcon,
BitcoinIcon, LastfmIcon,
BitcoinCashIcon, LitecoinIcon,
MoneroIcon, MailIcon,
NanoIcon, MoneroIcon,
LitecoinIcon, NanoIcon,
EthereumIcon, SignalIcon,
TwitterIcon,
} from "../components/Icon.tsx"; } from "../components/Icon.tsx";
export default define.page(() => { export default define.page(() => {
return ( return (
<> <>
<Rain /> <Rain />
<Centered> <Centered>
<Header /> <Header />
<Section> <Section>
<Title> <Title>
<HeartIcon class="icon" /> <HeartIcon class="icon" />
About me About me
</Title> </Title>
<p class="intro"> <p class="alt">
<span> <small>
{" "} <i>
muxiepuff{" "} uhhhhh g'day, name's laura and i go by she/her pronouns and i'm
<span class="alt alt-font">(/ˈmuˌksipʌf/, she/her)</span> a veeeery sweet <s>autist</s>{" "}
{" · "} girl passionate about free software!! ty for your time ^^
</span> </i>
I'm just your average advocate for open access to information and </small>
knowledge and aspiring electrical engineer with complementary </p>
interests in systems programming and linguistics. Neurodivergent <p class="intro">
student passionate about libre software. Advocate for open access to information and knowledge and aspiring
</p> electrical engineer with complementary interests in systems
<p class="intro"> programming and linguistics.
On the side, I maintain a modest FreeBSD server where I self-host </p>
this website and various services. This is nothing particularly <p class="intro">
impressive, just a growing curiosity about systems administration. On the side, I maintain a modest FreeBSD server where I self-host
Service status and uptime available{" "} this website and various services. This is nothing particularly
<Link href="https://glance.acpi.at">here</Link>. impressive, just a growing curiosity about systems administration.
</p> Service status and uptime available{" "}
<Time /> <Link href="https://glance.acpi.at">here</Link>.
</Section> </p>
<Section> <Time />
<Title> </Section>
<LabelIcon class="icon" /> <Section>
Links <Title>
</Title> <LabelIcon class="icon" />
<div> Links
<Title level={3}>Social platforms</Title> </Title>
<ul class="labeled-icons"> <div>
<li> <Title level={2}>Social platforms</Title>
<Box as="a" href="https://bsky.app/profile/acpi.at"> <ul class="labeled-icons">
<BlueskyIcon /> @acpi.at <li>
</Box> <Box as="a" href="https://bsky.app/profile/acpi.at">
</li> <BlueskyIcon /> @acpi.at
<li> </Box>
<Box as="a" href="https://last.fm/user/auwora"> </li>
<LastfmIcon /> @auwora <li>
</Box> <Box as="a" href="https://last.fm/user/auwora">
</li> <LastfmIcon /> @auwora
</ul> </Box>
</div> </li>
<div> </ul>
<Title level={3}>Software and code</Title> </div>
<ul class="labeled-icons"> <div>
<li> <Title level={2}>Software and code</Title>
<Box as="a" href="https://git.acpi.at/mux"> <ul class="labeled-icons">
<ForgejoIcon /> mux <li>
</Box> <Box as="a" href="https://git.acpi.at/w">
</li> <ForgejoIcon /> w
<li> </Box>
<Box as="a" href="https://codeberg.org/ex"> </li>
<CodebergIcon /> ex <li>
</Box> <Box as="a" href="https://codeberg.org/ex">
</li> <CodebergIcon /> ex
<li> </Box>
<Box as="a" href="https://github.com/xwra"> </li>
<GitHubIcon /> xwra <li>
</Box> <Box as="a" href="https://github.com/misties">
</li> <GitHubIcon /> misties
</ul> </Box>
</div> </li>
<div> </ul>
<Title level={3}>Congenial folks</Title> </div>
<ul class="labeled-icons b88x31"> <div>
<li> <Title level={2}>Congenial folks</Title>
<Meow /> <ul class="labeled-icons b88x31">
</li> <li>
<li> <Meow />
<a href="https://worf.win"> </li>
<img <li>
src="https://worf.win/images/worfwin.gif" <a href="https://worf.win">
title="worf" <img src="https://worf.win/images/worfwin.gif" alt="worf" />
alt="worf" </a>
/> </li>
</a> <li>
</li> <a href="https://codeberg.org/paige">
<li> <img src="/88x31/paige.gif" alt="paige" />
<a href="https://codeberg.org/paige"> </a>
<img src="/88x31/paige.gif" title="paige" alt="paige" /> </li>
</a> <li>
</li> <a href="https://mugman.tech">
<li> <img src="https://mugman.tech/88x31/me.gif" alt="mugman" />
<a href="https://mugman.tech"> </a>
<img </li>
src="https://mugman.tech/88x31/me.gif" <li>
title="mugman" <a href="https://f.dog">
alt="mugman" <img
/> src="https://x86.pet/~strawberry/june_88x31.png"
</a> alt="june"
</li> />
<li> </a>
<a href="https://f.dog"> </li>
<img <li>
src="https://x86.pet/~strawberry/june_88x31.png" <a
title="june" rel="noopener"
alt="june" referrerpolicy="strict-origin"
/> href="https://rushii.dev"
</a> >
</li> <img
<li> src="https://rushii.dev/88x31/rushii.webp"
<a alt="rushii's site"
rel="noopener" />
referrerpolicy="strict-origin" </a>
href="https://rushii.dev" </li>
> <li>
<img <a href="https://www.juwuba.xyz">
src="https://rushii.dev/88x31/rushii.webp" <img src="https://www.juwuba.xyz/88x31.gif" alt="Júlia" />
title="rushii's site" </a>
alt="rushii's site" </li>
/> <li>
</a> <a href="https://katelyn.moe/">
</li> <img src="https://katelyn.moe/8831.png" alt="katelyn" />
<li> </a>
<a href="https://www.juwuba.xyz"> </li>
<img <li>
src="https://www.juwuba.xyz/88x31.gif" <a href="https://meow-d.github.io">
title="Júlia" <img src="/88x31/meow_d.webp" alt="meow_d" />
alt="Júlia" </a>
/> </li>
</a> <li>
</li> <a href="https://caitlyn.moe">
<li> <img src="https://caitlyn.moe/88x31.png" alt="caitlyn" />
<a href="https://katelyn.moe/"> </a>
<img </li>
src="https://katelyn.moe/8831.png" </ul>
title="katelyn" </div>
alt="katelyn" </Section>
/> <Section>
</a> <Title>
</li> <CommentIcon class="icon" />
<li> Contact
<a href="https://meow-d.github.io"> </Title>
<img src="/88x31/meow_d.webp" title="meow_d" alt="meow_d" /> <p class="intro">
</a> Feel free to reach out through any of the platforms listed above.
</li> For email correspondence, you can reach me at{" "}
<li> <Code>base64 -d &lt;&lt;&lt; bXV4QGFjcGkuYXQK</Code>.
<a href="https://caitlyn.moe"> </p>
<img <p class="intro">
src="https://caitlyn.moe/88x31.png" Psst! When discussing sensitive matters over email or other insecure
title="caitlyn" communication channels, I'd really appreciate it if you could
alt="caitlyn" encrypt your message with my{" "}
/> <Link href="/pgp-key.asc">PGP key</Link> (fingerprint:{" "}
</a> <Code>AC14 9A39 5013 C572 CA74 8799 BCD2 117C 99E6 9817</Code>).
</li> </p>
</ul> <div>
</div> <Title level={2}>Communication</Title>
</Section> <ul class="labeled-icons">
<Section> <li>
<Title> <Box as="a" href="https://discord.com/users/797566974024351745">
<CommentIcon class="icon" /> <DiscordIcon /> @wwwife
Contact </Box>
</Title> </li>
<p class="intro"> <li>
Feel free to reach out through any of the platforms listed above. <Box
For email correspondence, you can reach me at{" "} as="a"
<Code>base64 -d &lt;&lt;&lt; bXV4QGFjcGkuYXQK</Code>. href="https://signal.me/#eu/yT8nprAP8x3r7RwHXKKMEiSirvd1OJ7azkDBbtE7_ICqtKH-z_NM7Kqv13e9hiv-"
</p> >
<p class="intro"> <SignalIcon /> @laura.120
Psst! When discussing sensitive matters over email or other insecure </Box>
communication channels, I'd really appreciate it if you could </li>
encrypt your message with my <Link href="/pgp-key.asc">PGP key</Link>{" "} </ul>
(fingerprint:{" "} </div>
<Code>AC14 9A39 5013 C572 CA74 8799 BCD2 117C 99E6 9817</Code>). <hr />
</p> <p class="intro">
<div> If you enjoy throwing money at people on the internet, please
<Title level={3}>Communication</Title> consider me! It keeps the server alive, fuels my tinkering with
<ul class="labeled-icons"> esoteric technology, and helps me navigate some rough financial
<li> patches and stay afloat while things are tight.
<Box as="a" href="https://discord.com/users/797566974024351745"> </p>
<DiscordIcon /> @muxiepuff <div>
</Box> <Title level={2}>Donations</Title>
</li> <ul class="labeled-icons full">
<li> <li>
<Box <Box as="a" href="https://ko-fi.com/west" title="Ko-fi">
as="a" <KofiIcon /> west
href="https://signal.me/#eu/gdveRFng4iFhFkB4m5Esr2ciQ5FWZTeSFrCGa2osQ7ZrSu2d48RCdqgDc2nEzWQq" </Box>
> </li>
<SignalIcon /> @mux.01 <li>
</Box> <Box
</li> as="a"
</ul> href="https://github.com/sponsors/xwra"
</div> title="GitHub Sponsors"
<hr /> >
<p class="intro"> <GitHubSponsorsIcon /> xwra
If you enjoy throwing money at people on the internet, please </Box>
consider me! It keeps the server alive, fuels my tinkering with </li>
esoteric technology, and helps me navigate some rough financial <li>
patches and stay afloat while things are tight. <Box as="span" title="Monero (XMR)">
</p> <MoneroIcon />{" "}
<div> 456tmp4CU158sV95Pjh75QfMcANNsRCFTdpmc86G31eKg9urvcYunnuBVyUmazAbuihUXwRDVojkhFTbzg6X2GuAJ7t3MCT
<Title level={3}>Donations</Title> </Box>
<ul class="labeled-icons full"> </li>
<li> <li>
<Box as="a" href="https://ko-fi.com/west"> <Box as="span" title="Litecoin (LTC)">
<KofiIcon /> west <LitecoinIcon /> ltc1ql30jtr2r0pkr0wshspf465rdupvlpmwacql7wp
</Box> </Box>
</li> </li>
<li> <li>
<Box as="span"> <Box as="span" title="Nano (XNO)">
<MoneroIcon />{" "} <NanoIcon />{" "}
456tmp4CU158sV95Pjh75QfMcANNsRCFTdpmc86G31eKg9urvcYunnuBVyUmazAbuihUXwRDVojkhFTbzg6X2GuAJ7t3MCT nano_1qbbwrzxnutw53kuykdo6zcwteawf3befpbf95zrz66b33yxpz5ans6wrw4w
</Box> </Box>
</li> </li>
<li> <li>
<Box as="span"> <Box as="span" title="Bitcoin (BTC)">
<LitecoinIcon /> ltc1ql30jtr2r0pkr0wshspf465rdupvlpmwacql7wp <BitcoinIcon /> bc1qj3l6cpxz604vlfz5zqlnhzr7g0aq7xlslnmzcm
</Box> </Box>
</li> </li>
<li> <li>
<Box as="span"> <Box as="span" title="Bitcoin Cash (BCH)">
<NanoIcon />{" "}nano_1qbbwrzxnutw53kuykdo6zcwteawf3befpbf95zrz66b33yxpz5ans6wrw4w <BitcoinCashIcon />{" "}
</Box> bitcoincash:qrs8y70dwzvz2kvxnv30c9k4pxa0vatzvudle5aaa3
</li> </Box>
<li> </li>
<Box as="span"> <li>
<BitcoinIcon />{" "} bc1qj3l6cpxz604vlfz5zqlnhzr7g0aq7xlslnmzcm <Box as="span" title="Ethereum (ETH)">
</Box> <EthereumIcon /> 0x9bb671035Dde19C674769592AbC20E63f36b5Aa9
</li> </Box>
<li> </li>
<Box as="span"> </ul>
<BitcoinCashIcon />{" "}bitcoincash:qrs8y70dwzvz2kvxnv30c9k4pxa0vatzvudle5aaa3 </div>
</Box> </Section>
</li> <Section>
<li> <Title>
<Box as="span"> <AttachmentIcon class="icon" />
<EthereumIcon />{" "}0x9bb671035Dde19C674769592AbC20E63f36b5Aa9 Extra
</Box> </Title>
</li> <ul id="extra">
</ul> <li>
</div> <TintedImage
</Section> src="/extra/mumengo.gif"
<Section> colour="var(--theme-accent-title)"
<Title> />
<AttachmentIcon class="icon" /> </li>
Extra <li>
</Title> <TintedImage
<ul id="extra"> src="/extra/nenezil.gif"
<li> colour="var(--theme-accent-title)"
<TintedImage />
src="/extra/mumengo.gif" </li>
colour="var(--theme-accent-title)" </ul>
/> </Section>
</li> <Footer />
<li> </Centered>
<TintedImage </>
src="/extra/nenezil.gif" );
colour="var(--theme-accent-title)"
/>
</li>
</ul>
</Section>
<Footer />
</Centered>
</>
);
}); });

View file

@ -15,17 +15,17 @@ const copyrightHeader = `/**
const dir = "./"; const dir = "./";
for await ( for await (
const entry of walk(dir, { const entry of walk(dir, {
exts: [".ts", ".tsx"], exts: [".ts", ".tsx"],
includeDirs: false, includeDirs: false,
skip: [/node_modules/, /copyright\.ts$/], skip: [/node_modules/, /copyright\.ts$/],
}) })
) { ) {
const filePath = entry.path; const filePath = entry.path;
const content = await Deno.readTextFile(filePath); const content = await Deno.readTextFile(filePath);
if (!content.startsWith(copyrightHeader)) { if (!content.startsWith(copyrightHeader)) {
await Deno.writeTextFile(filePath, copyrightHeader + "\n" + content); await Deno.writeTextFile(filePath, copyrightHeader + "\n" + content);
console.log(`Added header to ${filePath}`); console.log(`Added header to ${filePath}`);
} }
} }

View file

@ -1,243 +1,243 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<svg <svg
version="1.1" version="1.1"
width="380" width="380"
height="380" height="380"
xmlns="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"
shape-rendering="crispEdges" shape-rendering="crispEdges"
> >
<rect x="80" y="70" width="30" height="10" fill="#1E2545" /> <rect x="80" y="70" width="30" height="10" fill="#1E2545" />
<rect x="270" y="70" width="30" height="10" fill="#1E2545" /> <rect x="270" y="70" width="30" height="10" fill="#1E2545" />
<rect x="60" y="80" width="20" height="10" fill="#1E2545" /> <rect x="60" y="80" width="20" height="10" fill="#1E2545" />
<rect x="80" y="80" width="10" height="10" fill="#5E76AB" /> <rect x="80" y="80" width="10" height="10" fill="#5E76AB" />
<rect x="90" y="80" width="10" height="20" fill="#A0BDFC" /> <rect x="90" y="80" width="10" height="20" fill="#A0BDFC" />
<rect x="100" y="80" width="10" height="10" fill="#5E76AB" /> <rect x="100" y="80" width="10" height="10" fill="#5E76AB" />
<rect x="110" y="80" width="20" height="10" fill="#1E2545" /> <rect x="110" y="80" width="20" height="10" fill="#1E2545" />
<rect x="250" y="80" width="20" height="10" fill="#1E2545" /> <rect x="250" y="80" width="20" height="10" fill="#1E2545" />
<rect x="270" y="80" width="10" height="10" fill="#5E76AB" /> <rect x="270" y="80" width="10" height="10" fill="#5E76AB" />
<rect x="280" y="80" width="10" height="20" fill="#A0BDFC" /> <rect x="280" y="80" width="10" height="20" fill="#A0BDFC" />
<rect x="290" y="80" width="10" height="10" fill="#5E76AB" /> <rect x="290" y="80" width="10" height="10" fill="#5E76AB" />
<rect x="300" y="80" width="20" height="10" fill="#1E2545" /> <rect x="300" y="80" width="20" height="10" fill="#1E2545" />
<rect x="50" y="90" width="10" height="10" fill="#1E2545" /> <rect x="50" y="90" width="10" height="10" fill="#1E2545" />
<rect x="60" y="90" width="10" height="10" fill="#5E76AB" /> <rect x="60" y="90" width="10" height="10" fill="#5E76AB" />
<rect x="70" y="90" width="20" height="10" fill="#A0BDFC" /> <rect x="70" y="90" width="20" height="10" fill="#A0BDFC" />
<rect x="100" y="90" width="20" height="10" fill="#A0BDFC" /> <rect x="100" y="90" width="20" height="10" fill="#A0BDFC" />
<rect x="120" y="90" width="10" height="10" fill="#5E76AB" /> <rect x="120" y="90" width="10" height="10" fill="#5E76AB" />
<rect x="130" y="90" width="10" height="10" fill="#1E2545" /> <rect x="130" y="90" width="10" height="10" fill="#1E2545" />
<rect x="240" y="90" width="10" height="10" fill="#1E2545" /> <rect x="240" y="90" width="10" height="10" fill="#1E2545" />
<rect x="250" y="90" width="10" height="10" fill="#5E76AB" /> <rect x="250" y="90" width="10" height="10" fill="#5E76AB" />
<rect x="260" y="90" width="20" height="10" fill="#A0BDFC" /> <rect x="260" y="90" width="20" height="10" fill="#A0BDFC" />
<rect x="290" y="90" width="20" height="10" fill="#A0BDFC" /> <rect x="290" y="90" width="20" height="10" fill="#A0BDFC" />
<rect x="310" y="90" width="10" height="10" fill="#5E76AB" /> <rect x="310" y="90" width="10" height="10" fill="#5E76AB" />
<rect x="320" y="90" width="10" height="10" fill="#1E2545" /> <rect x="320" y="90" width="10" height="10" fill="#1E2545" />
<rect x="40" y="100" width="10" height="10" fill="#1E2545" /> <rect x="40" y="100" width="10" height="10" fill="#1E2545" />
<rect x="50" y="100" width="10" height="10" fill="#5E76AB" /> <rect x="50" y="100" width="10" height="10" fill="#5E76AB" />
<rect x="60" y="100" width="40" height="60" fill="#DFF2FE" /> <rect x="60" y="100" width="40" height="60" fill="#DFF2FE" />
<rect x="100" y="100" width="10" height="10" fill="#FAFEFF" /> <rect x="100" y="100" width="10" height="10" fill="#FAFEFF" />
<rect x="110" y="100" width="30" height="10" fill="#A0BDFC" /> <rect x="110" y="100" width="30" height="10" fill="#A0BDFC" />
<rect x="140" y="100" width="10" height="10" fill="#1E2545" /> <rect x="140" y="100" width="10" height="10" fill="#1E2545" />
<rect x="230" y="100" width="10" height="10" fill="#1E2545" /> <rect x="230" y="100" width="10" height="10" fill="#1E2545" />
<rect x="240" y="100" width="30" height="10" fill="#A0BDFC" /> <rect x="240" y="100" width="30" height="10" fill="#A0BDFC" />
<rect x="270" y="100" width="10" height="10" fill="#FAFEFF" /> <rect x="270" y="100" width="10" height="10" fill="#FAFEFF" />
<rect x="280" y="100" width="40" height="60" fill="#DFF2FE" /> <rect x="280" y="100" width="40" height="60" fill="#DFF2FE" />
<rect x="320" y="100" width="10" height="10" fill="#5E76AB" /> <rect x="320" y="100" width="10" height="10" fill="#5E76AB" />
<rect x="330" y="100" width="10" height="10" fill="#1E2545" /> <rect x="330" y="100" width="10" height="10" fill="#1E2545" />
<rect x="30" y="110" width="10" height="10" fill="#1E2545" /> <rect x="30" y="110" width="10" height="10" fill="#1E2545" />
<rect x="40" y="110" width="10" height="10" fill="#A0BDFC" /> <rect x="40" y="110" width="10" height="10" fill="#A0BDFC" />
<rect x="50" y="110" width="10" height="70" fill="#DFF2FE" /> <rect x="50" y="110" width="10" height="70" fill="#DFF2FE" />
<rect x="100" y="110" width="10" height="50" fill="#DFF2FE" /> <rect x="100" y="110" width="10" height="50" fill="#DFF2FE" />
<rect x="110" y="110" width="10" height="10" fill="#FAFEFF" /> <rect x="110" y="110" width="10" height="10" fill="#FAFEFF" />
<rect x="120" y="110" width="10" height="10" fill="#C0D4FF" /> <rect x="120" y="110" width="10" height="10" fill="#C0D4FF" />
<rect x="130" y="110" width="20" height="10" fill="#A0BDFC" /> <rect x="130" y="110" width="20" height="10" fill="#A0BDFC" />
<rect x="150" y="110" width="10" height="10" fill="#1E2545" /> <rect x="150" y="110" width="10" height="10" fill="#1E2545" />
<rect x="220" y="110" width="10" height="10" fill="#1E2545" /> <rect x="220" y="110" width="10" height="10" fill="#1E2545" />
<rect x="230" y="110" width="20" height="10" fill="#A0BDFC" /> <rect x="230" y="110" width="20" height="10" fill="#A0BDFC" />
<rect x="250" y="110" width="10" height="10" fill="#C0D4FF" /> <rect x="250" y="110" width="10" height="10" fill="#C0D4FF" />
<rect x="260" y="110" width="10" height="10" fill="#FAFEFF" /> <rect x="260" y="110" width="10" height="10" fill="#FAFEFF" />
<rect x="270" y="110" width="10" height="50" fill="#DFF2FE" /> <rect x="270" y="110" width="10" height="50" fill="#DFF2FE" />
<rect x="320" y="110" width="10" height="70" fill="#DFF2FE" /> <rect x="320" y="110" width="10" height="70" fill="#DFF2FE" />
<rect x="330" y="110" width="10" height="10" fill="#A0BDFC" /> <rect x="330" y="110" width="10" height="10" fill="#A0BDFC" />
<rect x="340" y="110" width="10" height="10" fill="#1E2545" /> <rect x="340" y="110" width="10" height="10" fill="#1E2545" />
<rect x="20" y="120" width="10" height="10" fill="#1E2545" /> <rect x="20" y="120" width="10" height="10" fill="#1E2545" />
<rect x="30" y="120" width="10" height="10" fill="#A0BDFC" /> <rect x="30" y="120" width="10" height="10" fill="#A0BDFC" />
<rect x="40" y="120" width="10" height="60" fill="#DFF2FE" /> <rect x="40" y="120" width="10" height="60" fill="#DFF2FE" />
<rect x="110" y="120" width="20" height="50" fill="#DFF2FE" /> <rect x="110" y="120" width="20" height="50" fill="#DFF2FE" />
<rect x="130" y="120" width="10" height="10" fill="#FAFEFF" /> <rect x="130" y="120" width="10" height="10" fill="#FAFEFF" />
<rect x="140" y="120" width="10" height="10" fill="#A0BDFC" /> <rect x="140" y="120" width="10" height="10" fill="#A0BDFC" />
<rect x="150" y="120" width="10" height="10" fill="#5E76AB" /> <rect x="150" y="120" width="10" height="10" fill="#5E76AB" />
<rect x="160" y="120" width="10" height="10" fill="#1E2545" /> <rect x="160" y="120" width="10" height="10" fill="#1E2545" />
<rect x="210" y="120" width="10" height="10" fill="#1E2545" /> <rect x="210" y="120" width="10" height="10" fill="#1E2545" />
<rect x="220" y="120" width="10" height="10" fill="#5E76AB" /> <rect x="220" y="120" width="10" height="10" fill="#5E76AB" />
<rect x="230" y="120" width="10" height="10" fill="#A0BDFC" /> <rect x="230" y="120" width="10" height="10" fill="#A0BDFC" />
<rect x="240" y="120" width="10" height="10" fill="#FAFEFF" /> <rect x="240" y="120" width="10" height="10" fill="#FAFEFF" />
<rect x="250" y="120" width="20" height="50" fill="#DFF2FE" /> <rect x="250" y="120" width="20" height="50" fill="#DFF2FE" />
<rect x="330" y="120" width="10" height="60" fill="#DFF2FE" /> <rect x="330" y="120" width="10" height="60" fill="#DFF2FE" />
<rect x="340" y="120" width="10" height="10" fill="#A0BDFC" /> <rect x="340" y="120" width="10" height="10" fill="#A0BDFC" />
<rect x="350" y="120" width="10" height="10" fill="#1E2545" /> <rect x="350" y="120" width="10" height="10" fill="#1E2545" />
<rect x="10" y="130" width="10" height="10" fill="#1E2545" /> <rect x="10" y="130" width="10" height="10" fill="#1E2545" />
<rect x="20" y="130" width="10" height="50" fill="#A0BDFC" /> <rect x="20" y="130" width="10" height="50" fill="#A0BDFC" />
<rect x="30" y="130" width="10" height="40" fill="#DFF2FE" /> <rect x="30" y="130" width="10" height="40" fill="#DFF2FE" />
<rect x="130" y="130" width="10" height="30" fill="#DFF2FE" /> <rect x="130" y="130" width="10" height="30" fill="#DFF2FE" />
<rect x="140" y="130" width="10" height="30" fill="#FAFEFF" /> <rect x="140" y="130" width="10" height="30" fill="#FAFEFF" />
<rect x="150" y="130" width="20" height="60" fill="#A0BDFC" /> <rect x="150" y="130" width="20" height="60" fill="#A0BDFC" />
<rect x="170" y="130" width="10" height="10" fill="#1E2545" /> <rect x="170" y="130" width="10" height="10" fill="#1E2545" />
<rect x="200" y="130" width="10" height="10" fill="#1E2545" /> <rect x="200" y="130" width="10" height="10" fill="#1E2545" />
<rect x="210" y="130" width="20" height="60" fill="#A0BDFC" /> <rect x="210" y="130" width="20" height="60" fill="#A0BDFC" />
<rect x="230" y="130" width="10" height="30" fill="#FAFEFF" /> <rect x="230" y="130" width="10" height="30" fill="#FAFEFF" />
<rect x="240" y="130" width="10" height="30" fill="#DFF2FE" /> <rect x="240" y="130" width="10" height="30" fill="#DFF2FE" />
<rect x="340" y="130" width="10" height="40" fill="#DFF2FE" /> <rect x="340" y="130" width="10" height="40" fill="#DFF2FE" />
<rect x="350" y="130" width="10" height="50" fill="#A0BDFC" /> <rect x="350" y="130" width="10" height="50" fill="#A0BDFC" />
<rect x="360" y="130" width="10" height="10" fill="#1E2545" /> <rect x="360" y="130" width="10" height="10" fill="#1E2545" />
<rect x="0" y="140" width="10" height="30" fill="#1E2545" /> <rect x="0" y="140" width="10" height="30" fill="#1E2545" />
<rect x="10" y="140" width="10" height="10" fill="#5E76AB" /> <rect x="10" y="140" width="10" height="10" fill="#5E76AB" />
<rect x="170" y="140" width="10" height="10" fill="#5E76AB" /> <rect x="170" y="140" width="10" height="10" fill="#5E76AB" />
<rect x="180" y="140" width="20" height="10" fill="#1E2545" /> <rect x="180" y="140" width="20" height="10" fill="#1E2545" />
<rect x="200" y="140" width="10" height="10" fill="#5E76AB" /> <rect x="200" y="140" width="10" height="10" fill="#5E76AB" />
<rect x="360" y="140" width="10" height="10" fill="#5E76AB" /> <rect x="360" y="140" width="10" height="10" fill="#5E76AB" />
<rect x="370" y="140" width="10" height="30" fill="#1E2545" /> <rect x="370" y="140" width="10" height="30" fill="#1E2545" />
<rect x="10" y="150" width="10" height="10" fill="#A0BDFC" /> <rect x="10" y="150" width="10" height="10" fill="#A0BDFC" />
<rect x="170" y="150" width="10" height="30" fill="#A0BDFC" /> <rect x="170" y="150" width="10" height="30" fill="#A0BDFC" />
<rect x="180" y="150" width="20" height="10" fill="#5E76AB" /> <rect x="180" y="150" width="20" height="10" fill="#5E76AB" />
<rect x="200" y="150" width="10" height="30" fill="#A0BDFC" /> <rect x="200" y="150" width="10" height="30" fill="#A0BDFC" />
<rect x="360" y="150" width="10" height="10" fill="#A0BDFC" /> <rect x="360" y="150" width="10" height="10" fill="#A0BDFC" />
<rect x="10" y="160" width="10" height="10" fill="#5E76AB" /> <rect x="10" y="160" width="10" height="10" fill="#5E76AB" />
<rect x="60" y="160" width="10" height="10" fill="#DFF2FE" /> <rect x="60" y="160" width="10" height="10" fill="#DFF2FE" />
<rect x="70" y="160" width="10" height="10" fill="#FAFEFF" /> <rect x="70" y="160" width="10" height="10" fill="#FAFEFF" />
<rect x="80" y="160" width="10" height="10" fill="#C0D4FF" /> <rect x="80" y="160" width="10" height="10" fill="#C0D4FF" />
<rect x="90" y="160" width="20" height="10" fill="#A0BDFC" /> <rect x="90" y="160" width="20" height="10" fill="#A0BDFC" />
<rect x="130" y="160" width="10" height="10" fill="#FAFEFF" /> <rect x="130" y="160" width="10" height="10" fill="#FAFEFF" />
<rect x="140" y="160" width="10" height="50" fill="#A0BDFC" /> <rect x="140" y="160" width="10" height="50" fill="#A0BDFC" />
<rect x="180" y="160" width="20" height="10" fill="#A0BDFC" /> <rect x="180" y="160" width="20" height="10" fill="#A0BDFC" />
<rect x="230" y="160" width="10" height="50" fill="#A0BDFC" /> <rect x="230" y="160" width="10" height="50" fill="#A0BDFC" />
<rect x="240" y="160" width="10" height="10" fill="#FAFEFF" /> <rect x="240" y="160" width="10" height="10" fill="#FAFEFF" />
<rect x="270" y="160" width="20" height="10" fill="#A0BDFC" /> <rect x="270" y="160" width="20" height="10" fill="#A0BDFC" />
<rect x="290" y="160" width="10" height="10" fill="#C0D4FF" /> <rect x="290" y="160" width="10" height="10" fill="#C0D4FF" />
<rect x="300" y="160" width="10" height="10" fill="#FAFEFF" /> <rect x="300" y="160" width="10" height="10" fill="#FAFEFF" />
<rect x="310" y="160" width="10" height="10" fill="#DFF2FE" /> <rect x="310" y="160" width="10" height="10" fill="#DFF2FE" />
<rect x="360" y="160" width="10" height="10" fill="#5E76AB" /> <rect x="360" y="160" width="10" height="10" fill="#5E76AB" />
<rect x="10" y="170" width="10" height="10" fill="#1E2545" /> <rect x="10" y="170" width="10" height="10" fill="#1E2545" />
<rect x="30" y="170" width="10" height="20" fill="#A0BDFC" /> <rect x="30" y="170" width="10" height="20" fill="#A0BDFC" />
<rect x="60" y="170" width="10" height="10" fill="#FAFEFF" /> <rect x="60" y="170" width="10" height="10" fill="#FAFEFF" />
<rect x="70" y="170" width="20" height="10" fill="#A0BDFC" /> <rect x="70" y="170" width="20" height="10" fill="#A0BDFC" />
<rect x="90" y="170" width="10" height="10" fill="#1E2545" /> <rect x="90" y="170" width="10" height="10" fill="#1E2545" />
<rect x="100" y="170" width="40" height="10" fill="#A0BDFC" /> <rect x="100" y="170" width="40" height="10" fill="#A0BDFC" />
<rect x="180" y="170" width="20" height="70" fill="#DFF2FE" /> <rect x="180" y="170" width="20" height="70" fill="#DFF2FE" />
<rect x="240" y="170" width="40" height="10" fill="#A0BDFC" /> <rect x="240" y="170" width="40" height="10" fill="#A0BDFC" />
<rect x="280" y="170" width="10" height="10" fill="#1E2545" /> <rect x="280" y="170" width="10" height="10" fill="#1E2545" />
<rect x="290" y="170" width="20" height="10" fill="#A0BDFC" /> <rect x="290" y="170" width="20" height="10" fill="#A0BDFC" />
<rect x="310" y="170" width="10" height="10" fill="#FAFEFF" /> <rect x="310" y="170" width="10" height="10" fill="#FAFEFF" />
<rect x="340" y="170" width="10" height="20" fill="#A0BDFC" /> <rect x="340" y="170" width="10" height="20" fill="#A0BDFC" />
<rect x="360" y="170" width="10" height="10" fill="#1E2545" /> <rect x="360" y="170" width="10" height="10" fill="#1E2545" />
<rect x="20" y="180" width="10" height="10" fill="#1E2545" /> <rect x="20" y="180" width="10" height="10" fill="#1E2545" />
<rect x="40" y="180" width="10" height="10" fill="#A0BDFC" /> <rect x="40" y="180" width="10" height="10" fill="#A0BDFC" />
<rect x="50" y="180" width="10" height="10" fill="#FAFEFF" /> <rect x="50" y="180" width="10" height="10" fill="#FAFEFF" />
<rect x="60" y="180" width="20" height="10" fill="#A0BDFC" /> <rect x="60" y="180" width="20" height="10" fill="#A0BDFC" />
<rect x="80" y="180" width="10" height="10" fill="#1E2545" /> <rect x="80" y="180" width="10" height="10" fill="#1E2545" />
<rect x="100" y="180" width="10" height="10" fill="#1E2545" /> <rect x="100" y="180" width="10" height="10" fill="#1E2545" />
<rect x="110" y="180" width="30" height="30" fill="#A0BDFC" /> <rect x="110" y="180" width="30" height="30" fill="#A0BDFC" />
<rect x="170" y="180" width="10" height="60" fill="#DFF2FE" /> <rect x="170" y="180" width="10" height="60" fill="#DFF2FE" />
<rect x="200" y="180" width="10" height="60" fill="#DFF2FE" /> <rect x="200" y="180" width="10" height="60" fill="#DFF2FE" />
<rect x="240" y="180" width="30" height="30" fill="#A0BDFC" /> <rect x="240" y="180" width="30" height="30" fill="#A0BDFC" />
<rect x="270" y="180" width="10" height="10" fill="#1E2545" /> <rect x="270" y="180" width="10" height="10" fill="#1E2545" />
<rect x="290" y="180" width="10" height="10" fill="#1E2545" /> <rect x="290" y="180" width="10" height="10" fill="#1E2545" />
<rect x="300" y="180" width="20" height="10" fill="#A0BDFC" /> <rect x="300" y="180" width="20" height="10" fill="#A0BDFC" />
<rect x="320" y="180" width="10" height="10" fill="#FAFEFF" /> <rect x="320" y="180" width="10" height="10" fill="#FAFEFF" />
<rect x="330" y="180" width="10" height="10" fill="#A0BDFC" /> <rect x="330" y="180" width="10" height="10" fill="#A0BDFC" />
<rect x="350" y="180" width="10" height="10" fill="#1E2545" /> <rect x="350" y="180" width="10" height="10" fill="#1E2545" />
<rect x="30" y="190" width="10" height="10" fill="#1E2545" /> <rect x="30" y="190" width="10" height="10" fill="#1E2545" />
<rect x="40" y="190" width="10" height="10" fill="#5E76AB" /> <rect x="40" y="190" width="10" height="10" fill="#5E76AB" />
<rect x="50" y="190" width="20" height="10" fill="#A0BDFC" /> <rect x="50" y="190" width="20" height="10" fill="#A0BDFC" />
<rect x="70" y="190" width="10" height="10" fill="#1E2545" /> <rect x="70" y="190" width="10" height="10" fill="#1E2545" />
<rect x="90" y="190" width="10" height="20" fill="#1E2545" /> <rect x="90" y="190" width="10" height="20" fill="#1E2545" />
<rect x="100" y="190" width="10" height="10" fill="#5E76AB" /> <rect x="100" y="190" width="10" height="10" fill="#5E76AB" />
<rect x="150" y="190" width="10" height="10" fill="#A0BDFC" /> <rect x="150" y="190" width="10" height="10" fill="#A0BDFC" />
<rect x="160" y="190" width="10" height="10" fill="#C0D4FF" /> <rect x="160" y="190" width="10" height="10" fill="#C0D4FF" />
<rect x="210" y="190" width="10" height="10" fill="#C0D4FF" /> <rect x="210" y="190" width="10" height="10" fill="#C0D4FF" />
<rect x="220" y="190" width="10" height="10" fill="#A0BDFC" /> <rect x="220" y="190" width="10" height="10" fill="#A0BDFC" />
<rect x="270" y="190" width="10" height="10" fill="#5E76AB" /> <rect x="270" y="190" width="10" height="10" fill="#5E76AB" />
<rect x="280" y="190" width="10" height="20" fill="#1E2545" /> <rect x="280" y="190" width="10" height="20" fill="#1E2545" />
<rect x="300" y="190" width="10" height="10" fill="#1E2545" /> <rect x="300" y="190" width="10" height="10" fill="#1E2545" />
<rect x="310" y="190" width="20" height="10" fill="#A0BDFC" /> <rect x="310" y="190" width="20" height="10" fill="#A0BDFC" />
<rect x="330" y="190" width="10" height="10" fill="#5E76AB" /> <rect x="330" y="190" width="10" height="10" fill="#5E76AB" />
<rect x="340" y="190" width="10" height="10" fill="#1E2545" /> <rect x="340" y="190" width="10" height="10" fill="#1E2545" />
<rect x="40" y="200" width="30" height="10" fill="#1E2545" /> <rect x="40" y="200" width="30" height="10" fill="#1E2545" />
<rect x="100" y="200" width="10" height="60" fill="#A0BDFC" /> <rect x="100" y="200" width="10" height="60" fill="#A0BDFC" />
<rect x="150" y="200" width="10" height="10" fill="#C0D4FF" /> <rect x="150" y="200" width="10" height="10" fill="#C0D4FF" />
<rect x="160" y="200" width="10" height="120" fill="#DFF2FE" /> <rect x="160" y="200" width="10" height="120" fill="#DFF2FE" />
<rect x="210" y="200" width="10" height="120" fill="#DFF2FE" /> <rect x="210" y="200" width="10" height="120" fill="#DFF2FE" />
<rect x="220" y="200" width="10" height="10" fill="#C0D4FF" /> <rect x="220" y="200" width="10" height="10" fill="#C0D4FF" />
<rect x="270" y="200" width="10" height="60" fill="#A0BDFC" /> <rect x="270" y="200" width="10" height="60" fill="#A0BDFC" />
<rect x="310" y="200" width="30" height="10" fill="#1E2545" /> <rect x="310" y="200" width="30" height="10" fill="#1E2545" />
<rect x="80" y="210" width="10" height="20" fill="#1E2545" /> <rect x="80" y="210" width="10" height="20" fill="#1E2545" />
<rect x="90" y="210" width="10" height="10" fill="#5E76AB" /> <rect x="90" y="210" width="10" height="10" fill="#5E76AB" />
<rect x="110" y="210" width="20" height="30" fill="#A0BDFC" /> <rect x="110" y="210" width="20" height="30" fill="#A0BDFC" />
<rect x="130" y="210" width="20" height="10" fill="#333C64" /> <rect x="130" y="210" width="20" height="10" fill="#333C64" />
<rect x="150" y="210" width="10" height="110" fill="#DFF2FE" /> <rect x="150" y="210" width="10" height="110" fill="#DFF2FE" />
<rect x="220" y="210" width="10" height="110" fill="#DFF2FE" /> <rect x="220" y="210" width="10" height="110" fill="#DFF2FE" />
<rect x="230" y="210" width="20" height="10" fill="#333C64" /> <rect x="230" y="210" width="20" height="10" fill="#333C64" />
<rect x="250" y="210" width="20" height="30" fill="#A0BDFC" /> <rect x="250" y="210" width="20" height="30" fill="#A0BDFC" />
<rect x="280" y="210" width="10" height="10" fill="#5E76AB" /> <rect x="280" y="210" width="10" height="10" fill="#5E76AB" />
<rect x="290" y="210" width="10" height="20" fill="#1E2545" /> <rect x="290" y="210" width="10" height="20" fill="#1E2545" />
<rect x="90" y="220" width="10" height="50" fill="#A0BDFC" /> <rect x="90" y="220" width="10" height="50" fill="#A0BDFC" />
<rect x="130" y="220" width="20" height="30" fill="#1E2545" /> <rect x="130" y="220" width="20" height="30" fill="#1E2545" />
<rect x="230" y="220" width="20" height="30" fill="#1E2545" /> <rect x="230" y="220" width="20" height="30" fill="#1E2545" />
<rect x="280" y="220" width="10" height="50" fill="#A0BDFC" /> <rect x="280" y="220" width="10" height="50" fill="#A0BDFC" />
<rect x="70" y="230" width="10" height="20" fill="#1E2545" /> <rect x="70" y="230" width="10" height="20" fill="#1E2545" />
<rect x="80" y="230" width="10" height="10" fill="#5E76AB" /> <rect x="80" y="230" width="10" height="10" fill="#5E76AB" />
<rect x="290" y="230" width="10" height="10" fill="#5E76AB" /> <rect x="290" y="230" width="10" height="10" fill="#5E76AB" />
<rect x="300" y="230" width="10" height="20" fill="#1E2545" /> <rect x="300" y="230" width="10" height="20" fill="#1E2545" />
<rect x="80" y="240" width="10" height="80" fill="#A0BDFC" /> <rect x="80" y="240" width="10" height="80" fill="#A0BDFC" />
<rect x="110" y="240" width="10" height="10" fill="#A0BDFC" /> <rect x="110" y="240" width="10" height="10" fill="#A0BDFC" />
<rect x="120" y="240" width="10" height="10" fill="#C0D4FF" /> <rect x="120" y="240" width="10" height="10" fill="#C0D4FF" />
<rect x="170" y="240" width="40" height="10" fill="#FC9797" /> <rect x="170" y="240" width="40" height="10" fill="#FC9797" />
<rect x="250" y="240" width="10" height="10" fill="#C0D4FF" /> <rect x="250" y="240" width="10" height="10" fill="#C0D4FF" />
<rect x="260" y="240" width="10" height="10" fill="#A0BDFC" /> <rect x="260" y="240" width="10" height="10" fill="#A0BDFC" />
<rect x="290" y="240" width="10" height="80" fill="#A0BDFC" /> <rect x="290" y="240" width="10" height="80" fill="#A0BDFC" />
<rect x="60" y="250" width="10" height="20" fill="#1E2545" /> <rect x="60" y="250" width="10" height="20" fill="#1E2545" />
<rect x="70" y="250" width="10" height="10" fill="#5E76AB" /> <rect x="70" y="250" width="10" height="10" fill="#5E76AB" />
<rect x="110" y="250" width="10" height="10" fill="#C0D4FF" /> <rect x="110" y="250" width="10" height="10" fill="#C0D4FF" />
<rect x="120" y="250" width="10" height="70" fill="#DFF2FE" /> <rect x="120" y="250" width="10" height="70" fill="#DFF2FE" />
<rect x="130" y="250" width="20" height="10" fill="#EBF5FF" /> <rect x="130" y="250" width="20" height="10" fill="#EBF5FF" />
<rect x="170" y="250" width="10" height="30" fill="#DFF2FE" /> <rect x="170" y="250" width="10" height="30" fill="#DFF2FE" />
<rect x="180" y="250" width="20" height="10" fill="#FC9797" /> <rect x="180" y="250" width="20" height="10" fill="#FC9797" />
<rect x="200" y="250" width="10" height="30" fill="#DFF2FE" /> <rect x="200" y="250" width="10" height="30" fill="#DFF2FE" />
<rect x="230" y="250" width="20" height="10" fill="#EBF5FF" /> <rect x="230" y="250" width="20" height="10" fill="#EBF5FF" />
<rect x="250" y="250" width="10" height="70" fill="#DFF2FE" /> <rect x="250" y="250" width="10" height="70" fill="#DFF2FE" />
<rect x="260" y="250" width="10" height="10" fill="#C0D4FF" /> <rect x="260" y="250" width="10" height="10" fill="#C0D4FF" />
<rect x="300" y="250" width="10" height="10" fill="#5E76AB" /> <rect x="300" y="250" width="10" height="10" fill="#5E76AB" />
<rect x="310" y="250" width="10" height="20" fill="#1E2545" /> <rect x="310" y="250" width="10" height="20" fill="#1E2545" />
<rect x="70" y="260" width="10" height="60" fill="#A0BDFC" /> <rect x="70" y="260" width="10" height="60" fill="#A0BDFC" />
<rect x="100" y="260" width="10" height="10" fill="#C0D4FF" /> <rect x="100" y="260" width="10" height="10" fill="#C0D4FF" />
<rect x="110" y="260" width="10" height="60" fill="#DFF2FE" /> <rect x="110" y="260" width="10" height="60" fill="#DFF2FE" />
<rect x="130" y="260" width="20" height="60" fill="#DFF2FE" /> <rect x="130" y="260" width="20" height="60" fill="#DFF2FE" />
<rect x="180" y="260" width="20" height="10" fill="#DFF2FE" /> <rect x="180" y="260" width="20" height="10" fill="#DFF2FE" />
<rect x="230" y="260" width="20" height="60" fill="#DFF2FE" /> <rect x="230" y="260" width="20" height="60" fill="#DFF2FE" />
<rect x="260" y="260" width="10" height="60" fill="#DFF2FE" /> <rect x="260" y="260" width="10" height="60" fill="#DFF2FE" />
<rect x="270" y="260" width="10" height="10" fill="#C0D4FF" /> <rect x="270" y="260" width="10" height="10" fill="#C0D4FF" />
<rect x="300" y="260" width="10" height="60" fill="#A0BDFC" /> <rect x="300" y="260" width="10" height="60" fill="#A0BDFC" />
<rect x="50" y="270" width="10" height="40" fill="#1E2545" /> <rect x="50" y="270" width="10" height="40" fill="#1E2545" />
<rect x="60" y="270" width="10" height="10" fill="#5E76AB" /> <rect x="60" y="270" width="10" height="10" fill="#5E76AB" />
<rect x="90" y="270" width="10" height="10" fill="#C0D4FF" /> <rect x="90" y="270" width="10" height="10" fill="#C0D4FF" />
<rect x="100" y="270" width="10" height="50" fill="#DFF2FE" /> <rect x="100" y="270" width="10" height="50" fill="#DFF2FE" />
<rect x="180" y="270" width="20" height="10" fill="#9EAEBA" /> <rect x="180" y="270" width="20" height="10" fill="#9EAEBA" />
<rect x="270" y="270" width="10" height="50" fill="#DFF2FE" /> <rect x="270" y="270" width="10" height="50" fill="#DFF2FE" />
<rect x="280" y="270" width="10" height="10" fill="#C0D4FF" /> <rect x="280" y="270" width="10" height="10" fill="#C0D4FF" />
<rect x="310" y="270" width="10" height="10" fill="#5E76AB" /> <rect x="310" y="270" width="10" height="10" fill="#5E76AB" />
<rect x="320" y="270" width="10" height="40" fill="#1E2545" /> <rect x="320" y="270" width="10" height="40" fill="#1E2545" />
<rect x="60" y="280" width="10" height="20" fill="#A0BDFC" /> <rect x="60" y="280" width="10" height="20" fill="#A0BDFC" />
<rect x="90" y="280" width="10" height="30" fill="#DFF2FE" /> <rect x="90" y="280" width="10" height="30" fill="#DFF2FE" />
<rect x="170" y="280" width="10" height="10" fill="#B8CAD9" /> <rect x="170" y="280" width="10" height="10" fill="#B8CAD9" />
<rect x="180" y="280" width="20" height="40" fill="#DFF2FE" /> <rect x="180" y="280" width="20" height="40" fill="#DFF2FE" />
<rect x="200" y="280" width="10" height="10" fill="#B8CAD9" /> <rect x="200" y="280" width="10" height="10" fill="#B8CAD9" />
<rect x="280" y="280" width="10" height="30" fill="#DFF2FE" /> <rect x="280" y="280" width="10" height="30" fill="#DFF2FE" />
<rect x="310" y="280" width="10" height="20" fill="#A0BDFC" /> <rect x="310" y="280" width="10" height="20" fill="#A0BDFC" />
<rect x="170" y="290" width="10" height="30" fill="#DFF2FE" /> <rect x="170" y="290" width="10" height="30" fill="#DFF2FE" />
<rect x="200" y="290" width="10" height="30" fill="#DFF2FE" /> <rect x="200" y="290" width="10" height="30" fill="#DFF2FE" />
<rect x="60" y="300" width="10" height="10" fill="#5E76AB" /> <rect x="60" y="300" width="10" height="10" fill="#5E76AB" />
<rect x="310" y="300" width="10" height="10" fill="#5E76AB" /> <rect x="310" y="300" width="10" height="10" fill="#5E76AB" />
<rect x="60" y="310" width="10" height="10" fill="#1E2545" /> <rect x="60" y="310" width="10" height="10" fill="#1E2545" />
<rect x="90" y="310" width="10" height="10" fill="#C0D4FF" /> <rect x="90" y="310" width="10" height="10" fill="#C0D4FF" />
<rect x="280" y="310" width="10" height="10" fill="#C0D4FF" /> <rect x="280" y="310" width="10" height="10" fill="#C0D4FF" />
<rect x="310" y="310" width="10" height="10" fill="#1E2545" /> <rect x="310" y="310" width="10" height="10" fill="#1E2545" />
<rect x="70" y="320" width="240" height="10" fill="#1E2545" /> <rect x="70" y="320" width="240" height="10" fill="#1E2545" />
</svg> </svg>

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 15 KiB

Before After
Before After

View file

@ -8,7 +8,7 @@ import { createDefine } from "fresh";
// This specifies the type of "ctx.state" which is used to share // This specifies the type of "ctx.state" which is used to share
// data among middlewares, layouts and routes. // data among middlewares, layouts and routes.
export interface State { export interface State {
shared: string; shared: string;
} }
export const define = createDefine<State>(); export const define = createDefine<State>();

View file

@ -7,5 +7,5 @@ import { defineConfig } from "vite";
import { fresh } from "@fresh/plugin-vite"; import { fresh } from "@fresh/plugin-vite";
export default defineConfig({ export default defineConfig({
plugins: [fresh()], plugins: [fresh()],
}); });