updated look and feel of the hero component

This commit is contained in:
Valentijn
2026-04-22 17:51:30 +02:00
parent a436da316d
commit a9926fbbb7
4 changed files with 249 additions and 50 deletions

View File

@@ -8,65 +8,72 @@ interface Props {
} }
const { label, href, icon } = Astro.props; const { label, href, icon } = Astro.props;
const navigationHandler = `window.open('${href}', '_blank')`;
--- ---
<div class="button"> <div class="button" onclick={navigationHandler}>
<Icon name={icon} class="icon" /> <Icon name={icon} class="icon" />
<a href={href} target="_blank"> <a href={href} target="_blank" rel="noreferrer">
{label} {label}
</a> </a>
</div> </div>
<style> <style>
:root { :root {
--border: 128, 115, 100; --transition-time: .28s;
--transition-time: .3s;
} }
.button { .button {
aspect-ratio: 6/2 !important;
min-width: 130px; min-width: 130px;
width: 10dvw; width: min(13rem, 100%);
border-radius: 10pt; border-radius: 999px;
border: 2px solid rgb(var(--border)); border: 1px solid rgba(255, 255, 255, 0.14);
background: rgba(18, 18, 28, 0.24);
backdrop-filter: blur(16px);
box-shadow: 0 24px 50px rgba(0, 0, 0, 0.18);
display: flex; display: flex;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
min-height: 1.8rem;
cursor: pointer; cursor: pointer;
transition: all var(--transition-time); transition: transform var(--transition-time), border-color var(--transition-time), background var(--transition-time), box-shadow var(--transition-time);
gap:.2rem; gap: 0.75rem;
padding-left: .5rem; padding: 0.95rem 1.2rem;
} }
.button:hover { .button:hover {
background: rgb(var(--border)); background: rgba(32, 32, 46, 0.5);
border-color: rgba(255, 255, 255, 0.22);
transform: translateY(-2px);
box-shadow: 0 24px 65px rgba(0, 0, 0, 0.22);
} }
.button:hover a { .button:hover a {
color: white; color: #fff;
transition: all var(--transition-time);
} }
.button a { .button a {
text-decoration: none; text-decoration: none;
color: black; color: #f5f2eb;
text-align: left !important; text-align: left !important;
width: 80%; width: 100%;
height: 100%;
border: none;
background: transparent;
font: inherit;
cursor: pointer;
padding: 0;
display: flex;
align-items: center;
justify-content: flex-start;
} }
.icon { .icon {
width: 1.1rem; width: 1.2rem;
height: 1.1rem; height: 1.2rem;
flex-shrink: 0; flex-shrink: 0;
} color: #f5f2eb;
@media (max-width: 600px) {
.button {
min-width: 28%;
}
} }
</style> </style>

View File

@@ -0,0 +1,131 @@
---
import { Icon } from 'astro-icon/components';
import { siteData } from '../../data/site';
interface Props {
label: string;
icon: string;
}
const { label, icon } = Astro.props;
const safeEmail = siteData.email;
const clipboardHandler = `navigator.clipboard.writeText('${safeEmail}').then(()=>{const btn=this.querySelector('.copy-button') || this; btn.dataset.copied='true'; setTimeout(()=>{ delete btn.dataset.copied }, 1200)})`;
---
<div class="email-button" onclick={clipboardHandler}>
<Icon name={icon} class="icon" />
<button
type="button"
class="copy-button"
onclick={clipboardHandler}
aria-label="Copy email address"
>
<span class="label">{label}</span>
<span class="email">{safeEmail}</span>
</button>
</div>
<style>
:root {
--transition-time: .28s;
}
.email-button {
min-width: 130px;
width: min(13rem, 100%);
border-radius: 999px;
border: 1px solid rgba(255, 255, 255, 0.14);
background: rgba(18, 18, 28, 0.24);
backdrop-filter: blur(16px);
box-shadow: 0 24px 50px rgba(0, 0, 0, 0.18);
display: flex;
justify-content: center;
align-items: center;
min-height: 1.8rem;
cursor: pointer;
transition: transform var(--transition-time), border-color var(--transition-time), background var(--transition-time), box-shadow var(--transition-time);
gap: 0.75rem;
padding: 0.95rem 1.2rem;
}
.email-button:hover {
background: rgba(32, 32, 46, 0.5);
border-color: rgba(255, 255, 255, 0.22);
transform: translateY(-2px);
box-shadow: 0 24px 65px rgba(0, 0, 0, 0.22);
width: min(15rem, 100%);
}
.email-button:hover .label {
color: #fff;
}
.email-button:hover .email {
color: #fff;
}
.copy-button {
text-decoration: none;
color: #f5f2eb;
text-align: left !important;
width: 100%;
height: 100%;
border: none;
background: transparent;
font: inherit;
cursor: pointer;
padding: 0;
display: flex;
align-items: center;
justify-content: flex-start;
position: relative;
gap: 0.35rem;
}
.email {
position: absolute;
display:none;
opacity: 0;
transition: opacity var(--transition-time) ease;
pointer-events: none;
}
.label {
transition: opacity var(--transition-time) ease;
}
.email-button:hover .label {
opacity: 0;
display:none;
pointer-events: none;
}
.email-button:hover .email {
position: static;
display:block;
opacity: 1;
pointer-events: auto;
}
.copy-button[data-copied='true']::after {
content: 'Copied!';
position: absolute;
right: 0.2rem;
top: -1.4rem;
padding: 0.2rem 0.55rem;
border-radius: 999px;
background: rgba(18, 18, 18, 0.92);
color: white;
font-size: 0.75rem;
white-space: nowrap;
}
.icon {
width: 1.2rem;
height: 1.2rem;
flex-shrink: 0;
color: #f5f2eb;
}
</style>

