mirror of
https://github.com/YouHaveTrouble/youhavetrouble.github.io.git
synced 2026-05-11 22:06:56 +00:00
nicer project showcase
This commit is contained in:
@@ -5,21 +5,12 @@ const projects = await getCollection('projects');
|
|||||||
projects.sort((a, b) => a.data.name.localeCompare(b.data.name));
|
projects.sort((a, b) => a.data.name.localeCompare(b.data.name));
|
||||||
---
|
---
|
||||||
<section id="projects">
|
<section id="projects">
|
||||||
<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>.
|
|
||||||
</p>
|
|
||||||
<div class="showcase">
|
<div class="showcase">
|
||||||
{
|
{
|
||||||
projects.map((project, index) => {
|
projects.map((project, index) => {
|
||||||
return (
|
return (
|
||||||
<article class="project">
|
<button class="project" popovertarget={`project-${[index]}`} popovertargetaction="show" aria-label={`Project details: ${project.data.name}`}>
|
||||||
<div class="icon">
|
<span class="icon">
|
||||||
<img
|
<img
|
||||||
src={project.data.image}
|
src={project.data.image}
|
||||||
alt=""
|
alt=""
|
||||||
@@ -28,12 +19,29 @@ projects.sort((a, b) => a.data.name.localeCompare(b.data.name));
|
|||||||
decoding="async"
|
decoding="async"
|
||||||
draggable="false"
|
draggable="false"
|
||||||
/>
|
/>
|
||||||
|
</span>
|
||||||
|
<span class="description">
|
||||||
|
<span>{project.data.name}</span>
|
||||||
|
</span>
|
||||||
|
</button>
|
||||||
|
<div popover id={`project-${[index]}`} class="window popup" aria-label={`Details about ${project.data.name}`} data-title={project.data.name}>
|
||||||
|
<div class="buttons">
|
||||||
|
<button popovertarget={`project-${[index]}`} popovertargetaction="hide" aria-label="Close project details">
|
||||||
|
<span class="icon">❌</span>
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="description">
|
<span class="icon">
|
||||||
<h3>{project.data.name}</h3>
|
<img
|
||||||
|
src={project.data.image}
|
||||||
|
alt=""
|
||||||
|
aria-hidden="true"
|
||||||
|
loading={index > 4 ? "lazy" : "eager"}
|
||||||
|
decoding="async"
|
||||||
|
draggable="false"
|
||||||
|
/>
|
||||||
|
</span>
|
||||||
<span>{project.data.description}</span>
|
<span>{project.data.description}</span>
|
||||||
</div>
|
<span class="links">
|
||||||
<div class="links">
|
|
||||||
{
|
{
|
||||||
project.data.links.map((link) => {
|
project.data.links.map((link) => {
|
||||||
return (
|
return (
|
||||||
@@ -43,8 +51,8 @@ projects.sort((a, b) => a.data.name.localeCompare(b.data.name));
|
|||||||
)
|
)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</article>
|
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -59,16 +67,37 @@ projects.sort((a, b) => a.data.name.localeCompare(b.data.name));
|
|||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: 1.5rem;
|
gap: 1.5rem;
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.popup {
|
||||||
|
position: fixed;
|
||||||
|
padding-top: 2.5rem;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
gap: 1.5rem;
|
||||||
|
width: min(40rem, 100%);
|
||||||
|
&:popover-open {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.showcase {
|
.showcase {
|
||||||
display: flex;
|
display: grid;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
overflow-x: scroll;
|
grid-template-columns: repeat(auto-fill, 10rem);
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
gap: 0.75rem;
|
gap: 0.75rem;
|
||||||
scroll-snap-type: x mandatory;
|
scroll-snap-type: x mandatory;
|
||||||
padding-block: 0.25rem;
|
padding-block: 1.5rem;
|
||||||
|
justify-content: center;
|
||||||
|
padding-inline: 0.5rem;
|
||||||
|
grid-row-gap: 1.5rem;
|
||||||
|
|
||||||
|
h3 {
|
||||||
|
font-size: 1rem;
|
||||||
|
font-weight: 300;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.project {
|
.project {
|
||||||
@@ -77,18 +106,26 @@ projects.sort((a, b) => a.data.name.localeCompare(b.data.name));
|
|||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
text-align: start;
|
text-align: start;
|
||||||
padding-block: 0.5rem;
|
|
||||||
padding-inline: 1rem;
|
|
||||||
border-radius: 0.25rem;
|
border-radius: 0.25rem;
|
||||||
background-color: #313131;
|
width: 100%;
|
||||||
min-width: min(20rem, calc(100% - 1.5rem));
|
|
||||||
max-width: min(20rem, calc(100% - 1.5rem));
|
|
||||||
scroll-snap-align: start;
|
scroll-snap-align: start;
|
||||||
|
color: #cccccc;
|
||||||
|
font-size: 1rem;
|
||||||
|
gap: 0.25rem;
|
||||||
|
padding: 0.25rem;
|
||||||
|
&:focus-within {
|
||||||
|
background-color: #548e9b;
|
||||||
|
}
|
||||||
|
&:focus-visible {
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.icon {
|
.icon {
|
||||||
width: 4rem;
|
width: 4rem;
|
||||||
height: 4rem;
|
height: 4rem;
|
||||||
border-radius: 0.25rem;
|
border-radius: 0.25rem;
|
||||||
|
|
||||||
img {
|
img {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
@@ -102,7 +139,6 @@ projects.sort((a, b) => a.data.name.localeCompare(b.data.name));
|
|||||||
gap: 0.5rem;
|
gap: 0.5rem;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
flex: 1 1;
|
flex: 1 1;
|
||||||
padding-block: 0.5rem;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.links {
|
.links {
|
||||||
@@ -113,11 +149,11 @@ projects.sort((a, b) => a.data.name.localeCompare(b.data.name));
|
|||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
gap: 0.5rem;
|
gap: 0.5rem;
|
||||||
line-height: 1;
|
line-height: 1;
|
||||||
|
|
||||||
a {
|
a {
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
@media screen and (max-width: 800px) {
|
@media screen and (max-width: 800px) {
|
||||||
.showcase {
|
.showcase {
|
||||||
|
|||||||
+41
-26
@@ -12,56 +12,64 @@ const permalink = Astro?.site?.href ?? '/';
|
|||||||
|
|
||||||
<BaseLayout title={title} description={description} permalink={permalink}>
|
<BaseLayout title={title} description={description} permalink={permalink}>
|
||||||
<div class="home-container">
|
<div class="home-container">
|
||||||
<div class="window home-copy" data-title="Welcome">
|
<div class="window home-copy" data-title="Welcome" id="welcome">
|
||||||
<div>
|
<div>
|
||||||
<h1>Welcome to my little corner of the interwebs</h1>
|
<h1>Welcome to my little corner of the interwebs</h1>
|
||||||
<p>Feel free to check out what I got in store!</p>
|
<p>Feel free to check out what I got in store!</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="window-row">
|
<div class="window-row">
|
||||||
<div class="window visitor-counter" data-title="Visitors counter" aria-label="Visitors counter">
|
<div class="window visitor-counter" data-title="Visitors counter" id="visitor-counter" aria-label="Visitors counter">
|
||||||
<ViewCounter />
|
<ViewCounter />
|
||||||
</div>
|
</div>
|
||||||
<div class="window activity" data-title="Activity" aria-label="Activity">
|
<div class="window activity" data-title="Activity" id="activity" aria-label="Activity">
|
||||||
<ActivityWidget />
|
<ActivityWidget />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="window-row">
|
<div class="window-row">
|
||||||
<div class="window socials" data-title="Socials" aria-label="Socials">
|
<div class="window socials" data-title="Socials" id="socials" aria-label="Socials">
|
||||||
<SocialsWidget />
|
<SocialsWidget />
|
||||||
</div>
|
</div>
|
||||||
<div class="window blog" aria-label="Blog" data-title="Blog">
|
<div class="window blog" aria-label="Blog" id="blog" data-title="Blog">
|
||||||
<a href="/blog">I have a blog btw!</a>
|
<a href="/blog">I have a blog btw!</a>
|
||||||
<a href="/rss.xml" target="_blank">It also has an RSS feed!</a>
|
<a href="/rss.xml" target="_blank">It also has an RSS feed!</a>
|
||||||
</div>
|
</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" 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" 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>.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
<ProjectsFeature />
|
<ProjectsFeature />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</BaseLayout>
|
</BaseLayout>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
|
|
||||||
.window {
|
#projects-info {
|
||||||
border: 2px solid #d0d0d0;
|
position: fixed;
|
||||||
border-radius: 0.5rem;
|
|
||||||
flex-direction: column;
|
|
||||||
position: relative;
|
|
||||||
overflow-y: hidden;
|
|
||||||
padding-top: 1.5rem;
|
|
||||||
min-width: 10rem;
|
|
||||||
&::before {
|
|
||||||
content: attr(data-title);
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
height: 1.5rem;
|
|
||||||
width: 100%;
|
|
||||||
border-bottom: #d0d0d0 solid 2px;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: row;
|
|
||||||
padding-inline: 0.5rem;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.visitor-counter {
|
.visitor-counter {
|
||||||
@@ -85,6 +93,13 @@ const permalink = Astro?.site?.href ?? '/';
|
|||||||
flex: 2;
|
flex: 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#projects {
|
||||||
|
width: 100%;
|
||||||
|
display: flex;
|
||||||
|
flex: 1;
|
||||||
|
padding-top: 1.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
.blog {
|
.blog {
|
||||||
padding: 2rem 1rem 0 1rem;
|
padding: 2rem 1rem 0 1rem;
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|||||||
@@ -15,6 +15,32 @@
|
|||||||
html {
|
html {
|
||||||
overflow-y: scroll;
|
overflow-y: scroll;
|
||||||
scroll-behavior: smooth;
|
scroll-behavior: smooth;
|
||||||
|
*:has(:popover-open) {
|
||||||
|
pointer-events: none;
|
||||||
|
touch-action: none;
|
||||||
|
[popover] {
|
||||||
|
pointer-events: auto;
|
||||||
|
touch-action: auto;
|
||||||
|
}
|
||||||
|
::backdrop {
|
||||||
|
pointer-events: all;
|
||||||
|
touch-action: manipulation;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@media (pointer: coarse) {
|
||||||
|
[popover] {
|
||||||
|
&::after {
|
||||||
|
content: "";
|
||||||
|
position: fixed;
|
||||||
|
inset: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
z-index: -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
p {
|
p {
|
||||||
@@ -110,6 +136,7 @@ li p {
|
|||||||
a {
|
a {
|
||||||
color: inherit;
|
color: inherit;
|
||||||
transition: color linear 0.15s;
|
transition: color linear 0.15s;
|
||||||
|
display: inline-block;
|
||||||
}
|
}
|
||||||
|
|
||||||
a:hover {
|
a:hover {
|
||||||
@@ -242,6 +269,18 @@ iframe {
|
|||||||
border: 0;
|
border: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
button {
|
||||||
|
display: inline-block;
|
||||||
|
background: none;
|
||||||
|
border: none;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
[popover]::backdrop {
|
||||||
|
background-color: rgba(0, 0, 0, 0.5);
|
||||||
|
backdrop-filter: blur(2px);
|
||||||
|
}
|
||||||
|
|
||||||
@media (max-width: 1020px) {
|
@media (max-width: 1020px) {
|
||||||
h1 {
|
h1 {
|
||||||
font-size: 3em;
|
font-size: 3em;
|
||||||
@@ -264,3 +303,45 @@ iframe {
|
|||||||
margin: 1em 0;
|
margin: 1em 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.window {
|
||||||
|
border: 2px solid #d0d0d0;
|
||||||
|
border-radius: 0.5rem;
|
||||||
|
flex-direction: column;
|
||||||
|
position: relative;
|
||||||
|
overflow-y: hidden;
|
||||||
|
padding-top: 1.5rem;
|
||||||
|
min-width: 10rem;
|
||||||
|
background-color: #232222;
|
||||||
|
color: #f3f3f3;
|
||||||
|
&::before {
|
||||||
|
content: attr(data-title);
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
height: 1.5rem;
|
||||||
|
width: 100%;
|
||||||
|
border-bottom: #d0d0d0 solid 2px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
padding-inline: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
&[popover] {
|
||||||
|
max-width: calc(100% - 2rem);
|
||||||
|
max-height: 100vh;
|
||||||
|
overflow-y: auto;
|
||||||
|
padding: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.buttons {
|
||||||
|
position: absolute;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
gap: 0.5rem;
|
||||||
|
top: 0;
|
||||||
|
right: 0;
|
||||||
|
font-size: 0.75rem;
|
||||||
|
height: 1.5rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user