full page redesign; improved light theme

This commit is contained in:
ari melody 2025-07-10 16:05:21 +01:00
parent b58290b4e5
commit 6ee4538dc3
Signed by: ari
GPG key ID: CF99829C92678188
9 changed files with 379 additions and 284 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 MiB

View file

@ -15,51 +15,101 @@
<meta property="og:url" content="https://bliss.town" /> <meta property="og:url" content="https://bliss.town" />
<link rel="stylesheet" type="text/css" href="/style/main.css"> <link rel="stylesheet" type="text/css" href="/style/main.css">
<script type="application/javascript" src="/script/vendor/htmx.min.js"></script> <link rel="stylesheet" type="text/css" href="/style/index.css">
<script type="module" src="/script/index.js" defer></script>
</head> </head>
<body> <body>
<header> <header>
<nav hx-boost="true" hx-target="body" hx-swap="outerHTML show:window:top"> <nav>
<span class="nav-title">
<span 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>
<strong>bliss<span class="col-on-primary">.</span>town</strong>
</span>
<a href="/">home</a> <a href="/">home</a>
<span aria-hidden="true">-</span> <a href="https://git.arimelody.me/ari/bliss.town">source</a>
<a href="/links">links</a>
<span aria-hidden="true">-</span>
<a href="/paste">paste</a>
<span aria-hidden="true">-</span>
<a href="https://git.arimelody.me/ari/bliss.town" target="_blank">source</a>
</nav> </nav>
</header> </header>
<main class="center-content"> <main>
<div class="title-icon"> <h1>
<img src="/img/icon-light.svg" class="icon-light" width=64 height=64 /> <span class="title-icon">
<img src="/img/icon-dark.svg" class="icon-dark" width=64 height=64 /> <img src="/img/icon-light.svg" class="only-light" width=64 height=64 />
</div> <img src="/img/icon-dark.svg" class="only-dark" width=64 height=64 />
<h1>welcome to bliss<span class="col-primary-bg">.</span>town!</h1> </span>
<hr> welcome to bliss<span class="col-on-primary">.</span>town!
</h1>
<p> <p>
we're not hosting much at this domain just yet. we're a collective of online creatives.
<br>
check back later for updates!
</p> </p>
<button id="friendly-button">friendly button</button>
<script> <hr/>
function hook_button() {
const button = document.getElementById("friendly-button"); <div id="crew">
if (!button) return; <h2>check us out!</h2>
let clicks = 0;
let saved_clicks = window.localStorage.getItem("friendly-button-clicks"); <div id="crew-list">
if (saved_clicks) { <div class="crew-item">
clicks = saved_clicks; <img src="https://arimelody.space/img/favicon.png" alt="ari melody photo" class="avatar" width=64 height=64>
button.innerText = `clicked ${clicks} times!`; <div class="crew-info">
} <h3>ari</h3>
button.addEventListener("click", () => { <p><a href="https://arimelody.space" class="handle">@arispacegirl</a></p>
button.innerText = `clicked ${++clicks} times!`; <div class="crew-tags">
window.localStorage.setItem("friendly-button-clicks", clicks); <span class="crew-tag">she/her</span>
}); <span class="crew-tag">developer</span>
} <span class="crew-tag">musician</span>
document.addEventListener("ready", hook_button); <span class="crew-tag">artist</span>
document.addEventListener("htmx:load", hook_button); </div>
</script> </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-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-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>
</div>
</div>
<hr/>
<div id="projects">
<h2>stuff we make</h2>
<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>
</div>
<div class="project-info">
<h3>campfire</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>
</div>
</main> </main>
<footer> <footer>
<p> <p>

View file

@ -1,47 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<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">
<title>shortlinks - bliss town</title>
<link rel="icon" type="image/x-icon" href="/img/favicon.png">
<meta property="og:site_name" content="bliss town" />
<meta property="og:title" content="bliss town shortlinks" />
<meta property="og:image" content="https://bliss.town/img/og-icon.png" />
<meta property="og:type" content="website" />
<meta property="og:url" content="https://bliss.town/links" />
<link rel="stylesheet" type="text/css" href="/style/main.css">
<script type="application/javascript" src="/script/vendor/htmx.min.js"></script>
</head>
<body>
<header>
<nav hx-boost="true" hx-target="body" hx-swap="outerHTML show:window:top">
<a href="/">home</a>
<span aria-hidden="true">-</span>
<a href="/links">links</a>
<span aria-hidden="true">-</span>
<a href="/paste">paste</a>
<span aria-hidden="true">-</span>
<a href="https://git.arimelody.me/ari/bliss.town" target="_blank">source</a>
</nav>
</header>
<main class="center-content">
<h1><span aria-hidden="true">🔗</span><br>bliss<span class="col-primary-bg">.</span>town shortlinks</h1>
<hr>
<p>
we run an invite-only shortlink service, <code>link.bliss.town</code>,
<br>
powered by <a href="https://yourls.org/">YOURLS</a>.
</p>
</main>
<footer>
<p>
made with <span role="img" aria-label="love"></span> by <a href="https://arimelody.me">ari</a>, 2024.
</p>
</footer>
</body>
</html>

