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

View file

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

View file

@ -7,23 +7,25 @@ import { HeartFilledIcon } from "./Icon.tsx";
import Link from "./Link.tsx";
export default function Footer() {
return (
<footer class="section">
<p class="alt alt-font">
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">
GNU Affero General Public License v3.0
</Link>
, with all site content licensed under{" "}
<Link href="https://creativecommons.org/licenses/by-sa/4.0/">
CC BY-SA 4.0
</Link>
.
</p>
<p class="alt alt-font">
© 2025 muxiepuff Powered by FreeBSD and pixels
</p>
</footer>
);
return (
<footer class="section">
<p class="alt alt-font">
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">
GNU Affero General Public License v3.0
</Link>
, with all site content licensed under{" "}
<Link href="https://creativecommons.org/licenses/by-sa/4.0/">
CC BY-SA 4.0
</Link>
.
</p>
<p class="alt alt-font">
© 2025 muxiepuff Powered by FreeBSD and pixels
</p>
</footer>
);
}

View file

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

View file

@ -4,439 +4,455 @@
*/
interface IconProps {
size?: number;
[key: string]: any;
size?: number;
[key: string]: any;
}
export function LinkIcon({ size = 24, ...props }: IconProps) {
return (
<svg
fill="none"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
width={size}
height={size}
{...props}
>
<path
d="M21 11V3h-8v2h4v2h-2v2h-2v2h-2v2H9v2h2v-2h2v-2h2V9h2V7h2v4h2zM11 5H3v16h16v-8h-2v6H5V7h6V5z"
fill="currentColor"
/>
</svg>
);
return (
<svg
fill="none"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
width={size}
height={size}
{...props}
>
<path
d="M21 11V3h-8v2h4v2h-2v2h-2v2h-2v2H9v2h2v-2h2v-2h2V9h2V7h2v4h2zM11 5H3v16h16v-8h-2v6H5V7h6V5z"
fill="currentColor"
/>
</svg>
);
}
export function PersonIcon({ size = 24, ...props }: IconProps) {
return (
<svg
fill="none"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
width={size}
height={size}
{...props}
>
<path
d="M10 2h4v4h-4V2zM7 7h10v2h-2v13h-2v-6h-2v6H9V9H7V7zM5 5v2h2V5H5zm0 0H3V3h2v2zm14 0v2h-2V5h2zm0 0V3h2v2h-2z"
fill="currentColor"
/>
</svg>
);
return (
<svg
fill="none"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
width={size}
height={size}
{...props}
>
<path
d="M10 2h4v4h-4V2zM7 7h10v2h-2v13h-2v-6h-2v6H9V9H7V7zM5 5v2h2V5H5zm0 0H3V3h2v2zm14 0v2h-2V5h2zm0 0V3h2v2h-2z"
fill="currentColor"
/>
</svg>
);
}
export function HeartIcon({ size = 24, ...props }: IconProps) {
return (
<svg
fill="none"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
width={size}
height={size}
{...props}
>
<path
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"
/>
</svg>
);
return (
<svg
fill="none"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
width={size}
height={size}
{...props}
>
<path
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"
/>
</svg>
);
}
export function CommentIcon({ size = 24, ...props }: IconProps) {
return (
<svg
fill="none"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
width={size}
height={size}
{...props}
>
<path
d="M22 2H2v14h2V4h16v12h-8v2h-2v2H8v-4H2v2h4v4h4v-2h2v-2h10V2z"
fill="currentColor"
/>
</svg>
);
return (
<svg
fill="none"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
width={size}
height={size}
{...props}
>
<path
d="M22 2H2v14h2V4h16v12h-8v2h-2v2H8v-4H2v2h4v4h4v-2h2v-2h10V2z"
fill="currentColor"
/>
</svg>
);
}
export function AttachmentIcon({ size = 24, ...props }: IconProps) {
return (
<svg
fill="none"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
width={size}
height={size}
{...props}
>
<path
d="M7 5v14H5V3h14v18H9V7h6v10h-2V9h-2v10h6V5H7z"
fill="currentColor"
/>
</svg>
);
return (
<svg
fill="none"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
width={size}
height={size}
{...props}
>
<path
d="M7 5v14H5V3h14v18H9V7h6v10h-2V9h-2v10h6V5H7z"
fill="currentColor"
/>
</svg>
);
}
export function LabelIcon({ size = 24, ...props }: IconProps) {
return (
<svg
fill="none"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
width={size}
height={size}
{...props}
>
<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"
fill="currentColor"
/>
</svg>
);
return (
<svg
fill="none"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
width={size}
height={size}
{...props}
>
<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"
fill="currentColor"
/>
</svg>
);
}
export function DiscordIcon({ size = 24, ...props }: IconProps) {
return (
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
width={size}
height={size}
{...props}
>
<title>Discord</title>
<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"
fill="currentColor"
/>
</svg>
);
return (
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
width={size}
height={size}
{...props}
>
<title>Discord</title>
<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"
fill="currentColor"
/>
</svg>
);
}
export function SignalIcon({ size = 24, ...props }: IconProps) {
return (
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
width={size}
height={size}
{...props}
>
<title>Signal</title>
<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"
fill="currentColor"
/>
</svg>
);
return (
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
width={size}
height={size}
{...props}
>
<title>Signal</title>
<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"
fill="currentColor"
/>
</svg>
);
}
export function LastfmIcon({ size = 24, ...props }: IconProps) {
return (
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
width={size}
height={size}
{...props}
>
<title>Last.fm</title>
<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"
fill="currentColor"
/>
</svg>
);
return (
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
width={size}
height={size}
{...props}
>
<title>Last.fm</title>
<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"
fill="currentColor"
/>
</svg>
);
}
export function BlueskyIcon({ size = 24, ...props }: IconProps) {
return (
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
width={size}
height={size}
{...props}
>
<title>Bluesky</title>
<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"
fill="currentColor"
/>
</svg>
);
return (
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
width={size}
height={size}
{...props}
>
<title>Bluesky</title>
<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"
fill="currentColor"
/>
</svg>
);
}
export function MastodonIcon({ size = 24, ...props }: IconProps) {
return (
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
width={size}
height={size}
{...props}
>
<title>Mastodon / Fediverse</title>
<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"
fill="currentColor"
/>
</svg>
);
return (
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
width={size}
height={size}
{...props}
>
<title>Mastodon / Fediverse</title>
<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"
fill="currentColor"
/>
</svg>
);
}
export function ForgejoIcon({ size = 24, ...props }: IconProps) {
return (
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
width={size}
height={size}
{...props}
>
<title>Forgejo</title>
<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"
fill="currentColor"
/>
</svg>
);
return (
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
width={size}
height={size}
{...props}
>
<title>Forgejo</title>
<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"
fill="currentColor"
/>
</svg>
);
}
export function CodebergIcon({ size = 24, ...props }: IconProps) {
return (
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
width={size}
height={size}
{...props}
>
<title>Codeberg</title>
<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"
fill="currentColor"
/>
</svg>
);
return (
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
width={size}
height={size}
{...props}
>
<title>Codeberg</title>
<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"
fill="currentColor"
/>
</svg>
);
}
export function GitHubIcon({ size = 24, ...props }: IconProps) {
return (
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
width={size}
height={size}
{...props}
>
<title>GitHub</title>
<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"
fill="currentColor"
/>
</svg>
);
return (
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
width={size}
height={size}
{...props}
>
<title>GitHub</title>
<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"
fill="currentColor"
/>
</svg>
);
}
export function MailIcon({ size = 24, ...props }: IconProps) {
return (
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 20 20"
width={size}
height={size}
{...props}
>
<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"
fill="currentColor"
/>
<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"
fill="currentColor"
/>
</svg>
);
return (
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 20 20"
width={size}
height={size}
{...props}
>
<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"
fill="currentColor"
/>
<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"
fill="currentColor"
/>
</svg>
);
}
export function TwitterIcon({ size = 24, ...props }: IconProps) {
return (
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
width={size}
height={size}
{...props}
>
<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"
fill="currentColor"
/>
</svg>
);
return (
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
width={size}
height={size}
{...props}
>
<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"
fill="currentColor"
/>
</svg>
);
}
export function KofiIcon({ size = 24, ...props }: IconProps) {
return (
<svg
role="img"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
width={size}
height={size}
{...props}
>
<title>Ko-fi</title>
<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"
fill="currentColor"
/>
</svg>
);
return (
<svg
role="img"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
width={size}
height={size}
{...props}
>
<title>Ko-fi</title>
<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"
fill="currentColor"
/>
</svg>
);
}
export function BitcoinIcon({ size = 24, ...props }: IconProps) {
return (
<svg
role="img"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
width={size}
height={size}
{...props}
>
<title>Bitcoin</title>
<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"
fill="currentColor"
/>
</svg>
);
return (
<svg
role="img"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
width={size}
height={size}
{...props}
>
<title>Bitcoin</title>
<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"
fill="currentColor"
/>
</svg>
);
}
export function BitcoinCashIcon({ size = 24, ...props }: IconProps) {
return (
<svg
role="img"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
width={size}
height={size}
{...props}
>
<title>Bitcoin Cash</title>
<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"
fill="currentColor"
/>
</svg>
);
return (
<svg
role="img"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
width={size}
height={size}
{...props}
>
<title>Bitcoin Cash</title>
<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"
fill="currentColor"
/>
</svg>
);
}
export function MoneroIcon({ size = 24, ...props }: IconProps) {
return (
<svg
role="img"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
width={size}
height={size}
{...props}
>
<title>Monero</title>
<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"
fill="currentColor"
/>
</svg>
);
return (
<svg
role="img"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
width={size}
height={size}
{...props}
>
<title>Monero</title>
<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"
fill="currentColor"
/>
</svg>
);
}
export function NanoIcon({ size = 24, ...props }: IconProps) {
return (
<svg
role="img"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
width={size}
height={size}
{...props}
>
<title>Nano</title>
<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"
fill="currentColor"
/>
</svg>
);
return (
<svg
role="img"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
width={size}
height={size}
{...props}
>
<title>Nano</title>
<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"
fill="currentColor"
/>
</svg>
);
}
export function LitecoinIcon({ size = 24, ...props }: IconProps) {
return (
<svg
role="img"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
width={size}
height={size}
{...props}
>
<title>Litecoin</title>
<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"
fill="currentColor"
/>
</svg>
);
return (
<svg
role="img"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
width={size}
height={size}
{...props}
>
<title>Litecoin</title>
<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"
fill="currentColor"
/>
</svg>
);
}
export function EthereumIcon({ size = 24, ...props }: IconProps) {
return (
<svg
role="img"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
width={size}
height={size}
{...props}
>
<title>Ethereum</title>
<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"
fill="currentColor"
/>
</svg>
);
return (
<svg
role="img"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
width={size}
height={size}
{...props}
>
<title>Ethereum</title>
<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"
fill="currentColor"
/>
</svg>
);
}
export function HeartFilledIcon({ 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}
>
<path d="M9 2H5v2H3v2H1v6h2v2h2v2h2v2h2v2h2v2h2v-2h2v-2h2v-2h2v-2h2v-2h2V6h-2V4h-2V2h-4v2h-2v2h-2V4H9V2z" />
</svg>
);
return (
<svg
fill="currentColor"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
width={size}
height={size}
{...props}
>
<path d="M9 2H5v2H3v2H1v6h2v2h2v2h2v2h2v2h2v2h2v-2h2v-2h2v-2h2v-2h2v-2h2V6h-2V4h-2V2h-4v2h-2v2h-2V4H9V2z" />
</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";
interface LayoutProps {
children: ComponentChildren;
[key: string]: any;
children: ComponentChildren;
[key: string]: any;
}
export function Section({ children, class: className, ...props }: LayoutProps) {
return (
<div
{...props}
class={`section ${className || ""}`}
>
{children}
</div>
);
return (
<div
{...props}
class={`section ${className || ""}`}
>
{children}
</div>
);
}
export function Centered(
{ children, class: className, ...props }: LayoutProps,
{ children, class: className, ...props }: LayoutProps,
) {
return (
<div class={`centered ${className || ""}`} {...props}>
{children}
</div>
);
return (
<main class={`centered ${className || ""}`} {...props}>
{children}
</main>
);
}

View file

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

View file

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

View file

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

120
deno.json
View file

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

View file

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

View file

@ -4,16 +4,20 @@
*/
export default function Meow() {
return (
<button
type="button"
id="muxiepuff"
onClick={() =>
navigator.clipboard.writeText(
'<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" />
</button>
);
return (
<button
type="button"
id="muxiepuff"
onClick={() =>
navigator.clipboard.writeText(
'<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"
/>
</button>
);
}

View file

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

View file

@ -6,41 +6,41 @@
import { useEffect, useRef } from "preact/hooks";
interface Particle {
offsetX: number;
offsetY: number;
velocityX: number;
velocityY: number;
offsetX: number;
offsetY: number;
velocityX: number;
velocityY: number;
}
interface Raindrop {
x: number;
y: number;
length: number;
speed: number;
opacity: number;
floorHeight: number;
x: number;
y: number;
length: number;
speed: number;
opacity: number;
floorHeight: number;
}
interface Splash {
x: number;
y: number;
age: number;
maxAge: number;
particles: Particle[];
x: number;
y: number;
age: number;
maxAge: number;
particles: Particle[];
}
interface Star {
x: number;
y: number;
size: number;
brightness: number;
twinkleSpeed: number;
twinkleOffset: number;
age: number;
maxAge: number;
canVanish: boolean;
color: { r: number; g: number; b: number };
colorIndex: number;
x: number;
y: number;
size: number;
brightness: number;
twinkleSpeed: number;
twinkleOffset: number;
age: number;
maxAge: number;
canVanish: boolean;
color: { r: number; g: number; b: number };
colorIndex: number;
}
const PIXEL_SIZE = 4;
@ -82,293 +82,299 @@ const ALPHA_STAR_COLORS: string[] = [];
const NUM_COLOR_VARIATIONS = 20;
for (let i = 0; i < NUM_COLOR_VARIATIONS; i++) {
const brightness = 1 - (i / NUM_COLOR_VARIATIONS) * 0.5;
RAIN_COLORS.push(
`rgb(${Math.floor(RAIN_COLOR.r * brightness)},${
Math.floor(RAIN_COLOR.g * brightness)
},${Math.floor(RAIN_COLOR.b * brightness)})`,
);
const brightness = 1 - (i / NUM_COLOR_VARIATIONS) * 0.5;
RAIN_COLORS.push(
`rgb(${Math.floor(RAIN_COLOR.r * brightness)},${
Math.floor(
RAIN_COLOR.g * brightness,
)
},${Math.floor(RAIN_COLOR.b * brightness)})`,
);
}
for (let i = 0; i < NUM_COLOR_VARIATIONS; i++) {
const brightness = STAR_BRIGHTNESS_MIN +
(i / NUM_COLOR_VARIATIONS) * STAR_BRIGHTNESS_RANGE;
STAR_COLORS.push(
`rgb(${Math.floor(RAIN_COLOR.r * brightness)},${
Math.floor(RAIN_COLOR.g * brightness)
},${Math.floor(RAIN_COLOR.b * brightness)})`,
);
ALPHA_STAR_COLORS.push(
`rgba(${Math.floor(RAIN_COLOR.r * brightness)},${
Math.floor(RAIN_COLOR.g * brightness)
},${Math.floor(RAIN_COLOR.b * brightness)},`,
);
const brightness = STAR_BRIGHTNESS_MIN +
(i / NUM_COLOR_VARIATIONS) * STAR_BRIGHTNESS_RANGE;
STAR_COLORS.push(
`rgb(${Math.floor(RAIN_COLOR.r * brightness)},${
Math.floor(
RAIN_COLOR.g * brightness,
)
},${Math.floor(RAIN_COLOR.b * brightness)})`,
);
ALPHA_STAR_COLORS.push(
`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},${
RAIN_COLOR.g * 0.95
RAIN_COLOR.g * 0.95
},${RAIN_COLOR.b * 1.1})`;
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 {
return {
offsetX: (Math.random() - 0.5) * PARTICLE_OFFSET_RANGE,
offsetY: -(Math.random() * PARTICLE_Y_RANGE + PARTICLE_Y_MIN),
velocityX: (Math.random() - 0.5) * PARTICLE_VX_RANGE,
velocityY: -(Math.random() * PARTICLE_VY_RANGE + PARTICLE_VY_MIN),
};
return {
offsetX: (Math.random() - 0.5) * PARTICLE_OFFSET_RANGE,
offsetY: -(Math.random() * PARTICLE_Y_RANGE + PARTICLE_Y_MIN),
velocityX: (Math.random() - 0.5) * PARTICLE_VX_RANGE,
velocityY: -(Math.random() * PARTICLE_VY_RANGE + PARTICLE_VY_MIN),
};
}
function createSplash(x: number, y: number): Splash {
return {
x,
y,
age: 0,
maxAge: 12,
particles: Array.from(
{ length: Math.floor(Math.random() * 3) + 3 },
createParticle,
),
};
return {
x,
y,
age: 0,
maxAge: 12,
particles: Array.from(
{ length: Math.floor(Math.random() * 3) + 3 },
createParticle,
),
};
}
function createRaindrop(gridWidth: number, gridHeight: number): Raindrop {
const bias = Math.random() * Math.random();
return {
x: Math.floor(Math.random() * gridWidth),
y: Math.floor(Math.random() * gridHeight) - gridHeight,
length: Math.floor(Math.random() * 4) + 2,
speed: RAIN_SPEED * (Math.random() * 2 + 1),
opacity: Math.random() * 0.3 + 0.6,
floorHeight: window.innerHeight *
(FLOOR_HEIGHT_MIN + bias * FLOOR_HEIGHT_RANGE),
};
const bias = Math.random() * Math.random();
return {
x: Math.floor(Math.random() * gridWidth),
y: Math.floor(Math.random() * gridHeight) - gridHeight,
length: Math.floor(Math.random() * 4) + 2,
speed: RAIN_SPEED * (Math.random() * 2 + 1),
opacity: Math.random() * 0.3 + 0.6,
floorHeight: window.innerHeight *
(FLOOR_HEIGHT_MIN + bias * FLOOR_HEIGHT_RANGE),
};
}
function createStar(): Star {
const brightness = Math.random() * STAR_BRIGHTNESS_RANGE +
STAR_BRIGHTNESS_MIN;
const colorIndex = Math.floor(
(brightness - STAR_BRIGHTNESS_MIN) / STAR_BRIGHTNESS_RANGE *
(NUM_COLOR_VARIATIONS - 1),
);
const brightness = Math.random() * STAR_BRIGHTNESS_RANGE +
STAR_BRIGHTNESS_MIN;
const colorIndex = Math.floor(
((brightness - STAR_BRIGHTNESS_MIN) / STAR_BRIGHTNESS_RANGE) *
(NUM_COLOR_VARIATIONS - 1),
);
return {
x: Math.random() * window.innerWidth,
y: Math.random() * window.innerHeight,
size: Math.random() > STAR_LARGE_THRESHOLD
? STAR_SIZE_LARGE
: STAR_SIZE_SMALL,
twinkleSpeed: Math.random() * STAR_TWINKLE_RANGE + STAR_TWINKLE_MIN,
twinkleOffset: Math.random() * Math.PI * 2,
brightness,
age: 0,
maxAge: STAR_AGE_MIN + Math.random() * STAR_AGE_RANGE,
canVanish: false,
colorIndex,
};
return {
x: Math.random() * window.innerWidth,
y: Math.random() * window.innerHeight,
size: Math.random() > STAR_LARGE_THRESHOLD
? STAR_SIZE_LARGE
: STAR_SIZE_SMALL,
twinkleSpeed: Math.random() * STAR_TWINKLE_RANGE + STAR_TWINKLE_MIN,
twinkleOffset: Math.random() * Math.PI * 2,
brightness,
age: 0,
maxAge: STAR_AGE_MIN + Math.random() * STAR_AGE_RANGE,
canVanish: false,
colorIndex,
};
}
function updateParticle(p: Particle) {
p.offsetX += p.velocityX;
p.offsetY += p.velocityY;
p.velocityY += PARTICLE_GRAVITY;
p.offsetX += p.velocityX;
p.offsetY += p.velocityY;
p.velocityY += PARTICLE_GRAVITY;
}
function updateSplash(splash: Splash) {
splash.age++;
splash.particles.forEach(updateParticle);
splash.age++;
splash.particles.forEach(updateParticle);
}
function updateRaindrop(
drop: Raindrop,
splashes: Splash[],
gridWidth: number,
gridHeight: number,
drop: Raindrop,
splashes: Splash[],
gridWidth: number,
gridHeight: number,
) {
drop.y += drop.speed;
const dropY = drop.y * PIXEL_SIZE;
drop.y += drop.speed;
const dropY = drop.y * PIXEL_SIZE;
if (dropY >= drop.floorHeight && Math.random() < SPLASH_CHANCE) {
splashes.push(createSplash(drop.x, Math.floor(dropY / PIXEL_SIZE)));
Object.assign(drop, createRaindrop(gridWidth, gridHeight));
} else if (dropY > window.innerHeight) {
Object.assign(drop, createRaindrop(gridWidth, gridHeight));
}
if (dropY >= drop.floorHeight && Math.random() < SPLASH_CHANCE) {
splashes.push(createSplash(drop.x, Math.floor(dropY / PIXEL_SIZE)));
Object.assign(drop, createRaindrop(gridWidth, gridHeight));
} else if (dropY > window.innerHeight) {
Object.assign(drop, createRaindrop(gridWidth, gridHeight));
}
}
function updateStar(star: Star): void {
star.age++;
const phase = (star.age * star.twinkleSpeed + star.twinkleOffset) %
(2 * Math.PI);
star.age++;
const phase = (star.age * star.twinkleSpeed + star.twinkleOffset) %
(2 * Math.PI);
if (!star.canVanish && phase < star.twinkleSpeed) {
star.canVanish = true;
}
if (!star.canVanish && phase < star.twinkleSpeed) {
star.canVanish = true;
}
if (star.canVanish && star.age > star.maxAge) {
Object.assign(star, createStar());
} else if (star.x > window.innerWidth || star.y > window.innerHeight) {
Object.assign(star, createStar());
}
if (star.canVanish && star.age > star.maxAge) {
Object.assign(star, createStar());
} else if (star.x > window.innerWidth || star.y > window.innerHeight) {
Object.assign(star, createStar());
}
}
const isSplashDead = (splash: Splash): boolean => splash.age >= splash.maxAge;
const drawRaindrop = (ctx: CanvasRenderingContext2D, drop: Raindrop): void => {
ctx.globalAlpha = drop.opacity;
const xPos = drop.x * PIXEL_SIZE;
ctx.globalAlpha = drop.opacity;
const xPos = drop.x * PIXEL_SIZE;
for (let i = 0; i < drop.length; i++) {
const colorIndex = Math.floor(
(i / drop.length) * NUM_COLOR_VARIATIONS * 0.5,
);
ctx.fillStyle = RAIN_COLORS[colorIndex];
ctx.fillRect(xPos, (drop.y - i) * PIXEL_SIZE, PIXEL_SIZE, PIXEL_SIZE);
}
ctx.globalAlpha = 1;
for (let i = 0; i < drop.length; i++) {
const colorIndex = Math.floor(
(i / drop.length) * NUM_COLOR_VARIATIONS * 0.5,
);
ctx.fillStyle = RAIN_COLORS[colorIndex];
ctx.fillRect(xPos, (drop.y - i) * PIXEL_SIZE, PIXEL_SIZE, PIXEL_SIZE);
}
ctx.globalAlpha = 1;
};
function drawSplash(ctx: CanvasRenderingContext2D, splash: Splash) {
if (splash.age >= splash.maxAge) return;
if (splash.age >= splash.maxAge) return;
const progress = splash.age / splash.maxAge;
ctx.globalAlpha = 1 - progress;
const progress = splash.age / splash.maxAge;
ctx.globalAlpha = 1 - progress;
ctx.fillStyle = SPLASH_PARTICLE_COLOR;
splash.particles.forEach((p) => {
const px = Math.floor(splash.x + p.offsetX) * PIXEL_SIZE;
const py = Math.floor(splash.y + p.offsetY) * PIXEL_SIZE;
ctx.fillRect(px, py, PIXEL_SIZE, PIXEL_SIZE);
});
ctx.fillStyle = SPLASH_PARTICLE_COLOR;
splash.particles.forEach((p) => {
const px = Math.floor(splash.x + p.offsetX) * PIXEL_SIZE;
const py = Math.floor(splash.y + p.offsetY) * PIXEL_SIZE;
ctx.fillRect(px, py, PIXEL_SIZE, PIXEL_SIZE);
});
if (splash.age < 6) {
const rippleSize = Math.floor(splash.age / 2) + 1;
const splashY = splash.y * PIXEL_SIZE;
ctx.fillStyle = SPLASH_RIPPLE_COLOR;
ctx.fillRect(
(splash.x - rippleSize) * PIXEL_SIZE,
splashY,
PIXEL_SIZE,
PIXEL_SIZE,
);
ctx.fillRect(
(splash.x + rippleSize) * PIXEL_SIZE,
splashY,
PIXEL_SIZE,
PIXEL_SIZE,
);
}
if (splash.age < 6) {
const rippleSize = Math.floor(splash.age / 2) + 1;
const splashY = splash.y * PIXEL_SIZE;
ctx.fillStyle = SPLASH_RIPPLE_COLOR;
ctx.fillRect(
(splash.x - rippleSize) * PIXEL_SIZE,
splashY,
PIXEL_SIZE,
PIXEL_SIZE,
);
ctx.fillRect(
(splash.x + rippleSize) * PIXEL_SIZE,
splashY,
PIXEL_SIZE,
PIXEL_SIZE,
);
}
ctx.globalAlpha = 1;
ctx.globalAlpha = 1;
}
function drawStar(
ctx: CanvasRenderingContext2D,
star: Star,
time: number,
) {
const twinkle = Math.sin(time * star.twinkleSpeed + star.twinkleOffset) *
STAR_TWINKLE_AMPLITUDE + STAR_TWINKLE_BASE;
const alpha = star.brightness * twinkle;
function drawStar(ctx: CanvasRenderingContext2D, star: Star, time: number) {
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 y = Math.floor(star.y);
const color = ALPHA_STAR_COLORS[star.colorIndex];
const x = Math.floor(star.x);
const y = Math.floor(star.y);
const color = ALPHA_STAR_COLORS[star.colorIndex];
ctx.fillStyle = color + alpha;
ctx.fillRect(x, y, star.size, star.size);
ctx.fillStyle = color + alpha;
ctx.fillRect(x, y, star.size, star.size);
if (star.size === STAR_SIZE_LARGE && alpha > STAR_GLOW_THRESHOLD) {
ctx.fillStyle = color + (alpha * STAR_GLOW_ALPHA);
ctx.fillRect(x - 4, 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 + 8, 4, 4);
}
if (star.size === STAR_SIZE_LARGE && alpha > STAR_GLOW_THRESHOLD) {
ctx.fillStyle = color + alpha * STAR_GLOW_ALPHA;
ctx.fillRect(x - 4, 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 + 8, 4, 4);
}
}
export default function Rain() {
const canvasRef = useRef<HTMLCanvasElement>(null);
const canvasRef = useRef<HTMLCanvasElement>(null);
useEffect(() => {
const prefersReducedMotion =
window.matchMedia("(prefers-reduced-motion: reduce)").matches;
if (prefersReducedMotion) return;
useEffect(() => {
const prefersReducedMotion = window.matchMedia(
"(prefers-reduced-motion: reduce)",
).matches;
if (prefersReducedMotion) return;
const canvas = canvasRef.current;
if (!canvas) return;
const canvas = canvasRef.current;
if (!canvas) return;
const ctx = canvas.getContext("2d");
if (!ctx) return;
const ctx = canvas.getContext("2d");
if (!ctx) return;
let gridWidth = 0;
let gridHeight = 0;
let gridWidth = 0;
let gridHeight = 0;
const resizeCanvas = () => {
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
gridWidth = Math.floor(window.innerWidth / PIXEL_SIZE);
gridHeight = Math.floor(window.innerHeight / PIXEL_SIZE);
};
const resizeCanvas = () => {
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
gridWidth = Math.floor(window.innerWidth / PIXEL_SIZE);
gridHeight = Math.floor(window.innerHeight / PIXEL_SIZE);
};
resizeCanvas();
window.addEventListener("resize", resizeCanvas);
resizeCanvas();
window.addEventListener("resize", resizeCanvas);
const stars = Array.from({ length: STAR_COUNT }, createStar);
const raindrops = Array.from(
{ length: DROP_COUNT },
() => createRaindrop(gridWidth, gridHeight),
);
const splashes: Splash[] = [];
const stars = Array.from({ length: STAR_COUNT }, createStar);
const raindrops = Array.from(
{ length: DROP_COUNT },
() => createRaindrop(gridWidth, gridHeight),
);
const splashes: Splash[] = [];
const startTime = performance.now();
const startTime = performance.now();
const animate = (time: number) => {
ctx.fillStyle = BACKGROUND_COLOUR;
ctx.fillRect(0, 0, canvas.width, canvas.height);
const animate = (time: number) => {
ctx.fillStyle = BACKGROUND_COLOUR;
ctx.fillRect(0, 0, canvas.width, canvas.height);
for (let i = 0; i < stars.length; i++) {
updateStar(stars[i]);
drawStar(ctx, stars[i], time - startTime);
}
raindrops.forEach((drop) =>
updateRaindrop(drop, splashes, gridWidth, gridHeight)
);
for (let i = splashes.length - 1; i >= 0; i--) {
updateSplash(splashes[i]);
if (isSplashDead(splashes[i])) {
splashes.splice(i, 1);
}
}
for (let i = 0; i < stars.length; i++) {
updateStar(stars[i]);
drawStar(ctx, stars[i], time - startTime);
}
raindrops.forEach((drop) =>
updateRaindrop(drop, splashes, gridWidth, gridHeight)
);
for (let i = splashes.length - 1; i >= 0; i--) {
updateSplash(splashes[i]);
if (isSplashDead(splashes[i])) {
splashes.splice(i, 1);
}
}
for (let i = 0; i < stars.length; i++) {
updateStar(stars[i]);
drawStar(ctx, stars[i], performance.now() - startTime);
}
raindrops.forEach((drop) => drawRaindrop(ctx, drop));
splashes.forEach((splash) => drawSplash(ctx, splash));
for (let i = 0; i < stars.length; i++) {
updateStar(stars[i]);
drawStar(ctx, stars[i], performance.now() - startTime);
}
raindrops.forEach((drop) => drawRaindrop(ctx, drop));
splashes.forEach((splash) => drawSplash(ctx, splash));
requestAnimationFrame(animate);
};
requestAnimationFrame(animate);
};
animate(0);
}, []);
animate(0);
}, []);
return (
<canvas
ref={canvasRef}
style={{
position: "fixed",
top: 0,
left: 0,
width: "100vw",
height: "100vh",
imageRendering: "pixelated",
background: BACKGROUND_COLOUR,
}}
/>
);
return (
<canvas
ref={canvasRef}
aria-hidden="true"
role="presentation"
style={{
position: "fixed",
top: 0,
left: 0,
width: "100vw",
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";
export default function Time() {
const formatter = new Intl.DateTimeFormat("en-US", {
hour: "numeric",
minute: "numeric",
hour12: true,
timeZone: "America/Sao_Paulo",
});
const formatter = new Intl.DateTimeFormat("en-US", {
hour: "numeric",
minute: "numeric",
hour12: true,
timeZone: "America/Sao_Paulo",
});
const now = new Date();
const time = formatter.format(now);
const [offset, setOffset] = useState("");
const now = new Date();
const time = formatter.format(now);
const [offset, setOffset] = useState("");
useEffect(() => {
const br = new Date(
now.toLocaleString("en-US", {
timeZone: "America/Sao_Paulo",
}),
);
const local = new Date(now.toLocaleString("en-US"));
const diff = br.getTime() - local.getTime();
const ms = Math.abs(diff);
const hours = ~~(ms / 36e5);
const minutes = ~~((ms / 6e4) % 60);
useEffect(() => {
const br = new Date(
now.toLocaleString("en-US", {
timeZone: "America/Sao_Paulo",
}),
);
const local = new Date(now.toLocaleString("en-US"));
const diff = br.getTime() - local.getTime();
const ms = Math.abs(diff);
const hours = ~~(ms / 36e5);
const minutes = ~~((ms / 6e4) % 60);
let output = " · ";
if (hours) output += `You're ${hours} hour${hours > 1 ? "s" : ""} `;
if (hours && minutes) output += "and ";
if (minutes) output += `${minutes} minute${minutes > 1 ? "s" : ""} `;
if (hours || minutes) output += diff > 0 ? "behind" : "ahead";
else output = " · Hey, we're in the same time zone!";
let output = " · ";
if (hours) output += `You're ${hours} hour${hours > 1 ? "s" : ""} `;
if (hours && minutes) output += "and ";
if (minutes) output += `${minutes} minute${minutes > 1 ? "s" : ""} `;
if (hours || minutes) output += diff > 0 ? "behind" : "ahead";
else output = " · Hey, we're in the same time zone!";
setOffset(output);
}, []);
setOffset(output);
}, []);
return (
<Box>
Brasília Time, {time}
{offset}
</Box>
);
return (
<Box>
Brasília Time, {time}
{offset}
</Box>
);
}

View file

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

View file

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

View file

@ -1,243 +1,243 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg
version="1.1"
width="380"
height="380"
xmlns="http://www.w3.org/2000/svg"
shape-rendering="crispEdges"
version="1.1"
width="380"
height="380"
xmlns="http://www.w3.org/2000/svg"
shape-rendering="crispEdges"
>
<rect x="80" 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="80" y="80" width="10" height="10" fill="#5E76AB" />
<rect x="90" y="80" width="10" height="20" fill="#A0BDFC" />
<rect x="100" y="80" width="10" height="10" fill="#5E76AB" />
<rect x="110" 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="280" y="80" width="10" height="20" fill="#A0BDFC" />
<rect x="290" y="80" width="10" height="10" fill="#5E76AB" />
<rect x="300" y="80" width="20" 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="70" 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="130" 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="260" 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="320" y="90" 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="60" y="100" width="40" height="60" fill="#DFF2FE" />
<rect x="100" y="100" width="10" height="10" fill="#FAFEFF" />
<rect x="110" y="100" width="30" height="10" fill="#A0BDFC" />
<rect x="140" 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="270" y="100" width="10" height="10" fill="#FAFEFF" />
<rect x="280" y="100" width="40" height="60" fill="#DFF2FE" />
<rect x="320" y="100" width="10" height="10" fill="#5E76AB" />
<rect x="330" y="100" 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="50" y="110" width="10" height="70" 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="120" y="110" width="10" height="10" fill="#C0D4FF" />
<rect x="130" y="110" width="20" height="10" fill="#A0BDFC" />
<rect x="150" 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="250" y="110" width="10" height="10" fill="#C0D4FF" />
<rect x="260" y="110" width="10" height="10" fill="#FAFEFF" />
<rect x="270" y="110" width="10" height="50" 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="340" y="110" 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="40" y="120" width="10" height="60" 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="140" y="120" width="10" height="10" fill="#A0BDFC" />
<rect x="150" y="120" width="10" height="10" fill="#5E76AB" />
<rect x="160" 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="230" y="120" width="10" height="10" fill="#A0BDFC" />
<rect x="240" y="120" width="10" height="10" fill="#FAFEFF" />
<rect x="250" y="120" width="20" height="50" 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="350" y="120" 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="30" y="130" width="10" height="40" 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="150" y="130" width="20" height="60" fill="#A0BDFC" />
<rect x="170" 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="230" y="130" width="10" height="30" fill="#FAFEFF" />
<rect x="240" y="130" width="10" height="30" 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="360" y="130" width="10" height="10" 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="170" y="140" width="10" height="10" fill="#5E76AB" />
<rect x="180" y="140" width="20" height="10" fill="#1E2545" />
<rect x="200" 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="10" y="150" width="10" height="10" 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="200" y="150" width="10" height="30" 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="60" y="160" width="10" height="10" fill="#DFF2FE" />
<rect x="70" y="160" width="10" height="10" fill="#FAFEFF" />
<rect x="80" y="160" width="10" height="10" fill="#C0D4FF" />
<rect x="90" y="160" width="20" height="10" fill="#A0BDFC" />
<rect x="130" y="160" width="10" height="10" fill="#FAFEFF" />
<rect x="140" y="160" width="10" height="50" 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="240" y="160" width="10" height="10" fill="#FAFEFF" />
<rect x="270" y="160" width="20" height="10" fill="#A0BDFC" />
<rect x="290" y="160" width="10" height="10" fill="#C0D4FF" />
<rect x="300" y="160" width="10" height="10" fill="#FAFEFF" />
<rect x="310" y="160" width="10" height="10" fill="#DFF2FE" />
<rect x="360" y="160" width="10" height="10" fill="#5E76AB" />
<rect x="10" y="170" width="10" height="10" fill="#1E2545" />
<rect x="30" y="170" width="10" height="20" fill="#A0BDFC" />
<rect x="60" y="170" width="10" height="10" fill="#FAFEFF" />
<rect x="70" y="170" width="20" height="10" fill="#A0BDFC" />
<rect x="90" y="170" width="10" height="10" fill="#1E2545" />
<rect x="100" y="170" width="40" height="10" fill="#A0BDFC" />
<rect x="180" y="170" width="20" height="70" fill="#DFF2FE" />
<rect x="240" y="170" width="40" height="10" fill="#A0BDFC" />
<rect x="280" y="170" width="10" height="10" fill="#1E2545" />
<rect x="290" y="170" width="20" height="10" fill="#A0BDFC" />
<rect x="310" y="170" width="10" height="10" fill="#FAFEFF" />
<rect x="340" y="170" width="10" height="20" fill="#A0BDFC" />
<rect x="360" y="170" 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="50" y="180" width="10" height="10" fill="#FAFEFF" />
<rect x="60" y="180" width="20" height="10" fill="#A0BDFC" />
<rect x="80" 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="170" 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="270" 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="320" y="180" width="10" height="10" fill="#FAFEFF" />
<rect x="330" y="180" width="10" height="10" fill="#A0BDFC" />
<rect x="350" y="180" 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="50" y="190" width="20" height="10" fill="#A0BDFC" />
<rect x="70" y="190" width="10" height="10" 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="150" y="190" width="10" height="10" fill="#A0BDFC" />
<rect x="160" 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="270" y="190" width="10" height="10" fill="#5E76AB" />
<rect x="280" y="190" width="10" height="20" 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="330" y="190" width="10" height="10" fill="#5E76AB" />
<rect x="340" y="190" width="10" 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="150" y="200" width="10" height="10" fill="#C0D4FF" />
<rect x="160" 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="270" y="200" width="10" height="60" fill="#A0BDFC" />
<rect x="310" y="200" width="30" height="10" 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="110" y="210" width="20" height="30" fill="#A0BDFC" />
<rect x="130" y="210" width="20" height="10" fill="#333C64" />
<rect x="150" 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="250" y="210" width="20" height="30" fill="#A0BDFC" />
<rect x="280" y="210" width="10" height="10" fill="#5E76AB" />
<rect x="290" y="210" width="10" height="20" fill="#1E2545" />
<rect x="90" y="220" width="10" height="50" fill="#A0BDFC" />
<rect x="130" 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="70" y="230" width="10" height="20" fill="#1E2545" />
<rect x="80" 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="80" y="240" width="10" height="80" 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="170" y="240" width="40" height="10" fill="#FC9797" />
<rect x="250" y="240" width="10" height="10" fill="#C0D4FF" />
<rect x="260" y="240" width="10" height="10" 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="70" y="250" width="10" height="10" fill="#5E76AB" />
<rect x="110" y="250" width="10" height="10" fill="#C0D4FF" />
<rect x="120" y="250" width="10" height="70" fill="#DFF2FE" />
<rect x="130" y="250" width="20" height="10" fill="#EBF5FF" />
<rect x="170" y="250" width="10" height="30" fill="#DFF2FE" />
<rect x="180" y="250" width="20" height="10" fill="#FC9797" />
<rect x="200" y="250" width="10" height="30" fill="#DFF2FE" />
<rect x="230" y="250" width="20" height="10" fill="#EBF5FF" />
<rect x="250" y="250" width="10" height="70" fill="#DFF2FE" />
<rect x="260" y="250" width="10" height="10" fill="#C0D4FF" />
<rect x="300" y="250" width="10" height="10" fill="#5E76AB" />
<rect x="310" y="250" width="10" height="20" fill="#1E2545" />
<rect x="70" y="260" width="10" height="60" fill="#A0BDFC" />
<rect x="100" y="260" width="10" height="10" fill="#C0D4FF" />
<rect x="110" y="260" width="10" 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="230" y="260" width="20" 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="300" y="260" width="10" height="60" fill="#A0BDFC" />
<rect x="50" y="270" width="10" height="40" fill="#1E2545" />
<rect x="60" y="270" width="10" height="10" fill="#5E76AB" />
<rect x="90" y="270" width="10" height="10" fill="#C0D4FF" />
<rect x="100" y="270" width="10" height="50" fill="#DFF2FE" />
<rect x="180" y="270" width="20" height="10" fill="#9EAEBA" />
<rect x="270" y="270" width="10" height="50" fill="#DFF2FE" />
<rect x="280" y="270" width="10" height="10" fill="#C0D4FF" />
<rect x="310" y="270" width="10" height="10" fill="#5E76AB" />
<rect x="320" y="270" width="10" height="40" fill="#1E2545" />
<rect x="60" y="280" width="10" height="20" fill="#A0BDFC" />
<rect x="90" y="280" width="10" height="30" fill="#DFF2FE" />
<rect x="170" y="280" width="10" height="10" fill="#B8CAD9" />
<rect x="180" y="280" width="20" height="40" fill="#DFF2FE" />
<rect x="200" y="280" width="10" height="10" fill="#B8CAD9" />
<rect x="280" y="280" width="10" height="30" fill="#DFF2FE" />
<rect x="310" y="280" width="10" height="20" fill="#A0BDFC" />
<rect x="170" 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="310" y="300" width="10" height="10" fill="#5E76AB" />
<rect x="60" y="310" width="10" height="10" fill="#1E2545" />
<rect x="90" 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="70" y="320" width="240" 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="60" y="80" width="20" height="10" fill="#1E2545" />
<rect x="80" y="80" width="10" height="10" fill="#5E76AB" />
<rect x="90" y="80" width="10" height="20" fill="#A0BDFC" />
<rect x="100" y="80" width="10" height="10" fill="#5E76AB" />
<rect x="110" 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="280" y="80" width="10" height="20" fill="#A0BDFC" />
<rect x="290" y="80" width="10" height="10" fill="#5E76AB" />
<rect x="300" y="80" width="20" 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="70" 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="130" 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="260" 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="320" y="90" 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="60" y="100" width="40" height="60" fill="#DFF2FE" />
<rect x="100" y="100" width="10" height="10" fill="#FAFEFF" />
<rect x="110" y="100" width="30" height="10" fill="#A0BDFC" />
<rect x="140" 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="270" y="100" width="10" height="10" fill="#FAFEFF" />
<rect x="280" y="100" width="40" height="60" fill="#DFF2FE" />
<rect x="320" y="100" width="10" height="10" fill="#5E76AB" />
<rect x="330" y="100" 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="50" y="110" width="10" height="70" 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="120" y="110" width="10" height="10" fill="#C0D4FF" />
<rect x="130" y="110" width="20" height="10" fill="#A0BDFC" />
<rect x="150" 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="250" y="110" width="10" height="10" fill="#C0D4FF" />
<rect x="260" y="110" width="10" height="10" fill="#FAFEFF" />
<rect x="270" y="110" width="10" height="50" 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="340" y="110" 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="40" y="120" width="10" height="60" 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="140" y="120" width="10" height="10" fill="#A0BDFC" />
<rect x="150" y="120" width="10" height="10" fill="#5E76AB" />
<rect x="160" 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="230" y="120" width="10" height="10" fill="#A0BDFC" />
<rect x="240" y="120" width="10" height="10" fill="#FAFEFF" />
<rect x="250" y="120" width="20" height="50" 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="350" y="120" 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="30" y="130" width="10" height="40" 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="150" y="130" width="20" height="60" fill="#A0BDFC" />
<rect x="170" 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="230" y="130" width="10" height="30" fill="#FAFEFF" />
<rect x="240" y="130" width="10" height="30" 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="360" y="130" width="10" height="10" 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="170" y="140" width="10" height="10" fill="#5E76AB" />
<rect x="180" y="140" width="20" height="10" fill="#1E2545" />
<rect x="200" 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="10" y="150" width="10" height="10" 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="200" y="150" width="10" height="30" 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="60" y="160" width="10" height="10" fill="#DFF2FE" />
<rect x="70" y="160" width="10" height="10" fill="#FAFEFF" />
<rect x="80" y="160" width="10" height="10" fill="#C0D4FF" />
<rect x="90" y="160" width="20" height="10" fill="#A0BDFC" />
<rect x="130" y="160" width="10" height="10" fill="#FAFEFF" />
<rect x="140" y="160" width="10" height="50" 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="240" y="160" width="10" height="10" fill="#FAFEFF" />
<rect x="270" y="160" width="20" height="10" fill="#A0BDFC" />
<rect x="290" y="160" width="10" height="10" fill="#C0D4FF" />
<rect x="300" y="160" width="10" height="10" fill="#FAFEFF" />
<rect x="310" y="160" width="10" height="10" fill="#DFF2FE" />
<rect x="360" y="160" width="10" height="10" fill="#5E76AB" />
<rect x="10" y="170" width="10" height="10" fill="#1E2545" />
<rect x="30" y="170" width="10" height="20" fill="#A0BDFC" />
<rect x="60" y="170" width="10" height="10" fill="#FAFEFF" />
<rect x="70" y="170" width="20" height="10" fill="#A0BDFC" />
<rect x="90" y="170" width="10" height="10" fill="#1E2545" />
<rect x="100" y="170" width="40" height="10" fill="#A0BDFC" />
<rect x="180" y="170" width="20" height="70" fill="#DFF2FE" />
<rect x="240" y="170" width="40" height="10" fill="#A0BDFC" />
<rect x="280" y="170" width="10" height="10" fill="#1E2545" />
<rect x="290" y="170" width="20" height="10" fill="#A0BDFC" />
<rect x="310" y="170" width="10" height="10" fill="#FAFEFF" />
<rect x="340" y="170" width="10" height="20" fill="#A0BDFC" />
<rect x="360" y="170" 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="50" y="180" width="10" height="10" fill="#FAFEFF" />
<rect x="60" y="180" width="20" height="10" fill="#A0BDFC" />
<rect x="80" 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="170" 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="270" 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="320" y="180" width="10" height="10" fill="#FAFEFF" />
<rect x="330" y="180" width="10" height="10" fill="#A0BDFC" />
<rect x="350" y="180" 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="50" y="190" width="20" height="10" fill="#A0BDFC" />
<rect x="70" y="190" width="10" height="10" 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="150" y="190" width="10" height="10" fill="#A0BDFC" />
<rect x="160" 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="270" y="190" width="10" height="10" fill="#5E76AB" />
<rect x="280" y="190" width="10" height="20" 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="330" y="190" width="10" height="10" fill="#5E76AB" />
<rect x="340" y="190" width="10" 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="150" y="200" width="10" height="10" fill="#C0D4FF" />
<rect x="160" 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="270" y="200" width="10" height="60" fill="#A0BDFC" />
<rect x="310" y="200" width="30" height="10" 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="110" y="210" width="20" height="30" fill="#A0BDFC" />
<rect x="130" y="210" width="20" height="10" fill="#333C64" />
<rect x="150" 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="250" y="210" width="20" height="30" fill="#A0BDFC" />
<rect x="280" y="210" width="10" height="10" fill="#5E76AB" />
<rect x="290" y="210" width="10" height="20" fill="#1E2545" />
<rect x="90" y="220" width="10" height="50" fill="#A0BDFC" />
<rect x="130" 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="70" y="230" width="10" height="20" fill="#1E2545" />
<rect x="80" 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="80" y="240" width="10" height="80" 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="170" y="240" width="40" height="10" fill="#FC9797" />
<rect x="250" y="240" width="10" height="10" fill="#C0D4FF" />
<rect x="260" y="240" width="10" height="10" 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="70" y="250" width="10" height="10" fill="#5E76AB" />
<rect x="110" y="250" width="10" height="10" fill="#C0D4FF" />
<rect x="120" y="250" width="10" height="70" fill="#DFF2FE" />
<rect x="130" y="250" width="20" height="10" fill="#EBF5FF" />
<rect x="170" y="250" width="10" height="30" fill="#DFF2FE" />
<rect x="180" y="250" width="20" height="10" fill="#FC9797" />
<rect x="200" y="250" width="10" height="30" fill="#DFF2FE" />
<rect x="230" y="250" width="20" height="10" fill="#EBF5FF" />
<rect x="250" y="250" width="10" height="70" fill="#DFF2FE" />
<rect x="260" y="250" width="10" height="10" fill="#C0D4FF" />
<rect x="300" y="250" width="10" height="10" fill="#5E76AB" />
<rect x="310" y="250" width="10" height="20" fill="#1E2545" />
<rect x="70" y="260" width="10" height="60" fill="#A0BDFC" />
<rect x="100" y="260" width="10" height="10" fill="#C0D4FF" />
<rect x="110" y="260" width="10" 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="230" y="260" width="20" 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="300" y="260" width="10" height="60" fill="#A0BDFC" />
<rect x="50" y="270" width="10" height="40" fill="#1E2545" />
<rect x="60" y="270" width="10" height="10" fill="#5E76AB" />
<rect x="90" y="270" width="10" height="10" fill="#C0D4FF" />
<rect x="100" y="270" width="10" height="50" fill="#DFF2FE" />
<rect x="180" y="270" width="20" height="10" fill="#9EAEBA" />
<rect x="270" y="270" width="10" height="50" fill="#DFF2FE" />
<rect x="280" y="270" width="10" height="10" fill="#C0D4FF" />
<rect x="310" y="270" width="10" height="10" fill="#5E76AB" />
<rect x="320" y="270" width="10" height="40" fill="#1E2545" />
<rect x="60" y="280" width="10" height="20" fill="#A0BDFC" />
<rect x="90" y="280" width="10" height="30" fill="#DFF2FE" />
<rect x="170" y="280" width="10" height="10" fill="#B8CAD9" />
<rect x="180" y="280" width="20" height="40" fill="#DFF2FE" />
<rect x="200" y="280" width="10" height="10" fill="#B8CAD9" />
<rect x="280" y="280" width="10" height="30" fill="#DFF2FE" />
<rect x="310" y="280" width="10" height="20" fill="#A0BDFC" />
<rect x="170" 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="310" y="300" width="10" height="10" fill="#5E76AB" />
<rect x="60" y="310" width="10" height="10" fill="#1E2545" />
<rect x="90" 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="70" y="320" width="240" height="10" fill="#1E2545" />
</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
// data among middlewares, layouts and routes.
export interface State {
shared: string;
shared: string;
}
export const define = createDefine<State>();

View file

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