Compare commits

..

14 commits
v2 ... main

Author SHA1 Message Date
c73749678b
update "made with <3" text
All checks were successful
/ deploy (push) Successful in 2s
2026-09-15 10:44:04 +01:00
ari
e70c83bdb4 Update README.md
All checks were successful
/ deploy (push) Successful in 2s
2026-09-15 09:41:44 +00:00
e063b2fa5c Merge pull request 'Add badges' (#1) from jj/add-badges into main
All checks were successful
/ deploy (push) Successful in 2s
Reviewed-on: #1
2026-09-15 09:39:43 +00:00
de6e1a98bc
Add badges to README.md 2026-09-15 10:39:02 +01:00
c49f2280f4
deploy workflow
All checks were successful
/ deploy (push) Successful in 2s
2026-09-15 10:36:44 +01:00
46e7d2660b
Add badges 2026-09-15 10:15:26 +01:00
64a50ccd10
update julia avatar 2026-07-28 23:22:35 +01:00
6e5aad77dd
css refactor :] 2026-03-23 21:32:25 +00:00
81ab7856c6
all my love for avif 2026-03-23 19:42:13 +00:00
ari melody
04951a75d5
update source link 2025-08-26 14:25:10 +01:00
ari melody
f06119c9a4
update crew list 2025-08-20 16:07:22 +01:00
ari melody
800f67a04f
update crew list; css tweaks 2025-08-11 12:24:50 +02:00
ari melody
6f6c0c3a6d
fix mobile display 2025-07-10 16:41:25 +01:00
ari melody
d112d7ae63
add makefile (ez bundling) 2025-07-10 16:24:35 +01:00
17 changed files with 209 additions and 151 deletions

View file

@ -0,0 +1,26 @@
on:
push:
branches:
- main
env:
REMOTE: ${{ secrets.SSH_USER }}@${{ secrets.SSH_HOST }}
PORT: ${{ secrets.SSH_PORT }}
jobs:
deploy:
runs-on: docker
steps:
- name: Set up SSH keys
run: |
mkdir -m 700 -p ~/.ssh
echo "${{ secrets.SSH_PRIVATE_KEY }}" > ~/.ssh/id_deploy
chmod 600 ~/.ssh/id_deploy
- name: Pull latest branch to production
run: |
ssh-keyscan -p $PORT ${{ secrets.SSH_HOST }} >> ~/.ssh/known_hosts
ssh -i ~/.ssh/id_deploy -p $PORT ${{ secrets.SSH_USER }}@${{ secrets.SSH_HOST }} <<EOF
cd ${{ secrets.SSH_DIRECTORY }}
git pull
EOF

5
.gitignore vendored
View file

@ -1,3 +1,2 @@
**/.DS_Store
docker-compose.yml
.vscode/
.DS_Store
*.tar.gz

View file

@ -1,3 +1,6 @@
# 🏕️ bliss.town
<a href="https://bliss.town"><img alt="Made with love by Bliss Town" src="https://bliss.town/img/badges/bliss-town.svg"/></a>
<img alt="Trans rights" src="https://bliss.town/img/badges/trans-rights.svg"/>
a cool source for a cool website!

Binary file not shown.

After