View file

@ -1,47 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<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">
<title>pastebin - bliss town</title>
<link rel="icon" type="image/x-icon" href="/img/favicon.png">
<meta property="og:site_name" content="bliss town" />
<meta property="og:title" content="bliss town pastebin" />
<meta property="og:image" content="https://bliss.town/img/og-icon.png" />
<meta property="og:type" content="website" />
<meta property="og:url" content="https://bliss.town/paste" />
<link rel="stylesheet" type="text/css" href="/style/main.css">
<script type="application/javascript" src="/script/vendor/htmx.min.js"></script>
</head>
<body>
<header>
<nav hx-boost="true" hx-target="body" hx-swap="outerHTML show:window:top">
<a href="/">home</a>
<span aria-hidden="true">-</span>
<a href="/links">links</a>
<span aria-hidden="true">-</span>
<a href="/paste">paste</a>
<span aria-hidden="true">-</span>
<a href="https://git.arimelody.me/ari/bliss.town" target="_blank">source</a>
</nav>
</header>
<main class="center-content">
<h1><span aria-hidden="true">📝</span><br>bliss<span class="col-primary-bg">.</span>town pastebin</h1>
<hr>
<p>
we run a public pastebin instance, <a href="https://paste.bliss.town"><code>paste.bliss.town</code></a>,
<br>
powered by <a href="https://docs.dpaste.org">dpaste</a>.
</p>
</main>
<footer>
<p>
made with <span role="img" aria-label="love"></span> by <a href="https://arimelody.me">ari</a>, 2024.
</p>
</footer>
</body>
</html>

13
public/script/index.js Normal file
View file

@ -0,0 +1,13 @@
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);
});
});

16
public/script/main.js Normal file
View file

@ -0,0 +1,16 @@
export function hijackClickEvent(container, link) {
container.addEventListener('click', event => {
if (event.target.tagName.toLowerCase() === 'a') return;
event.preventDefault();
link.dispatchEvent(new MouseEvent('click', {
bubbles: true,
cancelable: true,
view: window,
ctrlKey: event.ctrlKey,
metaKey: event.metaKey,
shiftKey: event.shiftKey,
altKey: event.altKey,
button: event.button,
}));
});
}

File diff suppressed because one or more lines are too long

117
public/style/index.css Normal file
View file

@ -0,0 +1,117 @@
#project-list {
display: flex;
gap: 1em;
}
.project-item {
width: 256px;
border-radius: 8px;
overflow: clip;
background-color: var(--primary);
transition: background-color .2s linear;
box-shadow: 2px 2px 2px #0004;
cursor: pointer;
}
.project-item:hover {
outline: 1px solid var(--on-primary);
}
.project-item-banner {
width: 256px;
height: 128px;
}
.project-item-banner img {
width: 100%;
height: 100%;
object-fit: cover;
}
.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;
color: var(--on-background);
opacity: .75;
transition: color .2s linear;
text-decoration: none;
}
#crew-list {
display: flex;
gap: 1em;
flex-wrap: wrap;
}
.crew-item {
display: flex;
flex-direction: row;
gap: .5em;
}
.crew-item img.avatar {
width: 64px;
height: 64px;
object-fit: cover;
border-radius: 8px;
background-color: #101010;
}
.crew-item .crew-info {
padding: .5em;
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;
}
.crew-item a.handle {
display: block;
font-style: italic;
font-size: .8em;
color: var(--on-background);
opacity: .75;
transition: color .2s linear;
text-decoration: none;
}
.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);
}

View file

