This commit is contained in:
2025-11-07 17:43:37 +01:00
parent c3f837b90f
commit a645c87020
47 changed files with 238 additions and 2203 deletions

View File

@@ -31,9 +31,14 @@ export default function Footer() {
function Social({ href, label, children }: { href: string; label: string; children: React.ReactNode }) {
return (
<a href={href} target="_blank" rel="noreferrer" aria-label={label}
className="rounded p-2 transition-transform duration-200 hover:scale-110 hover:text-[var(--c-other)]">
{children}
<a
href={href}
target="_blank"
rel="noreferrer"
aria-label={label}
className="group relative inline-flex items-center justify-center w-12 h-12 rounded-xl bg-brandGradient text-white shadow-glow transition-transform duration-200 hover:scale-110"
>
<span className="text-xl group-hover:scale-110 transition-transform">{children}</span>
</a>
);
}

View File

@@ -17,20 +17,19 @@ export default function ContactMeForm() {
if (!opened) {
setOpened(true)
setOpeningBehind(false)
setContentMoveUp(false)
setContentMoveUp(false)
// Wait for the rotate-opening animation to finish before moving content up
// The actual moveUp will be handled in onTransitionEnd
} else {
setContentMoveUp(false)
setOpeningBehind(false)
setTimeout(() => setOpened(false), 1000) // match transition duration
setTimeout(() => setOpened(false), 1000) // match transition duration
}
}
const handleTransitionEnd = (e: React.TransitionEvent<HTMLDivElement>) => {
if (opened && e.propertyName === "transform") {
setContentMoveUp(true)
// Move the opening behind after the animation
setContentMoveUp(true)
setTimeout(() => setOpeningBehind(true), 10)
}
if (!opened && e.propertyName === "transform") {
@@ -39,6 +38,7 @@ export default function ContactMeForm() {
}
return (
<div className={styles["contact-me"]}>
<div
ref={openingRef}
@@ -56,11 +56,10 @@ export default function ContactMeForm() {
</div>
<div
className={
contentMoveUp
? `${styles.content} ${styles["content-moveup"]}`
: styles.content
}
className={[
styles.content,
contentMoveUp ? styles["content-moveup"] : ''
].filter(Boolean).join(' ')}
>
<form onSubmit={handleSubmit}>
<input

View File

@@ -1,15 +1,16 @@
.contact-me {
margin: 5em auto;
margin: 15em auto;
margin-top: 15em;
margin-bottom: 3em;
position: relative;
aspect-ratio: 16 / 9;
background-color: #c8c8c8;
background: var(--c-background-light);
max-width: 100vw;
border: 2px solid var(--c-lines);
border-radius: 0.75em;
width: 30em;
}
.contact-me + .mail-box{
}
/* .mail-box sibling styles were unused; removed to satisfy linter */
.contact-me .opening {
width: 100%;
@@ -17,21 +18,17 @@
position: absolute;
top: 0;
left: 0;
z-index: 2;
transform-origin: top;
padding-top: 4em;
clip-path: polygon(0 0, 100% 0, 50% 50%);
background-color: #d2d2d2;
transition: all 1s ease;
background: linear-gradient(135deg, var(--c-boxes), var(--c-other));
transition: transform 1s ease, background 0.5s ease;
text-align: center;
color: var(--c-text);
}
.rotate-opening{
background-color: #c8c8c8;
background: linear-gradient(135deg, var(--c-background-light), var(--c-boxes));
transform: rotateX(180deg);
}
@@ -52,22 +49,22 @@
.content-moveup{
transform: translateY(-70%);
}
.content-moveup-index {
z-index: 2 !important;
}
.content-moveup-index { z-index: 2 !important; }
.contact-me .content form{
width: 80%;
width: 90%;
display: flex;
gap: 1em;
flex-direction: column;
align-items: flex-start;
align-items: stretch;
justify-content: center;
margin: auto;
background-color: #deefff;
padding: 1em;
border: 0.5em dashed #88d4ed;
border-radius: 0.25em;
background: color-mix(in hsl, var(--c-background-light), transparent 35%);
backdrop-filter: blur(6px);
padding: 1.5em;
border: 0.35em dashed var(--c-lines);
border-radius: 0.75em;
color: var(--c-text);
}
.contact-me .content form div{
width: -webkit-fill-available;
@@ -77,26 +74,37 @@
.contact-me .content form input[type=submit]{
margin: auto;
border: none;
background: #4ca4d5;
color: #ffffff;
padding: 1em 1.5em;
background: linear-gradient(135deg, var(--c-other), var(--c-boxes));
color: var(--c-text);
padding: 0.85em 1.5em;
cursor: pointer;
border-radius: 1em;
border-radius: 0.75em;
font-weight: 600;
box-shadow: 0 0 12px -3px rgba(112,162,136,0.5);
transition: transform 0.2s ease, box-shadow 0.3s ease;
}
.contact-me .content form input[type=submit]:hover {
transform: translateY(-2px);
box-shadow: 0 0 20px -2px rgba(112,162,136,0.65);
}
.contact-me .content form input[type=text],
.contact-me .content form input[type=email],
.contact-me .content form textarea{
background-color: #bfe8ff;
border: none;
border-bottom: 0.15em solid #064c7d;
padding: 0.5em;
background: var(--c-background-light);
border: 1px solid var(--c-lines);
padding: 0.6em 0.75em;
border-radius: 0.5em;
color: var(--c-text);
}
.contact-me .content form input[type=text]::placeholder,
.contact-me .content form input[type=email]::placeholder,
.contact-me .content form textarea::placeholder{ color: color-mix(in srgb, var(--c-lines), white 25%); }
.opening-behind { z-index: 0 !important; }
.contact-me .cover {
border-radius: 1em;
position: absolute;
bottom: 0;
left: 0;
@@ -104,9 +112,10 @@
height: 100%;
z-index: 2;
clip-path: polygon(0 0, 50% 50%, 100% 0, 100% 100%, 0 100%);
background-color: #f0f0f0;
background: var(--c-background);
}
.contact-me .triangle{
border-radius: 1em;
position: absolute;
bottom: 0;
right: 0;
@@ -114,7 +123,7 @@
width: 100%;
height: 100%;
clip-path: polygon(100% 0, 0 100%, 100% 100%);
background-color: rgb(255 255 255);
background: linear-gradient(135deg, var(--c-boxes), var(--c-background-light));
}
@keyframes shake {
@@ -140,6 +149,13 @@
@media only screen and (max-width: 990px){
.contact-me{
aspect-ratio: unset;
margin-top: 7ch;
margin-top: 3ch;
background: transparent;
border: none;
}
.contact-me .opening,
.contact-me .cover,
.contact-me .triangle { display: none; }
.contact-me .content { position: relative; width: 100%; transform: none !important; }
.contact-me .content form { backdrop-filter: none; border: 1px solid var(--c-lines); }
}

View File

@@ -19,8 +19,9 @@
height: 100%;
width: 100%;
background-color: #c2a67d;
color: #5e5747;
/* Use brand palette accents and lines for door */
background-color: var(--c-background-light);
color: var(--c-text);
border-radius: 1em;
@@ -50,7 +51,7 @@
}
.door i{
color: #5e5747;
color: var(--c-text);
font-size: 5em;
display: inline-block;
animation: shake 0.4s ease-in-out infinite;
@@ -70,8 +71,8 @@
left: 0;
padding: 1em 3em;
padding-bottom: 0;
background-color: #cdc19c;
color: #5e5747;
background-color: var(--c-background-light);
color: var(--c-text);
border-top-left-radius: 1em;
border-top-right-radius: 1em;
}
@@ -125,7 +126,7 @@
.portfolio div {
width: 100%;
padding: 3em;
background-color: #cdc19c;
background-color: var(--c-background-light);
display: flex;
justify-content: center;
flex-wrap: wrap;
@@ -141,7 +142,7 @@
.portfolio div article {
display: flex;
border-radius: 0em;
background-color: #9c885c;
background-color: var(--c-boxes);
width: 30%;
text-align: center;
flex-direction: column;

View File

@@ -4,26 +4,28 @@ import type { ReactNode } from 'react';
type Tier = { id: string; title: string; price: number; desc: string; color: string; icon: ReactNode };
const tiers: Tier[] = [
{ id: 'coffee', title: 'Coffee', price: 3, desc: 'Fuel late-night coding sessions.', color: '#d97706', icon: <FaCoffee /> },
{ id: 'battery', title: 'Drone Battery', price: 30, desc: 'Extend aerial filming time.', color: '#16a34a', icon: <FaBatteryFull /> },
{ id: 'gpu', title: 'GPU Upgrade', price: 200, desc: 'Speed up rendering and ML tasks.', color: '#6366f1', icon: <FaMicrochip /> },
{ id: 'coffee', title: 'Coffee', price: 3, desc: 'Fuel late-night coding sessions.', color: 'var(--c-other)', icon: <FaCoffee /> },
{ id: 'battery', title: 'Drone Battery', price: 30, desc: 'Extend aerial filming time.', color: 'var(--c-other)', icon: <FaBatteryFull /> },
{ id: 'gpu', title: 'GPU Upgrade', price: 200, desc: 'Speed up rendering and ML tasks.', color: 'var(--c-other)', icon: <FaMicrochip /> },
];
export default function DonationShop() {
return (
<section id="shop" className="section">
<div className="container">
<h2 className="text-3xl md:text-4xl font-bold mb-2 text-rainbow">Support My Creative Journey</h2>
<p className="text-gray-300">Instead of buying products, consider donating to support my creative journey.</p>
<h2 className="text-3xl md:text-4xl font-bold mb-2 text-rainbow">Support My Creative Journey</h2>
<p className="text-brand-text/80">Instead of buying products, consider donating to support my creative journey.</p>
<div className="grid md:grid-cols-3 gap-6 mt-6">
{tiers.map(t => (
<div key={t.id} className="card p-5 flex flex-col">
<div className="text-5xl mb-3" style={{ color: t.color }}>{t.icon}</div>
<div className="text-5xl mb-3 inline-flex items-center justify-center w-20 h-20 rounded-xl bg-brandGradient text-white shadow-glow">
{t.icon}
</div>
<h3 className="text-xl font-semibold" style={{ color: t.color }}>{t.title}</h3>
<p className="text-[var(--c-lines)] mt-1">{t.desc}</p>
<div className="mt-auto flex items-center justify-between pt-4">
<span className="text-2xl font-bold" style={{ color: t.color }}>${t.price}</span>
<button className="px-4 py-2 rounded-lg font-semibold text-white bg-gradient-to-r from-fuchsia-600 to-orange-500 hover:shadow-lg hover:shadow-fuchsia-600/25 transition-all" onClick={() => alert(`Thank you for supporting with ${t.title}!`)}>Donate</button>
<button className="px-4 py-2 rounded-lg font-semibold text-brand-text bg-gradient-to-r from-[var(--c-other)] to-[var(--c-lines)] hover:shadow-glow transition-all" onClick={() => alert(`Thank you for supporting with ${t.title}!`)}>Donate</button>
</div>
</div>
))}

View File

@@ -13,11 +13,11 @@ export default function HeroCarousel() {
return (
<section id="home" className="relative min-h-[80vh] md:min-h-[85vh] flex items-center justify-center overflow-hidden">
{/* Background Gradient and animated glows */}
<div className="absolute inset-0 bg-gradient-to-br from-slate-800 via-slate-900 to-black -z-10" />
<div className="absolute inset-0 bg-gradient-to-br from-[var(--c-background-light)] via-[var(--c-background)] to-[var(--c-background)] -z-10" />
<div className="absolute inset-0 -z-10 pointer-events-none">
<div className="absolute top-1/4 left-1/4 w-64 h-64 bg-fuchsia-600/10 rounded-full blur-3xl animate-pulse" />
<div className="absolute bottom-1/4 right-1/4 w-96 h-96 bg-orange-500/10 rounded-full blur-3xl animate-pulse delay-1000" />
<div className="absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 w-80 h-80 bg-violet-400/10 rounded-full blur-3xl animate-pulse delay-2000" />
<div className="absolute top-1/4 left-1/4 w-64 h-64 bg-brand-accent/10 rounded-full blur-3xl animate-pulse" />
<div className="absolute bottom-1/4 right-1/4 w-96 h-96 bg-brand-lines/10 rounded-full blur-3xl animate-pulse delay-1000" />
<div className="absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 w-80 h-80 bg-brand-boxes/10 rounded-full blur-3xl animate-pulse delay-2000" />
</div>
<div className="relative container mx-auto px-4 py-10 grid lg:grid-cols-2 gap-10 items-center">
@@ -25,18 +25,18 @@ export default function HeroCarousel() {
<div className="text-center lg:text-left">
<h1 className="text-4xl md:text-6xl font-bold mb-4 leading-tight">
<span className="text-rainbow">Welcome to</span><br />
<span className="text-white">Vontor.cz</span>
<span className="text-brand-text">Vontor.cz</span>
</h1>
<p className="text-lg md:text-xl text-gray-300 mb-6">Creative Tech & Design by <span className="text-fuchsia-600 font-semibold">Bruno Vontor</span></p>
<p className="text-lg md:text-xl text-brand-text/80 mb-6">Creative Tech & Design by <span className="text-brand-accent font-semibold">Bruno Vontor</span></p>
<div className="flex flex-col sm:flex-row gap-4 justify-center lg:justify-start">
<a href="#portfolio" className="px-8 py-3 bg-gradient-to-r from-fuchsia-600 to-orange-500 text-white font-semibold rounded-lg hover:shadow-lg hover:shadow-fuchsia-600/25 transition-all duration-300 transform hover:scale-105">View Portfolio</a>
<a href="#contact" className="px-8 py-3 border-2 border-violet-400 text-violet-400 font-semibold rounded-lg hover:bg-violet-400 hover:text-white transition-all duration-300">Get In Touch</a>
<a href="#portfolio" className="px-8 py-3 bg-gradient-to-r from-[var(--c-other)] to-[var(--c-lines)] text-brand-text font-semibold rounded-lg hover:shadow-glow transition-all duration-300 transform hover:scale-105">View Portfolio</a>
<a href="#contact" className="px-8 py-3 border-2 border-brand-lines text-brand-lines font-semibold rounded-lg hover:bg-brand-lines hover:text-brand-bg transition-all duration-300">Get In Touch</a>
</div>
</div>
{/* Video carousel */}
<div className="relative">
<div className="relative aspect-video bg-slate-800 rounded-xl overflow-hidden shadow-2xl">
<div className="relative aspect-video bg-brand-bgLight rounded-xl overflow-hidden shadow-2xl">
{videos.map((v,i) => (
<iframe
key={v}
@@ -47,12 +47,12 @@ export default function HeroCarousel() {
allowFullScreen
/>
))}
<div className="absolute inset-0 bg-gradient-to-t from-black/50 to-transparent pointer-events-none" />
<div className="absolute inset-0 bg-gradient-to-t from-brand-bg/60 to-transparent pointer-events-none" />
</div>
{/* Indicators */}
<div className="flex justify-center mt-4 space-x-2">
{videos.map((_,i) => (
<button key={i} onClick={()=>setIndex(i)} aria-label={`Go to slide ${i+1}`} className={`w-3 h-3 rounded-full transition-all duration-300 ${i===index? 'bg-fuchsia-600':'bg-gray-600 hover:bg-gray-400'}`} />
<button key={i} onClick={()=>setIndex(i)} aria-label={`Go to slide ${i+1}`} className={`w-3 h-3 rounded-full transition-all duration-300 ${i===index? 'bg-brand-accent':'bg-brand-lines/40 hover:bg-brand-lines/60'}`} />
))}
</div>
</div>

View File

@@ -1,14 +1,17 @@
export default function HostingSecuritySection() {
return (
<section id="hosting" className="py-20">
<div className="container mx-auto px-4">
<h2 className="text-3xl md:text-4xl font-bold mb-6 text-rainbow">Hosting & Protection</h2>
<div className="card p-6 md:p-8">
<p className="text-gray-300">We host our applications ourselves, which reduces hosting costs as projects scale.</p>
<p className="text-gray-300 mt-2">All websites are protected by Cloudflare and optimized for performance.</p>
<h2 className="text-3xl md:text-4xl font-bold mb-6 text-rainbow">Hosting & Protection</h2>
<div className="card p-6 md:p-8">
<p className="text-brand-text opacity-80">We host our applications ourselves, which reduces hosting costs as projects scale.</p>
<p className="text-brand-text opacity-80 mt-2">All websites are protected by Cloudflare and optimized for performance.</p>
<div className="grid grid-cols-3 md:grid-cols-6 gap-4 text-center text-sm mt-6">
{['Server', 'Cloudflare', 'Docker', 'SSL', 'Monitoring', 'Scaling'].map(item => (
<div key={item} className="p-3 rounded-lg bg-slate-700/50 text-violet-300 transition-transform duration-200 hover:scale-105">{item}</div>
<div key={item} className="p-3 rounded-lg bg-brandGradient text-white shadow-glow transition-transform duration-200 hover:scale-105 flex flex-col items-center justify-center">
<span className="text-xs tracking-wide">{item}</span>
</div>
))}
</div>
</div>

View File

@@ -22,7 +22,7 @@ nav{
background: linear-gradient(117deg, rgba(34,34,34,1) 0%, rgba(59,54,54,1) 100%);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr="#222222",endColorstr="#3b3636",GradientType=1);*/
color: #fff;
color: var(--c-text);
text-align: center;
margin: auto;
@@ -52,7 +52,7 @@ nav a{
text-decoration: none;
}
nav a:hover{
color: #fff;
color: var(--c-text);
}
/* Unify link/summary layout to prevent distortion */
nav a,
@@ -75,7 +75,7 @@ nav a::before {
height: 2px;
bottom: 0;
left: 0;
background-color: #fff;
background-color: var(--c-other);
transform: scaleX(0);
transition: transform 0.3s ease;
}
@@ -83,7 +83,7 @@ nav a:hover::before {
transform: scaleX(1);
}
nav summary:hover {
color: #fff;
color: var(--c-text);
}
/* underline effect shared for links and summary */
@@ -96,7 +96,7 @@ nav summary::before {
height: 2px;
bottom: 0;
left: 0;
background-color: #fff;
background-color: var(--c-other);
transform: scaleX(0);
transition: transform 0.3s ease;
}

View File

@@ -9,12 +9,14 @@ export default function HomeNav() {
return (
<nav className={styles.nav}>
<FaBars
className={`${styles.toggle} ${navOpen ? styles.toggleRotated : ""}`}
<div
className={`inline-flex items-center justify-center w-12 h-12 rounded-xl bg-brandGradient text-white shadow-glow cursor-pointer ${styles.toggle} ${navOpen ? styles.toggleRotated : ""}`}
onClick={toggleNav}
aria-label="Toggle navigation"
aria-expanded={navOpen}
/>
>
<FaBars />
</div>
<ul className={`${styles.navList} ${navOpen ? styles.open : ""}`}>
<li id="nav-logo" className={styles.logo}>
@@ -30,7 +32,9 @@ export default function HomeNav() {
<details>
<summary>
Services
<FaChevronDown className={`${styles.caret} ml-2 inline-block`} aria-hidden="true" />
<span className="inline-flex items-center justify-center w-6 h-6 rounded-md bg-brandGradient text-white ml-2 shadow-glow">
<FaChevronDown className={styles.caret} aria-hidden="true" />
</span>
</summary>
<ul className={styles.submenu}>
<li><a href="#web">Web development</a></li>

View File

@@ -16,19 +16,19 @@ export default function SiteNav() {
}, []);
return (
<header className={`sticky top-0 z-50 transition-all ${scrolled ? 'bg-slate-800/95 backdrop-blur-md shadow-lg' : 'bg-transparent'}`}>
<nav className="relative container mx-auto px-4 flex items-center justify-between h-16 text-[var(--c-text)] font-medium">
<header className={`sticky top-0 z-50 transition-all ${scrolled ? 'bg-brand-bg/95 backdrop-blur-md shadow-lg' : 'bg-transparent'}`}>
<nav className="relative container mx-auto px-4 flex items-center justify-between h-16 text-brand-text font-medium">
<div className="text-xl tracking-wide font-semibold">
<NavLink to="/" className="inline-block px-2 py-1 rounded nav-item text-rainbow font-bold">vontor.cz</NavLink>
</div>
<button
aria-label="Toggle navigation"
onClick={() => setOpen(o => !o)}
className="md:hidden p-2 rounded glow focus:outline-none"
className="md:hidden p-2 rounded-xl glow focus:outline-none bg-brandGradient text-white shadow-glow"
>
{open ? <FaTimes /> : <FaBars />}
</button>
<ul className={`md:flex md:items-center md:gap-8 md:static absolute left-0 w-full md:w-auto transition-all duration-300 ${open ? 'top-16 bg-slate-800/95 pb-6 rounded-lg backdrop-blur-md' : 'top-[-500px]'}`}>
<ul className={`md:flex md:items-center md:gap-8 md:static absolute left-0 w-full md:w-auto transition-all duration-300 ${open ? 'top-16 bg-brand-bg/95 pb-6 rounded-lg backdrop-blur-md' : 'top-[-500px]'}`}>
<li className="flex"><NavLink to="/" onClick={()=>setOpen(false)} className={linkCls}>Home</NavLink></li>
<li className="flex"><NavLink to="/portfolio" onClick={()=>setOpen(false)} className={linkCls}>Portfolio</NavLink></li>
<li className="flex"><NavLink to="/skills" onClick={()=>setOpen(false)} className={linkCls}>Skills</NavLink></li>
@@ -42,7 +42,7 @@ export default function SiteNav() {
className={`nav-item px-3 py-2 flex items-center gap-1`}
aria-haspopup="true" aria-expanded={servicesOpen}
>
More <FaChevronDown className={`transition-transform ${servicesOpen ? 'rotate-180' : ''}`} />
<span className="inline-flex items-center gap-1">More <span className="inline-flex items-center justify-center w-6 h-6 rounded-md bg-brandGradient text-white"><FaChevronDown className={`transition-transform ${servicesOpen ? 'rotate-180' : ''}`} /></span></span>
</button>
{/* Mobile inline dropdown */}
<div className={`md:hidden w-full mt-2 ${servicesOpen ? 'block' : 'hidden'}`}>
@@ -69,5 +69,5 @@ export default function SiteNav() {
);
}
const linkCls = ({ isActive }: { isActive: boolean }) => `nav-item px-3 py-2 rounded transition-colors ${isActive ? 'active text-[var(--c-other)] font-semibold' : 'hover:text-[var(--c-other)]'}`;
const linkCls = ({ isActive }: { isActive: boolean }) => `nav-item px-3 py-2 rounded transition-colors ${isActive ? 'active text-brand-accent font-semibold' : 'hover:text-brand-accent'}`;
const dropdownCls = "block px-2 py-1 rounded hover:bg-[color-mix(in_hsl,var(--c-other),transparent_85%)]";

View File

@@ -8,11 +8,11 @@ const categories: { name: string; items: string[] }[] = [
export default function SkillsSection() {
return (
<section id="skills" className="py-20 bg-gradient-to-b from-slate-900 to-slate-800">
<section id="skills" className="py-20 bg-gradient-to-b from-brand-bg to-brand-bgLight">
<div className="container mx-auto px-4">
<div className="text-center mb-12">
<h2 className="text-4xl font-bold mb-4 text-rainbow">Skills</h2>
<p className="text-gray-300 max-w-2xl mx-auto">Core technologies and tools I use across backend, frontend, infrastructure and hardware.</p>
<p className="text-brand-text/80 max-w-2xl mx-auto">Core technologies and tools I use across backend, frontend, infrastructure and hardware.</p>
</div>
<div className="grid gap-8 md:grid-cols-2 lg:grid-cols-3">
{categories.map(cat => (
@@ -20,9 +20,9 @@ export default function SkillsSection() {
<h3 className="font-semibold mb-4 text-rainbow tracking-wide">{cat.name}</h3>
<ul className="space-y-2 text-sm">
{cat.items.map(i => (
<li key={i} className="flex items-center gap-2 text-gray-300">
<span className="inline-block w-2 h-2 rounded-full bg-fuchsia-600" />
<span className="group-hover:text-white transition-colors">{i}</span>
<li key={i} className="flex items-center gap-2 text-brand-text/80">
<span className="inline-block w-2 h-2 rounded-full bg-brand-accent" />
<span className="group-hover:text-brand-text transition-colors">{i}</span>
</li>
))}
</ul>

View File

@@ -1,12 +1,12 @@
export default function TradingGraph() {
return (
<section id="live" className="py-20 bg-gradient-to-b from-slate-900 to-slate-800">
<section id="live" className="py-20 bg-gradient-to-b from-brand-bg to-brand-bgLight">
<div className="container mx-auto px-4">
<h2 className="text-3xl md:text-4xl font-bold mb-6 text-rainbow">Live Performance</h2>
<div className="card p-4 md:p-6">
<div className="mb-3 text-sm text-gray-400">Trading212 graph placeholder</div>
<div className="aspect-[16/9] w-full rounded border border-slate-700 bg-black/40 grid place-items-center">
<span className="text-gray-400">Graph will appear here</span>
<div className="mb-3 text-sm text-brand-text/60">Trading212 graph placeholder</div>
<div className="aspect-[16/9] w-full rounded border border-brand-lines/50 bg-brand-bg/40 grid place-items-center">
<span className="text-brand-text/60">Graph will appear here</span>
</div>
</div>
</div>

View File

@@ -28,8 +28,8 @@ body {
font-family: 'Inter', ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", "Apple Color Emoji", "Segoe UI Emoji";
color: var(--c-text);
background: radial-gradient(1200px 800px at 10% 10%, var(--c-background-light), transparent 60%),
radial-gradient(1000px 700px at 90% 20%, rgba(135,169,218,0.15), transparent 60%),
linear-gradient(180deg, var(--c-background) 0%, #02162f 100%);
radial-gradient(1000px 700px at 90% 20%, color-mix(in hsl, var(--c-lines), transparent 85%), transparent 60%),
linear-gradient(180deg, var(--c-background) 0%, color-mix(in hsl, var(--c-background), black 15%) 100%);
}
a {
@@ -157,3 +157,20 @@ button:active { transform: translateY(1px) }
transition: none;
}
}
/* Use project palette for list markers (bullets) and summary markers */
li::marker,
ol li::marker,
ul li::marker,
summary::marker {
color: var(--c-boxes);
}
/* Ensure fallback for older browsers by tinting bullets via ::before where used */
li.custom-marker::before {
content: "\2022"; /* bullet */
color: var(--c-boxes);
display: inline-block;
width: 1em;
margin-left: -1em;
}

View File

@@ -1,10 +1,35 @@
import ContactMeForm from "../../components/Forms/ContactMe/ContactMeForm";
export default function ContactPage(){
return (
<section className="section">
<div className="container">
<h2 className="text-2xl md:text-3xl font-bold mb-4">Get in Touch</h2>
<p className="text-[var(--c-lines)] mb-6">Reach out via email or phone. Social links are in the footer.</p>
<div className="glass p-6 max-w-lg">
<h2 className="text-2xl md:text-3xl font-bold mb-2 text-rainbow">Get in Touch</h2>
<p className="text-brand-lines mb-6">Reach out via the form or use the details below.</p>
{/* Desktop/tablet: envelope animation + slide-out form */}
<div className="hidden md:block">
<ContactMeForm />
</div>
{/* Mobile: simple card version without envelope */}
<div className="md:hidden">
<div className="card p-5">
<form className="space-y-3">
<div>
<label className="block text-sm text-brand-lines mb-1">Your email</label>
<input type="email" required className="w-full rounded-lg bg-brand-bgLight/40 border border-brand-lines/40 focus:outline-none focus:ring-2 focus:ring-brand-accent px-3 py-2 text-brand-text placeholder:text-brand-lines/70" placeholder="Enter your email" />
</div>
<div>
<label className="block text-sm text-brand-lines mb-1">Message</label>
<textarea required rows={5} className="w-full rounded-lg bg-brand-bgLight/40 border border-brand-lines/40 focus:outline-none focus:ring-2 focus:ring-brand-accent px-3 py-2 text-brand-text placeholder:text-brand-lines/70" placeholder="How can I help?" />
</div>
<button type="submit" className="px-4 py-2 rounded-lg font-semibold text-white bg-brandGradient shadow-glow">Send</button>
</form>
</div>
</div>
<div className="glass p-6 max-w-lg mt-8">
<p><strong>Email:</strong> <a href="mailto:brunovontor@gmail.com" className="hover:text-[var(--c-other)]">brunovontor@gmail.com</a></p>
<p className="mt-2"><strong>Phone:</strong> <a href="tel:+420605512624" className="hover:text-[var(--c-other)]">+420 605 512 624</a></p>
</div>

View File

@@ -109,7 +109,7 @@ export default function Downloader() {
<button
type="submit"
disabled={!url || probing}
className="px-3 py-2 rounded bg-blue-600 text-white disabled:opacity-50"
className="px-3 py-2 rounded bg-brand-accent text-brand-text disabled:opacity-50"
>
{probing ? "Probing..." : "Get info"}
</button>
@@ -117,7 +117,7 @@ export default function Downloader() {
type="button"
onClick={onDownload}
disabled={!canDownload || downloading}
className="px-3 py-2 rounded bg-emerald-600 text-white disabled:opacity-50"
className="px-3 py-2 rounded bg-brand-accent text-brand-text disabled:opacity-50"
>
{downloading ? "Downloading..." : "Download"}
</button>
@@ -134,7 +134,7 @@ export default function Downloader() {
className="w-40 h-24 object-cover rounded border"
/>
)}
<div className="text-sm text-gray-800 space-y-1">
<div className="text-sm text-brand-text/90 space-y-1">
<div>
<span className="font-medium">Title:</span> {info.title || "-"}
</div>

View File

@@ -23,7 +23,7 @@
border-radius: 1em;
}
.introduction article header {}
/* header rules intentionally left out; keep markup clean */
.introduction article:nth-child(1) {
width: 100%;
@@ -71,7 +71,9 @@
list-style: none;
width: 20px;
height: 20px;
background: rgba(255, 255, 255, 35%);
/* use design palette for animated dots */
background: var(--c-boxes);
opacity: 0.35;
animation: animate 4s linear infinite;
bottom: -150px;