Width:  |  Height:  |  Size: 101 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 78 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="197" height="20" role="img" aria-label="Made with love by: Bliss Town"><title>Made with love by: Bliss Town</title><a target="_blank" href="https://bliss.town"><filter id="blur"><feGaussianBlur stdDeviation="16"/></filter><linearGradient id="s" x2="0" y2="100%"><stop offset="0" stop-color="#bbb" stop-opacity=".1"/><stop offset="1" stop-opacity=".1"/></linearGradient><clipPath id="r"><rect width="197" height="20" rx="3"/></clipPath><g clip-path="url(#r)"><rect width="128" height="20" fill="#555"/><rect x="128" width="69" height="20" fill="#92a40a"/><rect width="197" height="20" fill="url(#s)"/></g><g fill="#fff" text-anchor="middle" font-family="Verdana,Geneva,DejaVu Sans,sans-serif" text-rendering="geometricPrecision" font-size="110"><image x="5" y="3" width="14" height="14" href="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbDpzcGFjZT0icHJlc2VydmUiIHN0eWxlPSJmaWxsLXJ1bGU6ZXZlbm9kZDtjbGlwLXJ1bGU6ZXZlbm9kZDtzdHJva2UtbGluZWpvaW46cm91bmQ7c3Ryb2tlLW1pdGVybGltaXQ6MiIgdmlld0JveD0iMCAwIDEwMDAgMTAwMCI+PHBhdGggZD0iTTAgMGg1MTJ2NTEySDB6IiBzdHlsZT0iZmlsbDpub25lIiB0cmFuc2Zvcm09InNjYWxlKDEuOTUzMTIpIi8+PHBhdGggZD0iTTY4MC40ODggNDAzLjE5YTE2Ljg3IDE2Ljg3IDAgMCAxIDE1LjYyOSAxMC41MTVMODQ3LjY2OCA3ODYuM2EyNS4zMDcgMjUuMzA3IDAgMCAxLTIzLjQ0MyAzNC44NDJINDUwLjM1MWExNi44NyAxNi44NyAwIDAgMS0xNS42MjgtMTAuNTE0TDMwMi4wNjggNDg0LjQ4OWE1OS4wNTIgNTkuMDUyIDAgMCAxIDU0LjY5OS04MS4yOTl6IiBzdHlsZT0iZmlsbDojNjA2OTJjIiB0cmFuc2Zvcm09Im1hdHJpeCgtMS4xODU0MiAwIDAgMS4xODU0MiAxMDc3LjE1IC0yNi4wNDcpIi8+PHBhdGggZD0ibTY2OC44MyA1MDMuODI0IDEyOS4wNjcgMzE3LjMxOEg0OTIuNTY2eiIgc3R5bGU9ImZpbGw6IzQyNDgxZCIgdHJhbnNmb3JtPSJtYXRyaXgoLTEuMTg1NDIgMCAwIDEuMTg1NDIgMTA3Ny4xNSAtMjYuMDQ3KSIvPjxwYXRoIGQ9Ik02NDYuNDM0IDQwMy4xOWMyNy40NTMgMCA1Mi4xNyAxNi42MyA2Mi41MTMgNDIuMDZsMTQzLjQ0NSAzNTIuNjY0YTE2Ljg3IDE2Ljg3IDAgMCAxLTE1LjYyOSAyMy4yMjhINDg0LjQwNmMtMjcuNDUzIDAtNTIuMTctMTYuNjI5LTYyLjUxNC00Mi4wNTlMMjgwLjIxNyA0MzAuNzY4YTIwLjAzMiAyMC4wMzIgMCAwIDEgMTguNTU1LTI3LjU3OHoiIHN0eWxlPSJmaWxsOiM4ZjlhNGIiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC04My4wOTIgLTI2LjA0NylzY2FsZSgxLjE4NTQyKSIvPjxwYXRoIGQ9Ik01NjkuODE5IDQwMy4xOWM3My43NzUgMCAxNDAuMTk4IDQ0LjY5IDE2Ny45OTUgMTEzLjAyOUw4MzYuNDUgNzU4LjcyYTQ1LjM0IDQ1LjM0IDAgMCAxLTQxLjk5OSA2Mi40MjJoLTIzMy40M2MtNzMuNzc1IDAtMTQwLjE5OS00NC42OS0xNjcuOTk1LTExMy4wMjlsLTk4LjYzNi0yNDIuNWE0NS4zNCA0NS4zNCAwIDAgMSA0MS45OTktNjIuNDIzeiIgc3R5bGU9ImZpbGw6I2Y0ZmZhZSIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMzM3Ljc1NCA0MDUuODg0KXNjYWxlKC40NDExKSIvPjxwYXRoIGQ9Ik01MTggNTUxdjI5YzAgMy44NjMtMy4xMzcgNy03IDdzLTctMy4xMzctNy03di0yOWMwLTMuODYzIDMuMTM3LTcgNy03czcgMy4xMzcgNyA3bTMxLjk2OC0zLjk2MXYyOWMwIDMuODY0LTMuMTM2IDctNyA3cy03LTMuMTM2LTctN3YtMjljMC0zLjg2MyAzLjEzNy03IDctN3M3IDMuMTM3IDcgNyIgc3R5bGU9ImZpbGw6IzllYWE1NSIgdHJhbnNmb3JtPSJyb3RhdGUoNDUgNjE5Ljk4OCA1NTIuNzI2KXNjYWxlKDEuMTg1NDIpIi8+PHBhdGggZD0iTTQwNy4wNTEgMTc4LjEwM2MwLTQ0LjEyNSAzNS44MjQtNzkuOTQ5IDc5Ljk0OS03OS45NDlzNzkuOTQ5IDM1LjgyNCA3OS45NDkgNzkuOTQ5YzQ0LjEyNCAwIDc5Ljk0OCAzNS44MjQgNzkuOTQ4IDc5Ljk0OCAwIDQ0LjEyNS0zNS44MjQgNzkuOTQ5LTc5Ljk0OCA3OS45NDlINDA3LjA1MXoiIHN0eWxlPSJmaWxsOiMzMjJlMWYiIHRyYW5zZm9ybT0icm90YXRlKC00NSA0NTEuMzczIDU1My45MzYpc2NhbGUoMS40MzcxKSIvPjxzY3JpcHQvPjwvc3ZnPg=="/><g transform="scale(.1)"><g aria-hidden="true" fill="#010101"><text x="735" y="150" fill-opacity=".8" filter="url(#blur)" textLength="1010">Made with love by</text><text x="735" y="150" fill-opacity=".3" textLength="1010">Made with love by</text></g><text x="735" y="140" textLength="1010">Made with love by</text></g><g transform="scale(.1)"><g aria-hidden="true" fill="#010101"><text x="1615" y="150" fill-opacity=".8" filter="url(#blur)" textLength="590">Bliss Town</text><text x="1615" y="150" fill-opacity=".3" textLength="590">Bliss Town</text></g><text x="1615" y="140" textLength="590">Bliss Town</text></g></g></a><script xmlns=""/></svg>

