Files
youhavetrouble.github.io/src/pages/index.astro
T

336 lines
7.8 KiB
Plaintext

---
import BaseLayout from '../layouts/BaseLayout.astro';
import {getCollection} from "astro:content";
import logoImage from '../assets/img/yht_logo.png';
import {Image} from 'astro:assets';
import ActivityWidget from "../components/ActivityWidget.astro";
import ViewCounter from "../components/ViewCounter.astro";
const title = 'Home';
const description = 'My little corner of the internet.';
const permalink = Astro?.site?.href ?? '/';
const latestBlogPost = await getCollection("posts")
.then(posts => posts.sort(
(a, b) => new Date(b.data.publishDate).getTime() - new Date(a.data.publishDate).getTime()
)
).then(sortedBlogPosts => sortedBlogPosts.length > 0 ? sortedBlogPosts[0] : null);
---
<BaseLayout
title={title}
description={description}
permalink={permalink}
showLogo={false}
>
<div class="hero">
<div class="thought-bubble">
<div class="thoughts">
<div class="latest-blogpost">
{
latestBlogPost ? (
<span>Latest blog post:</span>
<a href={`/blog/${latestBlogPost.slug}`} style={`view-transition-name: blogpost-${latestBlogPost.slug}`}>
{latestBlogPost.data.title}
</a>
) : (
<span>No blog posts yet.</span>
)
}
</div>
<div class="visitor-count">
<ViewCounter />
</div>
</div>
<div class="thoughts-list">
<label>
<input
type="radio"
name="thoughts"
id="latest-blogpost"
aria-label="Latest blog post"
checked
/>
</label>
<label>
<input
type="radio"
name="thoughts"
id="visitor-count"
aria-label="Activity"
/>
</label>
</div>
</div>
<div class="hero-body">
<div class="hero-nav">
<a class="option about" href="/about">About</a>
<a class="option projects" href="/projects">Projects</a>
<a class="option blog" href="/blog">Blog</a>
</div>
<Image
src={logoImage}
alt="Logo displaying a stylized character with brown hair wearing purple hoodie on a light blue circle background"
width={150}
height={150}
loading="eager"
class="main-logo"
draggable="false"
/>
</div>
</div>
</BaseLayout>
<style lang="scss">
.hero {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
flex: 1;
container-type: inline-size;
container-name: hero;
.hero-body {
display: flex;
justify-content: center;
flex-direction: column-reverse;
width: 100%;
align-items: center;
gap: 0.5rem;
position: relative;
z-index: 1;
}
.hero-nav {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
gap: 0.5rem;
width: 100%;
.option {
border-width: 1px;
border-style: solid;
border-color: var(--text-main);
display: flex;
justify-content: center;
align-items: center;
font-size: 0.8rem;
text-decoration: none;
padding: 0.5rem;
width: 100%;
border-radius: 1rem;
background-color: var(--background-body);
&.about {
view-transition-name: about;
}
&.projects {
view-transition-name: projects;
}
&.blog {
view-transition-name: blog;
}
}
}
.thought-bubble {
position: relative;
width: min(100%, 15rem);
min-height: 5rem;
background-color: var(--text-main);
margin-bottom: 0.75rem;
border-radius: 1rem;
border: 2px solid black;
opacity: 0;
z-index: 5;
animation: fadeIn 1s linear forwards;
animation-delay: 0.25s;
&:has(input#latest-blogpost:checked) {
.thoughts {
.latest-blogpost {
display: flex;
}
}
}
&:has(input#visitor-count:checked) {
.thoughts {
.visitor-count {
display: flex;
}
}
}
.thoughts {
display: flex;
flex-direction: row;
height: 5rem;
& > * {
display: none;
}
.latest-blogpost {
flex-direction: column;
justify-content: center;
align-items: center;
width: 100%;
height: 100%;
color: var(--background-body);
a {
color: var(--background-body);
text-decoration: underline;
}
}
.visitor-count {
width: 100%;
height: 100%;
justify-content: center;
align-items: center;
color: var(--background-body)
}
.activity {
overflow: hidden;
}
}
.thoughts-list {
display: flex;
flex-direction: row;
justify-content: center;
gap: 0.5rem;
}
&::before {
position: absolute;
content: '';
bottom: -2.25rem;
right: 25%;
width: 2rem;
height: 2rem;
background-color: var(--text-main);
border: 2px solid black;
border-radius: 50%;
z-index: 5;
}
&::after {
position: absolute;
content: '';
bottom: -3.25rem;
right: 33%;
width: 1rem;
height: 1rem;
background-color: var(--text-main);
border: 2px solid black;
border-radius: 50%;
z-index: 5;
}
}
@container hero (width >= 320px) {
.hero-body {
flex-direction: row;
}
.hero-nav {
animation-name: animateNavIn;
animation-duration: 0.5s;
animation-fill-mode: forwards;
animation-delay: 0.1s;
position: absolute;
opacity: 0;
.option {
position: absolute;
width: 4rem;
height: 4rem;
border-radius: 50%;
&.about {
animation-name: animateNavAboutIn;
animation-duration: 0.75s;
animation-fill-mode: forwards;
animation-delay: 0.25s;
}
&.blog {
animation-name: animateNavBlogIn;
animation-duration: 0.75s;
animation-fill-mode: forwards;
animation-delay: 0.25s;
}
}
}
}
}
.main-logo {
border-radius: 50%;
view-transition-name: nav-logo;
}
@keyframes animateNavIn {
0% {
bottom: 50%;
left: auto;
right: auto;
opacity: 0;
}
100% {
left: auto;
right: auto;
bottom: -2.5rem;
opacity: 1;
}
}
@keyframes animateNavBlogIn {
0% {
transform: translateX(0) translateY(0);
}
100% {
transform: translateX(calc(100% + 0.25rem)) translateY(-1.5rem);
}
}
@keyframes animateNavAboutIn {
0% {
transform: translateX(0) translateY(0);
}
100% {
transform: translateX(calc(-100% - 0.25rem)) translateY(-1.5rem);
}
}
@keyframes fadeIn {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
</style>