@ -1,18 +1,18 @@
@import url("/font/lora/lora-font.css"); @import url("/font/lora/lora-font.css");
:root { :root {
--foreground: #322e1f; --background: #fffcf7;
--background: #f9f1db; --on-background: #322e1f;
--primary-fg: #92a40a; --primary: #f7eddb;
--primary-bg: #c4ce7e; --on-primary: #92a40a;
} }
@media screen and (prefers-color-scheme: dark) { @media screen and (prefers-color-scheme: dark) {
:root { :root {
--foreground: #e2dfe3;
--background: #1b141e; --background: #1b141e;
--primary-fg: #cda1ec; --on-background: #e2dfe3;
--primary-bg: #513d60; --primary: #352640;
--on-primary: #cda1ec;
} }
} }
@ -23,7 +23,7 @@ body {
font-family: "Lora", serif; font-family: "Lora", serif;
font-size: 20px; font-size: 20px;
color: var(--foreground); color: var(--on-background);
background-color: var(--background); background-color: var(--background);
transition: color .2s linear, background-color .2s linear; transition: color .2s linear, background-color .2s linear;
@ -31,83 +31,79 @@ body {
header { header {
position: fixed; position: fixed;
top: 1em; top: 0;
left: 50%; left: 0;
transform: translateX(-50%); width: 100vw;
width: min(900px, calc(100vw - 4rem)); transform: none;
margin: 0 auto; border-bottom: 1px solid var(--primary);
padding: .5em 0; background-color: var(--background);
border-radius: 2em; z-index: 1000;
text-align: center; transition: background-color .2s linear, box-shadow .2s linear, border-color .2s linear;
backdrop-filter: blur(1em);
z-index: 100;
} }
header nav { header nav {
width: min(900px, calc(100vw - 4rem));
margin: 0 auto;
font-size: .8em; font-size: .8em;
user-select: none;
} }
header nav span { header nav>span,
margin: 0 .8em; header nav>div,
color: var(--primary-fg); header nav>a {
margin: 0;
padding: .5em 1em;
display: inline-block;
color: var(--on-primary);
}
header nav .nav-title {
color: var(--on-background);
}
header nav div {
margin: 0 .4em;
display: inline-block;
}
header nav div img {
display: inline-block;
} }
main { main {
width: min(720px, calc(100vw - 4rem)); width: min(900px, calc(100vw - 4rem));
min-height: calc(100vh - 8.3em); min-height: calc(100vh - 9.4em);
margin: 3em auto 0 auto; margin: 4em auto 0 auto;
text-align: center; padding: 0;
} }
.title-icon { .only-light {
width: 64px; opacity: 1;
margin: 1em auto -1em auto;
display: flex;
}
.title-icon img {
transition: opacity .2s linear; transition: opacity .2s linear;
} }
.title-icon img.icon-dark { .only-dark {
position: relative;
left: -64px;
opacity: 0; opacity: 0;
} transition: opacity .2s linear;
@media screen and (prefers-color-scheme: dark) {
.title-icon img.icon-light {
opacity: 0;
}
.title-icon img.icon-dark {
opacity: 1;
}
}
.center-content {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
} }
hr { hr {
width: 100%; width: 100%;
margin: 1em 0; margin: 2em 0 1.5em 0;
border-width: 1px 0 0 0; border-width: 1px 0 0 0;
text-align: center;
} }
hr::after { hr::after {
content: "✦"; content: "✦";
position: absolute; position: absolute;
transform: translate(-50%, -54.5%); transform: translate(-50%, -54.5%);
padding: 5px; padding: 5px;
color: var(--foreground); color: var(--on-background);
background: var(--background); background: var(--background);
transition: color .2s linear, background-color .2s linear; transition: color .2s linear, background-color .2s linear;
} }
a { a {
color: var(--primary-fg); color: var(--on-primary);
text-decoration: none; text-decoration: none;
font-weight: bold; font-weight: bold;
transition: color .2s linear; transition: color .2s linear;
@ -122,8 +118,8 @@ button {
font-size: .8em; font-size: .8em;
font-family: inherit; font-family: inherit;
font-weight: bold; font-weight: bold;
color: var(--foreground); color: var(--on-background);
background-color: var(--primary-bg); background-color: var(--primary);
border: none; border: none;
border-radius: 2em; border-radius: 2em;
cursor: pointer; cursor: pointer;
@ -155,33 +151,31 @@ footer:hover {
font-size: .8em; font-size: .8em;
} }
[class^="col-"] { .title-icon {
transition: color .2s linear; position: relative;
height: 1.2em;
margin: 0 .1em;
padding-right: 1.6em;
display: inline-block;
} }
[class^="bg-"] {
transition: background-color .2s linear; .title-icon img {
position: absolute;
} }
.col-fg {
color: var(--foreground); .col-on-primary {
color: var(--on-primary);
} }
.bg-fg {
background-color: var(--foreground); @media screen and (prefers-color-scheme: dark) {
.only-light {
opacity: 0;
} }
.col-bg { .only-dark {
color: var(--background); opacity: 1;
} }
.bg-bg {
background-color: var(--background); header {
box-shadow: 0 2px 8px #0c03116e;
} }
.col-primary-fg {
color: var(--primary-fg);
}
.bg-primary-fg {
background-color: var(--primary-fg);
}
.col-primary-bg {
color: var(--primary-bg);
}
.bg-primary-bg {
background-color: var(--primary-bg);
} }