After

Width:  |  Height:  |  Size: 3.7 KiB

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="107" height="20" role="img" aria-label="Trans rights"><title>Trans rights</title><linearGradient id="s" x2="0" y2="100%"><stop offset="0" stop-color="#bbb" stop-opacity=".1"/><stop offset="1" stop-opacity=".1"/></linearGradient><clipPath id="r"><rect width="107" height="20" rx="3" fill="#fff"/></clipPath><g clip-path="url(#r)"><rect width="77" height="20" fill="#555"/><rect x="77" width="6" height="20" fill="#5bcefa"/><rect x="83" width="6" height="20" fill="#f5a9b8"/><rect x="89" width="6" height="20" fill="#ffffff"/><rect x="95" width="6" height="20" fill="#f5a9b8"/><rect x="101" width="6" height="20" fill="#5bcefa"/><rect width="107" height="20" fill="url(#s)"/></g><g fill="#fff" text-anchor="middle" font-family="Verdana,Geneva,DejaVu Sans,sans-serif" text-rendering="geometricPrecision" font-size="110"><text aria-hidden="true" x="395" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="670">Trans rights</text><text x="395" y="140" transform="scale(.1)" fill="#fff" textLength="670">Trans rights</text></g><script xmlns=""/></svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 MiB

View file

