Files
0xa0.dev/css/style.css
T
2026-10-03 15:08:34 +02:00

288 lines
8.5 KiB
CSS

:root {
--bg: #0d0d0d;
--fg: #e8e8e8;
--muted: #888;
--line: #262626;
--field: #161616;
}
* { box-sizing: border-box; }
body {
margin-inline: auto;
max-width: 680px;
padding: 2rem 1.25rem;
background: var(--bg);
color: var(--fg);
font: 16px/1.6 ui-monospace, "JetBrains Mono", Menlo, monospace;
}
a { color: var(--fg); text-decoration: none; border-bottom: 1px solid var(--muted); }
a:hover { border-color: var(--fg); }
header nav {
display: flex;
gap: 1rem;
margin-bottom: 2rem;
padding-bottom: 1rem;
border-bottom: 1px solid var(--line);
}
h1 { font-size: 1.6rem; }
h1 .phonetic { color: darkgrey; font-size: 1rem; font-weight: normal; }
h2 { font-size: 1.1rem; color: var(--muted); font-weight: normal; }
footer {
margin-top: 3rem;
padding-top: 1rem;
border-top: 1px solid var(--line);
color: var(--muted);
}
.buttons88x31 {
display: flex;
flex-wrap: wrap;
gap: .4rem;
margin-bottom: .8rem;
}
.buttons88x31 a { border-bottom: none; }
.buttons88x31 img {
width: 88px;
height: 31px;
image-rendering: pixelated;
display: block;
}
.dot {
display: inline-block;
width: .6em; height: .6em;
border-radius: 50%;
background: var(--muted);
vertical-align: middle;
}
.dot-online { background: #3ba55d; }
.dot-idle { background: #faa61a; }
.dot-dnd { background: #ed4245; }
.dot-offline { background: #747f8d; }
.status-row {
display: flex;
flex-wrap: wrap;
align-items: stretch;
gap: .6rem;
}
.status-card {
display: flex;
align-items: center;
gap: .8rem;
padding: .8rem;
flex: 1 1 220px;
min-width: 0;
border: 1px solid var(--line);
border-radius: 4px;
background-size: cover;
background-position: center;
}
.status-card .avatar { border-radius: 4px; flex: none; }
.status-card .who { display: flex; flex-direction: column; gap: .15rem; }
.status-card .name { font-weight: bold; }
.status-card .state { color: var(--muted); font-size: .9rem; }
.spotify-card {
display: flex;
align-items: center;
gap: .8rem;
padding: .7rem;
flex: 1 1 220px;
min-width: 0;
border: 1px solid var(--line);
border-radius: 4px;
color: var(--fg);
}
a.spotify-card:hover { border-color: #1db954; }
.spotify-card .album-art { border-radius: 4px; flex: none; }
.spotify-card .album-art--empty {
width: 64px; height: 64px;
display: flex; align-items: center; justify-content: center;
background: var(--field);
color: var(--muted);
font-size: 1.5rem;
}
.np-label { font-size: .72rem; letter-spacing: .02em; }
.spotify-card .np-label { color: #1db954; }
.spotify-idle .np-label { color: var(--muted); }
.dc-label { color: #5865f2; }
.spotify-card .track { display: flex; flex-direction: column; gap: .1rem; min-width: 0; }
.spotify-card .np-label { color: #1db954; font-size: .72rem; letter-spacing: .02em; }
.spotify-card .song { font-weight: bold; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.spotify-card .artist { color: var(--muted); font-size: .85rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
form { display: flex; flex-direction: column; gap: .5rem; margin: 1.5rem 0; }
input, textarea {
background: var(--field);
border: 1px solid var(--line);
color: var(--fg);
padding: .6rem;
font: inherit;
border-radius: 4px;
}
textarea { min-height: 5rem; resize: vertical; }
button {
align-self: flex-start;
background: var(--fg);
color: var(--bg);
border: 0;
padding: .5rem 1.2rem;
font: inherit;
cursor: pointer;
border-radius: 4px;
}
.entry { border-top: 1px solid var(--line); padding: .8rem 0; }
.entry .date { color: var(--muted); font-size: .8rem; margin-left: .5rem; }
.entry p { margin: .3rem 0 0; }
.muted { color: var(--muted); }
/* post list (home widget + /blog) */
.posts-widget { margin: 2rem 0; }
.post-list { list-style: none; padding: 0; margin: 1rem 0; }
.post-list li {
display: flex;
justify-content: space-between;
align-items: baseline;
gap: 1rem;
padding: .6rem 0;
border-top: 1px solid var(--line);
}
.post-list .date { color: var(--muted); font-size: .85rem; white-space: nowrap; }
/* single post */
.back-link { margin: .5rem 0; }
.back-link a { border-bottom: none; color: var(--muted); }
.back-link a:hover { color: var(--fg); }
.post-title { margin-bottom: .2rem; }
.post-meta { color: var(--muted); font-size: .85rem; margin-bottom: 1.5rem; }
.post-body img {
max-width: 100%;
height: auto;
display: block;
margin: 1.5rem 0;
border-radius: 4px;
}
.post-body h1, .post-body h2, .post-body h3 { margin: 1.8rem 0 .6rem; }
.post-body h2 { color: var(--fg); font-size: 1.2rem; }
.post-body pre {
background: var(--field);
border: 1px solid var(--line);
border-radius: 4px;
padding: .8rem;
overflow-x: auto;
}
.post-body code {
background: var(--field);
padding: .1rem .3rem;
border-radius: 3px;
font-size: .9em;
}
.post-body pre code { background: none; padding: 0; }
.post-body blockquote {
border-left: 3px solid var(--line);
margin: 1rem 0;
padding-left: 1rem;
color: var(--muted);
}
/* ── side art ───────────────────────────────────────────────────────────
Full-height sakura in both margins: colored ASCII art (inc/art/left.html
and right.html, 104x88 characters), mirrored so the branches hang in from
the outer corners. Hidden when there's no margin. */
/* The art is drawn for .6em-wide characters; system monospaces range from
.5em up, which squashes it. So it gets its own: JetBrains Mono's printable
ASCII (OFL), about 4.5 KB. */
@font-face {
font-family: sideart;
src: url(sideart.woff2) format("woff2");
}
.side {
position: fixed;
top: 0;
z-index: -2;
margin: 0;
max-width: calc(50% - 360px);
overflow: hidden;
/* 88 rows at a 1.2 line fill the height */
font: calc(100vh / 105.6) / 1.2 sideart, monospace;
opacity: .85;
pointer-events: none;
user-select: none;
}
.side i { font-style: normal; }
.side-left { left: 0; }
/* rtl only so the right panel clips on its inner edge; the art itself stays
ltr, or the bidi algorithm reorders runs of punctuation */
.side-right { right: 0; direction: rtl; }
.side-right > span { direction: ltr; unicode-bidi: isolate; }
.side .a0 { color: #8c6068; }
.side .a1 { color: #a07076; }
.side .a2 { color: #ffb0cc; }
.side .a3 { color: #ff96be; }
.side .a4 { color: #f678ac; }
.side .a5 { color: #ffd4e4; }
.side .a6 { color: #e86098; }
.side .a7 { color: #ffecbe; }
/* the column's shadow: the art fades out under it instead of stopping dead
beside the text. Eased falloff, as wide as about a third of the margin. */
body::before {
content: "";
position: fixed;
inset: 0;
z-index: -1;
pointer-events: none;
--l: calc(50% - 340px);
--r: calc(50% + 340px);
--fade: clamp(60px, (100vw - 680px) * .16, 180px);
background: linear-gradient(90deg,
transparent calc(var(--l) - var(--fade)),
color-mix(in srgb, var(--bg) 22%, transparent) calc(var(--l) - var(--fade) * .75),
color-mix(in srgb, var(--bg) 55%, transparent) calc(var(--l) - var(--fade) * .5),
color-mix(in srgb, var(--bg) 85%, transparent) calc(var(--l) - var(--fade) * .25),
var(--bg) var(--l) var(--r),
color-mix(in srgb, var(--bg) 85%, transparent) calc(var(--r) + var(--fade) * .25),
color-mix(in srgb, var(--bg) 55%, transparent) calc(var(--r) + var(--fade) * .5),
color-mix(in srgb, var(--bg) 22%, transparent) calc(var(--r) + var(--fade) * .75),
transparent calc(var(--r) + var(--fade)));
}
@media (max-width: 1280px) {
.side, body::before { display: none; }
}
@media print, (forced-colors: active) {
.side, body::before { display: none; }
}
/* guestbook sign button */
.btn-sign {
display: inline-flex;
align-items: center;
gap: .5rem;
background: var(--fg);
color: var(--bg);
border: 1px solid var(--fg);
padding: .5rem 1.4rem;
border-radius: 4px;
font: inherit;
cursor: pointer;
transition: background .12s ease, color .12s ease, transform .08s ease;
}
.btn-sign .arrow { transition: transform .15s ease; }
.btn-sign:hover:not(:disabled) { background: transparent; color: var(--fg); }
.btn-sign:hover:not(:disabled) .arrow { transform: translateX(3px); }
.btn-sign:active:not(:disabled) { transform: translateY(1px); }
.btn-sign:focus-visible { outline: 2px solid var(--muted); outline-offset: 2px; }
.btn-sign:disabled { opacity: .55; cursor: progress; }
/* htmx swaps the label while the request is in flight */
.btn-sign .pending { display: none; }
.btn-sign.htmx-request .idle { display: none; }
.btn-sign.htmx-request .pending { display: inline; }
.btn-sign.htmx-request .arrow { display: none; }