i can't stop obsessing over the blog layout smdh

This commit is contained in:
haetae 2025-04-17 20:46:20 -04:00
parent dc3e9aa226
commit f673e3955d
14 changed files with 143 additions and 41 deletions

Binary file not shown.

Binary file not shown.

BIN
src/assets/buttons.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 254 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 252 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 252 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 255 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 255 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 255 B

View File

@ -10,8 +10,7 @@
--sans-font: "Super Star", 'Lucida Sans', 'Lucida Sans Regular', 'Lucida Grande', 'Lucida Sans Unicode', Geneva, Verdana, sans-serif; --sans-font: "Super Star", 'Lucida Sans', 'Lucida Sans Regular', 'Lucida Grande', 'Lucida Sans Unicode', Geneva, Verdana, sans-serif;
--arial-font: "Arial Pixel", Arial, Helvetica, sans-serif; --arial-font: "Arial Pixel", Arial, Helvetica, sans-serif;
--pmd-font: "Wonder Mail", Inter, Roboto, 'Helvetica Neue', 'Arial Nova', 'Nimbus Sans', Arial, sans-serif; --pmd-font: "Wonder Mail", Inter, Roboto, 'Helvetica Neue', 'Arial Nova', 'Nimbus Sans', Arial, sans-serif;
--mplus-10-font: "PixelMPlus 10", "MS Gothic", system-ui-ja, system-ui-zh-cn, system-ui-zh-tw, system-ui-zh-hk, system-ui-ko, sans-serif; --dotum-font: "DotumChe", "Dotum", system-ui-ko, system-ui-ja, system-ui-zh-cn, system-ui-zh-tw, system-ui-zh-hk, monospace, sans-serif;
--mplus-12-font: "PixelMPlus 12", "MS Gothic", system-ui-ja, system-ui-zh-cn, system-ui-zh-tw, system-ui-zh-hk, system-ui-ko, sans-serif;
@media screen and (prefers-color-scheme: light) { @media screen and (prefers-color-scheme: light) {
--bg-color: #e6f2ef; --bg-color: #e6f2ef;

View File

@ -2,12 +2,14 @@
font-family: "Arial Pixel"; font-family: "Arial Pixel";
src: url("/fonts/pixearg.woff2") format("woff2"); src: url("/fonts/pixearg.woff2") format("woff2");
font-weight: normal; font-weight: normal;
font-display: fallback;
} }
@font-face { @font-face {
font-family: "Arial Pixel"; font-family: "Arial Pixel";
src: url("/fonts/pixeab.woff2") format("woff2"); src: url("/fonts/pixeab.woff2") format("woff2");
font-weight: bold; font-weight: bold;
font-display: fallback;
} }
@font-face { @font-face {
@ -16,6 +18,18 @@
font-weight: normal; font-weight: normal;
} }
@font-face {
font-family: "Dotum";
src: url("/fonts/dotum-Regular.woff2") format("woff2");
font-weight: normal;
}
@font-face {
font-family: "DotumChe";
src: url("/fonts/dotumche-Regular.woff2") format("woff2");
font-weight: normal;
}
@font-face { @font-face {
font-family: "Kiwi Soda"; font-family: "Kiwi Soda";
src: url("/fonts/KiwiSoda.woff2") format("woff2"); src: url("/fonts/KiwiSoda.woff2") format("woff2");

View File

@ -26,10 +26,17 @@ const { title, date, currently } = Astro.props;
const blog = await getCollection("blog"); const blog = await getCollection("blog");
blog.length = Math.min(blog.length, 12); blog.length = Math.min(blog.length, 12);
blog.sort((a, b) => a.data.pubDate!.valueOf() - b.data.pubDate!.valueOf()); blog.sort((a, b) => b.data.pubDate!.valueOf() - a.data.pubDate!.valueOf());
--- ---
<Layout {title}> <Layout {title}>
<slot slot="head" name="head" /> <Fragment slot="head">
<link rel="preload" href={outerBBS.src} as="image" />
<link rel="preload" href={innerBBS.src} as="image" />
<link rel="preload" href={sideBBS.src} as="image" />
<link rel="preload" href="/fonts/pixearg.woff2" as="font" />
<link rel="preload" href="/fonts/pixeab.woff2" as="font" />
<slot name="head" />
</Fragment>
<Navbar /> <Navbar />
<main> <main>
@ -143,15 +150,19 @@ blog.sort((a, b) => a.data.pubDate!.valueOf() - b.data.pubDate!.valueOf());
--border-4: #88aabb; --border-4: #88aabb;
--border-5: #99bbcc; --border-5: #99bbcc;
--border-6: #bbccdd; --border-6: #bbccdd;
--normal-color: #335577;
--active-color: #aa0033;
--active-border: #442266;
color: #000; color: #000;
} }
h1 { font: bold 1rem var(--arial-font); } h1 { font: bold 1rem var(--arial-font); }
h2 { h2 {
font: normal 1.5rem var(--mplus-12-font); font: normal 1rem var(--dotum-font);
text-transform: uppercase; text-transform: uppercase;
} }
main { main {
font: 1rem var(--arial-font); font: 1rem var(--arial-font);
letter-spacing: 1px;
display: grid; display: grid;
grid-template-columns: auto minmax(auto, 75ch); grid-template-columns: auto minmax(auto, 75ch);
justify-content: center; justify-content: center;
@ -211,8 +222,7 @@ blog.sort((a, b) => a.data.pubDate!.valueOf() - b.data.pubDate!.valueOf());
.item { .item {
position: relative; position: relative;
font-family: var(--mplus-10-font); font: bold 1em var(--dotum-font);
font-size: 1.25rem; /* this should be 20px */
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
align-items: center; align-items: center;
@ -225,6 +235,17 @@ blog.sort((a, b) => a.data.pubDate!.valueOf() - b.data.pubDate!.valueOf());
left: 0; left: 0;
width: 100%; width: 100%;
height: 100%; height: 100%;
~ .link {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
/* max-width: 19ch; */
@media screen and (max-width: 76em) {
max-width: unset;
}
}
} }
} }
@ -269,7 +290,6 @@ blog.sort((a, b) => a.data.pubDate!.valueOf() - b.data.pubDate!.valueOf());
article { article {
display: flex; display: flex;
letter-spacing: 1px;
border: 2px solid var(--border-0); border: 2px solid var(--border-0);
border-image: var(--outerBorder) 19 9 38 11 fill / 38px 18px 76px 22px; border-image: var(--outerBorder) 19 9 38 11 fill / 38px 18px 76px 22px;
background-color: var(--bg-3); background-color: var(--bg-3);
@ -286,7 +306,9 @@ blog.sort((a, b) => a.data.pubDate!.valueOf() - b.data.pubDate!.valueOf());
} }
.title { .title {
font: normal 1.5rem var(--mplus-12-font); display: grid;
place-content: center;
font: normal 1.25em var(--dotum-font);
background-color: var(--bg-2); background-color: var(--bg-2);
padding: 2px 6px; padding: 2px 6px;
} }
@ -316,9 +338,10 @@ blog.sort((a, b) => a.data.pubDate!.valueOf() - b.data.pubDate!.valueOf());
border-color: var(--bg-2) var(--bg-2) var(--bg-1) var(--bg-1); border-color: var(--bg-2) var(--bg-2) var(--bg-1) var(--bg-1);
padding: 2px 4px; padding: 2px 4px;
time, .section { time {
display: flex; display: flex;
width: 100%; width: 100%;
align-items: stretch;
} }
} }
@ -345,6 +368,19 @@ blog.sort((a, b) => a.data.pubDate!.valueOf() - b.data.pubDate!.valueOf());
p { margin-block: 1lh; } p { margin-block: 1lh; }
a, del, s { text-decoration-thickness: 2px; } a, del, s { text-decoration-thickness: 2px; }
a {
color: var(--normal-color);
&:visited {
color: var(--active-border);
}
&:hover {
color: var(--active-color);
}
&:active, &:focus {
color: var(--normal-color);
}
}
@supports not (margin-trim: block) { @supports not (margin-trim: block) {
:first-child { margin-block-start: 0; } :first-child { margin-block-start: 0; }

View File

@ -2,13 +2,7 @@
import Blog from '@/layouts/Blog.astro'; import Blog from '@/layouts/Blog.astro';
import type { GetStaticPaths } from 'astro'; import type { GetStaticPaths } from 'astro';
import { getCollection, render } from 'astro:content'; import { getCollection, render } from 'astro:content';
import buttons from "$/buttons.png";
import leftNormal from "$/left-normal.png";
import leftHover from "$/left-hover.png";
import leftActive from "$/left-active.png";
import rightNormal from "$/right-normal.png";
import rightHover from "$/right-hover.png";
import rightActive from "$/right-active.png";
export const getStaticPaths = (async () => { export const getStaticPaths = (async () => {
const blog = await getCollection("blog"); const blog = await getCollection("blog");
@ -30,30 +24,37 @@ const next = current === 0 ? undefined : blog[current - 1];
<Blog title={entry.data.title!} date={entry.data.pubDate!} currently={entry.data.currently}> <Blog title={entry.data.title!} date={entry.data.pubDate!} currently={entry.data.currently}>
<Fragment slot="head"> <Fragment slot="head">
<meta name="description" content={entry.body?.substring(0, 150) + "…"}> <meta name="description" content={entry.body?.substring(0, 150) + "…"}>
<link rel="preload" href={buttons.src} as="image" />
</Fragment> </Fragment>
<Content /> <Content />
{(previous || next) && ( {(previous || next) && (
<div id="blog-pagination" slot="pagination"> <footer id="blog-pagination" slot="pagination">
{previous && ( {previous && (
<a id="previous" aria-label="previous post" href={`/blog/${previous.id}`}> <a id="previous" aria-label="go to previous post" href={`/blog/${previous.id}`}>
<img class="arrow" src={leftNormal.src} alt="" /> <div class="arrow" />
{previous.data.title} <div class="title">
<span>{previous.data.title}</span>
</div>
</a> </a>
)} )}
{next && ( {next && (
<a id="next" aria-label="next post" href={`/blog/${next.id}`}> <a id="next" aria-label="go to next post" href={`/blog/${next.id}`}>
{next.data.title} <div class="title">
<img class="arrow" src={rightNormal.src} alt="" /> <span>{next.data.title}</span>
</div>
<div class="arrow" />
</a> </a>
)} )}
</div> </footer>
)} )}
</Blog> </Blog>
<style define:vars={{ leftNormal: `url(${leftNormal.src})`, leftHover: `url(${leftHover.src})`, leftActive: `url(${leftActive.src})`, rightNormal: `url(${rightNormal.src})`, rightHover: `url(${rightHover.src})`, rightActive: `url(${rightActive.src})` }}> <style define:vars={{ buttons: `url(${buttons.src})` }}>
#blog-pagination { #blog-pagination {
margin: 1rem 0;
display: grid; display: grid;
grid-column: 1 / -1; grid-column: 1 / -1;
grid-template-columns: repeat(2, 1fr); grid-template-columns: repeat(2, 1fr);
@ -61,33 +62,87 @@ const next = current === 0 ? undefined : blog[current - 1];
.arrow { .arrow {
width: 36px; width: 36px;
height: 50px; height: 50px;
background: var(--buttons) no-repeat top left;
} }
#previous { #previous {
grid-column: 1 / 2; grid-column: 1 / 2;
justify-self: left; justify-self: left;
.arrow { content: var(--leftNormal) var(--leftHover) var(--leftActive); } .arrow { background-position: 0 0; }
&:hover .arrow { content: var(--leftHover); } &:hover .arrow { background-position: -36px 0; }
&:active .arrow, &:focus .arrow { content: var(--leftActive); } &:active .arrow, &:focus .arrow { background-position: -72px 0; }
.title {
border-left: none;
margin-left: -2px;
padding-left: calc(0.5em + 2px);
}
} }
#next { #next {
grid-column: 2 / -1; grid-column: 2 / -1;
justify-self: right; justify-self: right;
.arrow { content: var(--rightNormal) var(--rightHover) var(--rightActive); } .arrow { background-position: -108px 0; }
&:hover .arrow { content: var(--rightHover); } &:hover .arrow { background-position: -144px 0; }
&:active .arrow, &:focus .arrow { content: var(--rightActive); } &:active .arrow, &:focus .arrow { background-position: -180px 0; }
.title {
position: relative;
z-index: 1;
border-right: none;
margin-right: -2px;
padding-right: calc(0.5em + 2px);
}
} }
a { a {
display: flex; display: flex;
flex-flow: row wrap; flex-flow: row wrap;
align-items: center; align-items: stretch;
gap: 2px; font: bold larger var(--dotum-font);
color: var(--bg-0); color: var(--normal-color);
text-decoration: none; text-decoration: none;
.title {
display: grid;
place-content: center;
padding: 0 0.5em;
background-color: var(--bg-7);
border: 2px solid var(--border-1);
box-shadow:
inset 2px 2px 0 0 var(--bg-0),
inset 4px 4px 0 0 var(--bg-5),
inset -2px -2px 0 0 var(--border-5),
inset -4px -4px 0 0 var(--border-6);
@media screen and (468px > width) {
> span {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
max-width: calc(12ch + 1em);
}
}
}
&:hover {
color: var(--active-color);
.title { border-color: var(--active-border); }
}
&:active, &:focus {
color: var(--normal-color);
.title {
border-color: var(--border-1);
box-shadow:
inset -2px -2px 0 0 var(--bg-0),
inset -4px -4px 0 0 var(--bg-5),
inset 2px 2px 0 0 var(--border-5),
inset 4px 4px 0 0 var(--border-6);
}
}
} }
} }
</style> </style>