@ -4,7 +4,7 @@
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" value="width=device-width, initial-scale=1">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>bliss town</title>
<link rel="icon" type="image/x-icon" href="/img/favicon.png">
@ -16,28 +16,27 @@
<link rel="stylesheet" type="text/css" href="/style/main.css">
<link rel="stylesheet" type="text/css" href="/style/index.css">
<script type="module" src="/script/index.js" defer></script>
</head>
<body>
<header>
<nav>
<span class="nav-title">
<span class="title-icon">
<div class="title-icon">
<img src="/img/icon-light.svg" class="only-light" width=26 height=26 />
<img src="/img/icon-dark.svg" class="only-dark" width=26 height=26 />
</span>
</div>
<strong>bliss<span class="col-on-primary">.</span>town</strong>
</span>
<a href="/">home</a>
<a href="https://git.arimelody.me/ari/bliss.town">source</a>
<a href="https://forge.bliss.town/blisstown/bliss.town">source</a>
</nav>
</header>
<main>
<h1>
<span class="title-icon">
<div class="title-icon">
<img src="/img/icon-light.svg" class="only-light" width=64 height=64 />
<img src="/img/icon-dark.svg" class="only-dark" width=64 height=64 />
</span>
</div>
welcome to bliss<span class="col-on-primary">.</span>town!
</h1>
@ -52,42 +51,64 @@
<div id="crew-list">
<div class="crew-item">
<img src="https://arimelody.space/img/favicon.png" alt="ari melody photo" class="avatar" width=64 height=64>
<div class="crew-avatar">
<img src="/img/avatars/arispacegirl.avif"
alt="ari melody photo"
class="avatar"
width=128 height=128>
</div>
<div class="crew-info">
<h3>ari</h3>
<p><a href="https://arimelody.space" class="handle">@arispacegirl</a></p>
<div class="crew-tags">
<span class="crew-tag">she/her</span>
<span class="crew-tag">developer</span>
<span class="crew-tag">musician</span>
<span class="crew-tag">artist</span>
</div>
</div>
</div>
<div class="crew-item">
<img src="https://media.wetdry.world/accounts/avatars/107/412/233/663/540/779/original/9e4353266869a4cd.jpeg" alt="vimae photo" class="avatar" width=64 height=64>
<div class="crew-avatar">
<img src="/img/avatars/vimae.avif"
alt="vimae photo"
class="avatar"
width=128 height=128>
</div>
<div class="crew-info">
<h3>mae</h3>
<p><a href="https://mae.wtf" class="handle">@vimae</a></p>
<div class="crew-tags">
<span class="crew-tag">she/they</span>
<span class="crew-tag">musician</span>
<span class="crew-tag">artist</span>
<span class="crew-tag">developer</span>
</div>
</div>
</div>
<div class="crew-item">
<img src="https://44.media.tumblr.com/feb33c9c0151a46d09a55a6e0d7fa0f3/34631bc4c40620ff-2c/s128x128u_c1_f1/b06e02240d23dacddf257fe50cfe3a9c6dbee537.gif" alt="claire photo" class="avatar" width=64 height=64>
<div class="crew-avatar">
<img src="/img/avatars/zaire.avif"
alt="claire photo"
class="avatar"
width=128 height=128>
</div>
<div class="crew-info">
<h3>claire</h3>
<p><a href="https://supitszaire.com" class="handle">@zaire</a></p>
<div class="crew-tags">
<span class="crew-tag">she/her</span>
<span class="crew-tag">musician</span>
<span class="crew-tag">artist</span>
</div>
</div>
<div class="crew-item">
<div class="crew-avatar">
<img src="/img/avatars/karakara.avif"
alt="julia photo"
class="avatar"
width=128 height=128>
</div>
<div class="crew-info">
<h3>julia</h3>
<p><a href="https://insertdomain.name" class="handle">@karakara</a></p>
</div>
</div>
<div class="crew-item">
<div class="crew-avatar">
<img src="/img/avatars/loudar.avif"
alt="alex photo"
class="avatar"
width=128 height=128>
</div>
<div class="crew-info">
<h3>alex</h3>
<p><a href="https://illegal.trading" class="handle">@loudar</a></p>
</div>
</div>
</div>
</div>
@ -100,12 +121,15 @@
<div id="project-list">
<div class="project-item">
<div class="project-item-banner">
<img src="/img/projects/campfire.png" alt="screenshot of the campfire timeline" width=256>
<img src="/img/projects/campfire.avif" alt="screenshot of the campfire timeline" width=256>
</div>
<div class="project-info">
<h3>campfire</h3>
<h3>
<a href="https://campfire.bliss.town" class="col-on-primary">
campfire
</a>
</h3>
<p>a pretty, modern web client for the fediverse!</p>
<a href="https://campfire.bliss.town" class="col-on-primary">campfire.bliss.town</a>
</div>
</div>
</div>
@ -113,8 +137,10 @@
</main>
<footer>
<p>
made with <span role="img" aria-label="love"></span> by <a href="https://arimelody.space">ari</a>, 2025.
made with <span role="img" aria-label="love"></span> by bliss town, 2026.
</p>
</footer>
<script type="module" src="/script/index.js" defer></script>
</body>
</html>

