mirror of
https://github.com/YouHaveTrouble/youhavetrouble.github.io.git
synced 2026-05-12 06:16:55 +00:00
lean more into transitions and animations
This commit is contained in:
+283
-221
@@ -1,272 +1,334 @@
|
||||
---
|
||||
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";
|
||||
import SocialsWidget from "../components/SocialsWidget.astro";
|
||||
import ProjectsFeature from "../components/ProjectsFeature.astro";
|
||||
import {getCollection} from "astro:content";
|
||||
|
||||
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);
|
||||
.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}>
|
||||
<div class="home-container">
|
||||
<div class="window home-copy" data-title="Welcome" id="welcome">
|
||||
<div>
|
||||
<h1>Welcome to my little corner of the interwebs</h1>
|
||||
<p>Feel free to check out what I got in store!</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="window-row">
|
||||
<div class="window visitor-counter" data-title="Visitors counter" id="visitor-counter"
|
||||
aria-label="Visitors counter">
|
||||
<ViewCounter/>
|
||||
</div>
|
||||
<div class="window activity" data-title="Activity" id="activity" aria-label="Activity">
|
||||
<ActivityWidget/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="window-row">
|
||||
<div class="window socials" data-title="Socials" id="socials" aria-label="Socials">
|
||||
<SocialsWidget/>
|
||||
</div>
|
||||
<div class="window blog" aria-label="Blog" id="blog" data-title="Blog">
|
||||
<span>Latest article:</span>
|
||||
{
|
||||
latestBlogPost === null ? (
|
||||
<div class="latest-article">
|
||||
<span class="title">No articles yet</span>
|
||||
<span class="excerpt">Come back later to check for new articles!</span>
|
||||
</div>
|
||||
) : null
|
||||
}
|
||||
<div class="latest-article">
|
||||
<span class="title">{latestBlogPost?.data.title}</span>
|
||||
<span class="excerpt">{latestBlogPost?.data.description}</span>
|
||||
<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="actions">
|
||||
{
|
||||
latestBlogPost !== null && (
|
||||
<a href={`/blog/${latestBlogPost?.slug}`} class="button">Read more</a>
|
||||
<a href="/blog" class="button secondary">All articles</a>
|
||||
)
|
||||
}
|
||||
</div>
|
||||
<div class="buttons">
|
||||
<div class="rss">
|
||||
<a
|
||||
href="/rss.xml"
|
||||
target="_blank"
|
||||
aria-label="RSS feed"
|
||||
title="RSS feed"
|
||||
>
|
||||
<svg height="14px" width="14px" xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="-271 273 256 256" xml:space="preserve">
|
||||
<g>
|
||||
<path fill="white" d="M-271,360v48.9c31.9,0,62.1,12.6,84.7,35.2c22.6,22.6,35.1,52.8,35.1,84.8v0.1h49.1c0-46.6-19-88.7-49.6-119.4
|
||||
C-182.2,379-224.4,360.1-271,360z"/>
|
||||
<path fill="white" d="M-237,460.9c-9.4,0-17.8,3.8-24,10s-10,14.6-10,24c0,9.3,3.8,17.7,10,23.9c6.2,6.1,14.6,9.9,24,9.9s17.8-3.7,24-9.9
|
||||
s10-14.6,10-23.9c0-9.4-3.8-17.8-10-24C-219.2,464.7-227.6,460.9-237,460.9z"/>
|
||||
<path fill="white" d="M-90.1,348.1c-46.3-46.4-110.2-75.1-180.8-75.1v48.9C-156.8,322-64.1,414.9-64,529h49C-15,458.4-43.7,394.5-90.1,348.1z"/>
|
||||
</g>
|
||||
</svg>
|
||||
</a>
|
||||
</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>
|
||||
</div>
|
||||
<div class="window-row">
|
||||
<div class="window" data-title="Projects" id="projects" aria-label="Projects">
|
||||
<div class="buttons">
|
||||
<button popovertarget="projects-info" popovertargetaction="show" tabindex="0" aria-label="Projects info">
|
||||
<span class="icon">ℹ️</span>
|
||||
</button>
|
||||
</div>
|
||||
<div popover="auto" id="projects-info" class="window">
|
||||
<div class="buttons">
|
||||
<button popovertarget="projects-info" popovertargetaction="hide" tabindex="0"
|
||||
aria-label="Close projects info">
|
||||
<span class="icon">❌</span>
|
||||
</button>
|
||||
</div>
|
||||
<h2>Projects</h2>
|
||||
<p>
|
||||
Here are some of the projects I'm working on. Most of them are open source, so feel free to check them out!
|
||||
<br>
|
||||
Projects presented here are what I consider in presentable and/or finished state. They might or might not
|
||||
get
|
||||
updates.
|
||||
<br>
|
||||
Most logos generated using <a href="https://huggingface.co/spaces/dalle-mini/dalle-mini" target="_blank">DALL-E
|
||||
mini</a>.
|
||||
<br>
|
||||
Inviter logo by <a href="https://slyfoxart.artstation.com/projects" target="_blank">SlyFox</a>
|
||||
</p>
|
||||
</div>
|
||||
<ProjectsFeature/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</BaseLayout>
|
||||
|
||||
<style lang="scss">
|
||||
|
||||
#projects-info {
|
||||
position: fixed;
|
||||
}
|
||||
|
||||
.visitor-counter {
|
||||
padding: 1.5rem 2rem 0 2rem;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
min-width: min(15rem, 100%);
|
||||
flex: 1;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.socials {
|
||||
padding: 2rem 1rem 0 1rem;
|
||||
flex: 2;
|
||||
min-width: min(25rem, 100%);
|
||||
}
|
||||
|
||||
.activity {
|
||||
min-width: min(100%, 16rem);
|
||||
flex: 2;
|
||||
}
|
||||
|
||||
#projects {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex: 1;
|
||||
padding-top: 1.5rem;
|
||||
}
|
||||
|
||||
.blog {
|
||||
padding: 2rem 1rem 0.75rem 1rem;
|
||||
.hero {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
min-width: min(25rem, 100%);
|
||||
width: 100%;
|
||||
gap: 0.5rem;
|
||||
flex: 1;
|
||||
container-type: inline-size;
|
||||
container-name: hero;
|
||||
|
||||
.latest-article {
|
||||
.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;
|
||||
align-items: center;
|
||||
text-align: center;
|
||||
margin-bottom: 0.5rem;
|
||||
background: rgba(255,255,255, 0.05);
|
||||
padding: 0.5rem;
|
||||
border-radius: 0.25rem;
|
||||
|
||||
.title {
|
||||
font-weight: 600;
|
||||
font-size: 1.1rem;
|
||||
view-transition-name: blog-title;
|
||||
}
|
||||
|
||||
.excerpt {
|
||||
font-size: 0.9rem;
|
||||
color: var(--text-secondary);
|
||||
}
|
||||
}
|
||||
|
||||
.actions {
|
||||
display: flex;
|
||||
gap: 0.5rem;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.buttons {
|
||||
.rss {
|
||||
display: flex;
|
||||
height: 100%;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
aspect-ratio: 1/1;
|
||||
padding-bottom: 4px;
|
||||
a {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
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);
|
||||
|
||||
.window-row {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
gap: 1.5rem;
|
||||
width: 100%;
|
||||
justify-content: center;
|
||||
}
|
||||
&.about {
|
||||
view-transition-name: about;
|
||||
}
|
||||
|
||||
.home-container {
|
||||
align-items: center;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
margin: 2em 0;
|
||||
gap: 1.5rem;
|
||||
&.projects {
|
||||
view-transition-name: projects;
|
||||
}
|
||||
|
||||
.home-copy {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
width: 100%;
|
||||
padding-top: 3rem;
|
||||
padding-inline: 0.5rem;
|
||||
|
||||
h1 {
|
||||
font-weight: 700;
|
||||
margin-bottom: 0.5em;
|
||||
line-height: 1.3;
|
||||
font-size: 2rem;
|
||||
text-align: center;
|
||||
&.blog {
|
||||
view-transition-name: blog;
|
||||
}
|
||||
}
|
||||
|
||||
p {
|
||||
text-align: center;
|
||||
font-size: 1.2rem;
|
||||
}
|
||||
|
||||
.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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@media (max-width: 1200px) {
|
||||
p {
|
||||
font-size: 1.2em;
|
||||
.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);
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 800px) {
|
||||
.home-container {
|
||||
flex-direction: column;
|
||||
@keyframes animateNavAboutIn {
|
||||
0% {
|
||||
transform: translateX(0) translateY(0);
|
||||
}
|
||||
100% {
|
||||
transform: translateX(calc(-100% - 0.25rem)) translateY(-1.5rem);
|
||||
}
|
||||
}
|
||||
|
||||
.home-copy {
|
||||
flex: 0;
|
||||
padding-bottom: 2em;
|
||||
text-align: center;
|
||||
@keyframes fadeIn {
|
||||
0% {
|
||||
opacity: 0;
|
||||
}
|
||||
100% {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user