View File

@@ -3,9 +3,12 @@ import {age} from "../../utils/getAge"
import {study} from "../../utils/getCurrentStudy" import {study} from "../../utils/getCurrentStudy"
import hero_img from "../../assets/hero.png" import hero_img from "../../assets/hero.png"
const hero_img_src = `url(${hero_img.src})`;
import Button from "./Button.astro" import Button from "./Button.astro"
import EmailButton from "./EmailButton.astro"
const hero_img_src = `url(${hero_img.src})`;
--- ---
<div id="container"> <div id="container">
@@ -16,8 +19,8 @@ import Button from "./Button.astro"
<div class="buttonContainer"> <div class="buttonContainer">
<Button icon="mdi:git" label="Gitea" href="https://git.herpiederpiee.nl/valentijn?tab=repositories"/> <Button icon="mdi:git" label="Gitea" href="https://git.herpiederpiee.nl/valentijn?tab=repositories"/>
<Button icon="mdi:linkedin" label="LinkedIn", href="https://nl.linkedin.com/in/valentijn-van-der-jagt"/> <Button icon="mdi:linkedin" label="LinkedIn" href="https://nl.linkedin.com/in/valentijn-van-der-jagt"/>
<Button icon="mdi:email-outline" label="E-mail" href="mailto:valentijn@example.com"/> <EmailButton icon="mdi:email-outline" label="E-mail" />
</div> </div>
@@ -29,47 +32,104 @@ import Button from "./Button.astro"
#container { #container {
font-family: Inter, Roboto, 'Helvetica Neue', 'Arial Nova', 'Nimbus Sans', Arial, sans-serif; font-family: Inter, Roboto, 'Helvetica Neue', 'Arial Nova', 'Nimbus Sans', Arial, sans-serif;
height: 60dvh; position: relative;
margin: 10px 10px 0px 10px; min-height: clamp(420px, 58vh, 680px);
background:rgb(172, 146, 116); margin: 10px;
background-image: var(--hero_img_src) !important; padding: clamp(1.5rem, 3vw, 2.5rem);
background: radial-gradient(circle at 15% 18%, rgba(255, 246, 228, 0.32), transparent 24%),
linear-gradient(180deg, rgba(255, 255, 255, 0.1), rgba(10, 10, 10, 0.24)),
var(--hero_img_src);
background-size: cover; background-size: cover;
background-position: center; background-position: center;
background-blend-mode: hue; border-radius: 20px;
border-radius: 10pt; box-shadow: 0 24px 60px rgba(16, 14, 12, 0.18);
overflow: hidden;
display: flex;
flex-direction: column;
justify-content: flex-start;
animation: driftBackground 16s ease-in-out infinite alternate;
} }
.buttonContainer { .buttonContainer {
padding-left:10px;
display: flex; display: flex;
justify-content: start; flex-wrap: wrap;
gap:10px; align-items: center;
justify-content: flex-start;
gap: 1rem;
margin-top: 1.4rem;
padding: 0;
}
.buttonContainer > * {
flex: 0 1 auto;
}
.titleContainer {
display: flex;
flex-direction: column;
gap: 0.9rem;
} }
h1, h3 { h1, h3 {
font-family: "Work Sans", sans-serif; font-family: "Work Sans", sans-serif;
font-optical-sizing: auto; font-optical-sizing: auto;
font-style: normal; font-style: normal;
margin:0; margin: 0;
color: #ecfbff;
} }
.main-title { .main-title {
font-size: max(min(8dvw, 130px), 30px); font-size: clamp(2.5rem, 6vw, 5.25rem);
font-weight: 600; font-weight: 700;
line-height: 0.95;
letter-spacing: -0.03em;
animation: floatText 10s ease-in-out infinite alternate;
} }
.sub-title { .sub-title {
font-size: max(min(3dvw, 90px), 18px); font-size: clamp(1.5rem, 2.5vw, 2.5rem);
font-weight: 300; font-weight: 300;
color: rgba(255, 255, 255, 0.9);
margin-top: 0.7rem;
opacity: 0.94;
} }
@keyframes floatText {
0% { transform: translateY(0); }
100% { transform: translateY(-8px); }
}
@keyframes driftBackground {
0% { background-position: center top; }
100% { background-position: 12% 62%; }
}
@media (max-width: 900px) {
#container {
padding: 1.5rem 1.2rem;
}
.buttonContainer {
justify-content: center;
}
}
@media (max-width: 760px) {
.buttonContainer {
justify-content: center;
gap: 0.85rem;
}
}
@media (max-width: 600px) { @media (max-width: 600px) {
#container {
min-height: 360px;
}
.buttonContainer { .buttonContainer {
justify-content: space-around; justify-content: center;
padding-left:0 gap: 0.8rem;
padding: 0.75rem 0 0;
} }
} }
</style> </style>

View File

@@ -1,5 +1,6 @@
export const siteData = { export const siteData = {
name: "Valentijn van der Jagt", name: "Valentijn van der Jagt",
email: "valentijnkijkuit@outlook.com",
birthDate: new Date("2006-06-27"), birthDate: new Date("2006-06-27"),
studies: [ studies: [
{ {