View file

@ -1,13 +1,8 @@
import { hijackClickEvent } from './main.js';
import { hijackClickEvent } from "./main.js";
document.addEventListener('readystatechange', () => {
document.querySelectorAll("#project-list .project-item").forEach(projectItem => {
const link = projectItem.querySelector('a');
hijackClickEvent(projectItem, link);
});
document.querySelectorAll("#crew-list .crew-item .crew-info").forEach(crewItem => {
const link = crewItem.querySelector('a.handle');
hijackClickEvent(crewItem, link);
document.addEventListener("readystatechange", () => {
document.querySelectorAll(".project-item").forEach(container => {
const link = container.querySelector("a");
hijackClickEvent(container, link);
});
});

View file

@ -1,4 +1,4 @@
export function hijackClickEvent(container, link) {
export function hijackClickEvent(container, link) {
container.addEventListener('click', event => {
if (event.target.tagName.toLowerCase() === 'a') return;
event.preventDefault();

View file

@ -8,110 +8,113 @@
border-radius: 8px;
overflow: clip;
background-color: var(--primary);
transition: background-color .2s linear;
box-shadow: 2px 2px 2px #0004;
box-shadow: 4px 4px 0 color-mix(in srgb, var(--background), #0008 50%);
cursor: pointer;
}
.project-item:hover {
outline: 1px solid var(--on-primary);
}
.project-item-banner {
.project-item-banner {
width: 256px;
height: 128px;
}
.project-item-banner img {
img {
width: 100%;
height: 100%;
object-fit: cover;
}
}
}
.project-info {
.project-info {
padding: .4em .5em;
}
.project-info h3 {
margin: 0;
}
.project-info p {
font-size: .8em;
margin: 0;
}
.project-info a {
font-style: italic;
font-size: .8em;
h3 {
margin: 0 0 .2em 0;
a {
color: var(--on-background);
opacity: .75;
transition: color .2s linear;
text-decoration: none;
}
}
p {
font-size: .8em;
margin: 0;
}
}
&:hover {
outline: 1px solid var(--on-primary);
}
}
#crew-list {
display: flex;
gap: 1em;
flex-wrap: wrap;
}
justify-content: center;
gap: 2em 4em;
.crew-item {
display: flex;
flex-direction: row;
.crew-item {
width: 10em;
display: grid;
grid-template-rows: 8em 4em;
gap: .5em;
}
text-align: center;
transform: rotate(2deg);
.crew-item img.avatar {
width: 64px;
height: 64px;
&:nth-child(even) {
transform: rotate(-2deg);
&:hover .crew-avatar img.avatar {
transform: rotate(-4deg);
}
}
.crew-avatar img.avatar, .crew-info {
box-shadow: 4px 4px 0 color-mix(in srgb, var(--background), #0008 50%);
}
&:hover .crew-avatar img.avatar {
transform: rotate(2deg);
}
}
.crew-avatar {
img.avatar {
width: 8em;
height: 8em;
aspect-ratio: 1;
object-fit: cover;
border-radius: 8px;
background-color: #101010;
}
background-color: var(--primary);
}
}
.crew-item:nth-child(even) .crew-avatar img.avatar {
transform: rotate(-2deg);
}
.crew-item .crew-info {
.crew-info {
padding: .5em;
display: flex;
flex-direction: column;
background-color: var(--primary);
border-radius: 8px;
box-shadow: 2px 2px 2px #0004;
transition: background-color .2s linear;
cursor: pointer;
}
.crew-info:hover {
outline: 1px solid var(--on-primary);
}
.crew-item h3 {
display: block;
margin: 0 0 -.2em 0;
transition: inherit;
}
.crew-item h3 a {
display: block;
color: inherit;
}
h3, p {
margin: 0;
}
.crew-item a.handle {
display: block;
font-style: italic;
h3 {
font-size: 1.5em;
}
p {
font-size: .8em;
color: var(--on-background);
opacity: .75;
transition: color .2s linear;
text-decoration: none;
}
}
.crew-item:nth-child(odd) .crew-info:before {
transform: skew(0, 2deg) translate(1.3em, -.2em);
}
}
.crew-item p {
margin: .2em 0;
}
.crew-item .crew-tags {
margin: .5em 0 0 0;
display: flex;
gap: .2em;
}
.crew-item .crew-tag {
font-size: .75em;
padding: .2em .5em;
border-radius: 4px;
text-wrap: nowrap;
color: var(--on-primary);
border: 1px solid var(--on-primary);
@media screen and (max-width: 900px) {
#crew-list {
#grid-template-columns: repeat(2, 1fr);
}
}

View file

@ -25,8 +25,11 @@ body {
color: var(--on-background);
background-color: var(--background);
}
transition: color .2s linear, background-color .2s linear;
*, *::before, *::after {
transition-property: background-color, color, box-shadow, border-color, opacity;
transition-duration: .2s;
}
header {
@ -38,7 +41,6 @@ header {
border-bottom: 1px solid var(--primary);
background-color: var(--background);
z-index: 1000;
transition: background-color .2s linear, box-shadow .2s linear, border-color .2s linear;
}
header nav {
@ -78,12 +80,10 @@ main {
.only-light {
opacity: 1;
transition: opacity .2s linear;
}
.only-dark {
opacity: 0;
transition: opacity .2s linear;
}
hr {
@ -99,14 +99,12 @@ hr::after {
padding: 5px;
color: var(--on-background);
background: var(--background);
transition: color .2s linear, background-color .2s linear;
}
a {
color: var(--on-primary);
text-decoration: none;
font-weight: bold;
transition: color .2s linear;
}
a:hover {
@ -123,7 +121,6 @@ button {
border: none;
border-radius: 2em;
cursor: pointer;
transition: color .2s linear, background-color .2s linear, transform .1s ease-out;
}
button:hover {
@ -140,7 +137,6 @@ footer {
padding: 1em 0;
text-align: center;
opacity: .5;
transition: opacity .1s ease-out;
}
footer:hover {
@ -153,13 +149,15 @@ footer:hover {
.title-icon {
position: relative;
height: 1.2em;
width: 1.3em;
height: 1.1em;
margin: 0 .1em;
padding-right: 1.6em;
display: inline-block;
}
.title-icon img {
width: 1.4em;
height: 1.4em;
position: absolute;
}
@ -179,3 +177,9 @@ footer:hover {
box-shadow: 0 2px 8px #0c03116e;
}
}
@media screen and (max-width: 500px) {
h1 {
font-size: 1.2em;
}
}