View File

@ -1,16 +1,14 @@
--- ---
import Layout from "@/layouts/Layout.astro"; import Layout from "@/layouts/Layout.astro";
import formatDate from "@/utils/formatDate";
import { getCollection } from "astro:content"; import { getCollection } from "astro:content";
import dayjs from "dayjs"; import dayjs from "dayjs";
import utc from "dayjs/plugin/utc";
const blog = await getCollection("blog"); const blog = await getCollection("blog");
const sorted = Object.groupBy(blog, ({ data }) => data.pubDate!.getMonth()); const sorted = Object.groupBy(blog, ({ data }) => data.pubDate!.getMonth());
dayjs.extend(utc); function getMonth(id: number): string {
const getMonth = (id: number) => {
let date = new Date(); let date = new Date();
date.setDate(1);
date.setMonth(id); date.setMonth(id);
return dayjs(date).format("MMMM"); return dayjs(date).format("MMMM");
} }
@ -27,8 +25,8 @@ const getMonth = (id: number) => {
<ul> <ul>
{entry[1]?.sort((a, b) => a.data.pubDate!.valueOf() - b.data.pubDate!.valueOf()).map(post => ( {entry[1]?.sort((a, b) => a.data.pubDate!.valueOf() - b.data.pubDate!.valueOf()).map(post => (
<li> <li>
<time datetime={dayjs(post.data.pubDate).utc(true).toISOString()}> <time datetime={formatDate(post.data.pubDate!, true)}>
{dayjs(post.data.pubDate).utc(true).format("MMMM DD, YYYY")} {formatDate(post.data.pubDate!)}
</time> </time>
<a href={`/blog/${post.id}`}>{post.data.title}</a> <a href={`/blog/${post.id}`}>{post.data.title}</a>
</li> </li>