chore: migrate to static site
This commit is contained in:
@@ -1,43 +1,86 @@
|
||||
# Astro Starter Kit: Minimal
|
||||
# Personal Portfolio
|
||||
|
||||
```sh
|
||||
pnpm create astro@latest -- --template minimal
|
||||
A framework-free, static portfolio website built with vanilla HTML, CSS, and JavaScript.
|
||||
|
||||
## Features
|
||||
|
||||
- **Zero Runtime Dependencies**: No JavaScript framework required
|
||||
- **Multi-language Support**: English and Spanish with instant switching
|
||||
- **Dark/Light Mode**: Theme persistence with localStorage
|
||||
- **Glassmorphism Design**: Modern UI with blur effects and transparency
|
||||
- **Fully Responsive**: Works on all devices
|
||||
- **SEO Optimized**: Semantic HTML5 markup
|
||||
- **Fast Loading**: Minimal bundle size
|
||||
|
||||
## Tech Stack
|
||||
|
||||
- **HTML5**: Semantic markup
|
||||
- **CSS3**: Custom properties, flexbox, grid, animations
|
||||
- **Vanilla JavaScript**: ES6+ modules, classes, localStorage
|
||||
- **Google Fonts**: Space Grotesk typography
|
||||
- **Material Symbols**: Icon system
|
||||
|
||||
## Development
|
||||
|
||||
### Prerequisites
|
||||
|
||||
- Node.js (for dev server only)
|
||||
- Any modern web browser
|
||||
|
||||
### Setup
|
||||
|
||||
```bash
|
||||
# Install dev dependencies (optional)
|
||||
npm install
|
||||
|
||||
# Start development server
|
||||
npm run dev
|
||||
|
||||
# Or simply open index.html in your browser
|
||||
```
|
||||
|
||||
> 🧑🚀 **Seasoned astronaut?** Delete this file. Have fun!
|
||||
### Project Structure
|
||||
|
||||
## 🚀 Project Structure
|
||||
|
||||
Inside of your Astro project, you'll see the following folders and files:
|
||||
|
||||
```text
|
||||
/
|
||||
├── public/
|
||||
├── src/
|
||||
│ └── pages/
|
||||
│ └── index.astro
|
||||
└── package.json
|
||||
```
|
||||
├── index.html # Main HTML file
|
||||
├── styles/
|
||||
│ └── main.css # Complete stylesheet
|
||||
├── js/
|
||||
│ └── main.js # JavaScript functionality
|
||||
├── public/ # Static assets
|
||||
└── package.json # Dev dependencies only
|
||||
```
|
||||
|
||||
Astro looks for `.astro` or `.md` files in the `src/pages/` directory. Each page is exposed as a route based on its file name.
|
||||
## Features Implementation
|
||||
|
||||
There's nothing special about `src/components/`, but that's where we like to put any Astro/React/Vue/Svelte/Preact components.
|
||||
### Language Switching
|
||||
|
||||
Any static assets, like images, can be placed in the `public/` directory.
|
||||
- Translations stored in JavaScript objects
|
||||
- No page reload required
|
||||
- Preference saved in localStorage
|
||||
- Dynamic content rendering
|
||||
|
||||
## 🧞 Commands
|
||||
### Theme Toggle
|
||||
|
||||
All commands are run from the root of the project, from a terminal:
|
||||
- CSS custom properties for theming
|
||||
- System preference detection
|
||||
- Smooth transitions
|
||||
- Icon updates based on current theme
|
||||
|
||||
| Command | Action |
|
||||
| :------------------------ | :----------------------------------------------- |
|
||||
| `pnpm install` | Installs dependencies |
|
||||
| `pnpm dev` | Starts local dev server at `localhost:4321` |
|
||||
| `pnpm build` | Build your production site to `./dist/` |
|
||||
| `pnpm preview` | Preview your build locally, before deploying |
|
||||
| `pnpm astro ...` | Run CLI commands like `astro add`, `astro check` |
|
||||
| `pnpm astro -- --help` | Get help using the Astro CLI |
|
||||
### Performance
|
||||
|
||||
## 👀 Want to learn more?
|
||||
- No build step required
|
||||
- Minimal HTTP requests
|
||||
- Optimized CSS with custom properties
|
||||
- Efficient DOM manipulation
|
||||
|
||||
Feel free to check [our documentation](https://docs.astro.build) or jump into our [Discord server](https://astro.build/chat).
|
||||
## Browser Support
|
||||
|
||||
- Chrome 60+
|
||||
- Firefox 55+
|
||||
- Safari 12+
|
||||
- Edge 79+
|
||||
|
||||
## License
|
||||
|
||||
MIT
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
// @ts-check
|
||||
import { defineConfig } from 'astro/config';
|
||||
|
||||
import tailwindcss from '@tailwindcss/vite';
|
||||
|
||||
// https://astro.build/config
|
||||
export default defineConfig({
|
||||
vite: {
|
||||
plugins: [tailwindcss()]
|
||||
}
|
||||
});
|
||||
+159
@@ -0,0 +1,159 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en" class="light">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="description" content="Itziar ZG - Vanguard Designer Portfolio">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Itziar ZG - Vanguard CV</title>
|
||||
<link rel="icon" type="image/svg+xml" href="/favicon.svg">
|
||||
<link rel="stylesheet" href="/styles/main.css">
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@300;400;500;600;700&display=swap" rel="stylesheet">
|
||||
<link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:wght@100..700,0..1&display=swap" rel="stylesheet">
|
||||
</head>
|
||||
<body class="bg-background-light dark:bg-background-dark font-display text-slate-900 dark:text-slate-100 min-h-screen pb-24">
|
||||
<!-- Top Navigation -->
|
||||
<nav class="sticky top-0 z-50 flex items-center justify-between p-4 glass-dark">
|
||||
<div class="flex items-center gap-2">
|
||||
<span class="material-symbols-outlined text-primary text-3xl">deployed_code</span>
|
||||
<h1 class="text-xl font-bold tracking-tight">Itziar ZG</h1>
|
||||
</div>
|
||||
<div class="flex items-center gap-2">
|
||||
<button
|
||||
id="language-toggle"
|
||||
class="p-2 rounded-full hover:bg-primary/10 transition-colors"
|
||||
aria-label="Toggle language"
|
||||
>
|
||||
<span class="material-symbols-outlined text-primary">translate</span>
|
||||
</button>
|
||||
<button
|
||||
id="theme-toggle"
|
||||
class="p-2 rounded-full hover:bg-primary/10 transition-colors"
|
||||
aria-label="Toggle theme"
|
||||
>
|
||||
<span class="material-symbols-outlined text-primary">dark_mode</span>
|
||||
</button>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<!-- Hero Section -->
|
||||
<header class="relative px-6 pt-10 pb-16 overflow-hidden">
|
||||
<div class="absolute top-0 right-0 -z-10 w-64 h-64 bg-primary/20 rounded-full blur-[100px]"></div>
|
||||
<div class="absolute bottom-0 left-0 -z-10 w-48 h-48 bg-purple-600/10 rounded-full blur-[80px]"></div>
|
||||
|
||||
<div class="flex flex-col items-center text-center gap-6">
|
||||
<div class="relative p-1 rounded-full bg-gradient-to-tr from-primary to-purple-400">
|
||||
<div
|
||||
class="w-32 h-32 rounded-full bg-cover bg-center border-4 border-background-dark"
|
||||
alt="Professional portrait of a female digital designer"
|
||||
style="background-image: url('https://lh3.googleusercontent.com/aida-public/AB6AXuD6WeB0nJf-ZCuFJ6oa6vOkhHSa7HvieIuXVDVhw_U7ITO-kq3Gi8J9JWbH0WOiEd2zxiItpdWLWJY89C09LQncuy8iD4pjprH8H7aiGUya87L_ap88RqW2GuhhUJHNt74NW_m7y4KGn43RzotxT69wM9i-ri2HEEMQtBZRWPUtWgjSqSguENLtttWkpQrUrXBoy8TXkmvdya-d9S9QKMbaDSVa_6eVpI7uR_BAB1wRlMdbAFlVZVmzUG3HafS5P4jOA1I0nkvNChY')"
|
||||
></div>
|
||||
</div>
|
||||
|
||||
<div class="space-y-2">
|
||||
<h2 class="text-4xl font-bold tracking-tighter" data-i18n="hero.title">Vanguard Designer</h2>
|
||||
<p class="text-primary font-medium tracking-widest uppercase text-sm" data-i18n="hero.subtitle">Crafting Digital Excellence</p>
|
||||
<div class="flex gap-2 justify-center mt-4">
|
||||
<span class="px-3 py-1 rounded-full text-xs font-semibold glass border border-primary/20">UI/UX</span>
|
||||
<span class="px-3 py-1 rounded-full text-xs font-semibold glass border border-primary/20">Motion</span>
|
||||
<span class="px-3 py-1 rounded-full text-xs font-semibold glass border border-primary/20">Strategy</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<!-- About Section -->
|
||||
<section class="px-6 mb-12">
|
||||
<div class="glass-dark rounded-xl p-6 space-y-4">
|
||||
<div class="flex items-center gap-2 text-primary">
|
||||
<span class="material-symbols-outlined">person</span>
|
||||
<h3 class="font-bold text-lg" data-i18n="about.title">About Me</h3>
|
||||
</div>
|
||||
<p class="text-slate-400 leading-relaxed" data-i18n="about.description">
|
||||
A sophisticated designer specializing in high-end digital experiences with a focus on dark aesthetics, glassmorphism, and modern typography. Transforming complex problems into elegant, intuitive interfaces.
|
||||
</p>
|
||||
<div class="flex gap-4 pt-2">
|
||||
<button class="flex-1 bg-primary text-white py-3 rounded-lg font-bold shadow-lg shadow-primary/20" data-i18n="about.downloadCV">Download CV</button>
|
||||
<button class="flex-1 border border-primary/30 text-primary py-3 rounded-lg font-bold glass" data-i18n="about.contact">Contact</button>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Skills Section -->
|
||||
<section class="px-6 mb-12">
|
||||
<h3 class="text-2xl font-bold mb-6 px-1" data-i18n="skills.title">Core Expertise</h3>
|
||||
<div class="grid grid-cols-1 gap-4">
|
||||
<div class="glass-dark p-5 rounded-xl border-l-4 border-primary">
|
||||
<div class="flex justify-between items-center mb-3">
|
||||
<span class="font-bold">Visual Design</span>
|
||||
<span class="text-xs text-primary bg-primary/10 px-2 py-1 rounded">Expert</span>
|
||||
</div>
|
||||
<div class="w-full bg-slate-800 h-1.5 rounded-full overflow-hidden">
|
||||
<div class="bg-primary h-full w-[95%]"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="glass-dark p-5 rounded-xl border-l-4 border-primary">
|
||||
<div class="flex justify-between items-center mb-3">
|
||||
<span class="font-bold">Prototyping</span>
|
||||
<span class="text-xs text-primary bg-primary/10 px-2 py-1 rounded">Advanced</span>
|
||||
</div>
|
||||
<div class="w-full bg-slate-800 h-1.5 rounded-full overflow-hidden">
|
||||
<div class="bg-primary h-full w-[88%]"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="glass-dark p-5 rounded-xl border-l-4 border-primary">
|
||||
<div class="flex justify-between items-center mb-3">
|
||||
<span class="font-bold">Interaction Design</span>
|
||||
<span class="text-xs text-primary bg-primary/10 px-2 py-1 rounded">Advanced</span>
|
||||
</div>
|
||||
<div class="w-full bg-slate-800 h-1.5 rounded-full overflow-hidden">
|
||||
<div class="bg-primary h-full w-[82%]"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Projects Section -->
|
||||
<section class="px-6 mb-12">
|
||||
<div class="flex justify-between items-end mb-6 px-1">
|
||||
<h3 class="text-2xl font-bold" data-i18n="projects.title">Latest Work</h3>
|
||||
<a class="text-primary text-sm font-semibold" href="#" data-i18n="projects.viewAll">View All</a>
|
||||
</div>
|
||||
<div class="flex flex-col gap-6" id="projects-container">
|
||||
<!-- Projects will be inserted here by JavaScript -->
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Experience Timeline -->
|
||||
<section class="px-6 mb-12">
|
||||
<h3 class="text-2xl font-bold mb-6 px-1" data-i18n="experience.title">Experience</h3>
|
||||
<div class="space-y-8 relative before:absolute before:left-[11px] before:top-2 before:bottom-2 before:w-0.5 before:bg-primary/20" id="experience-container">
|
||||
<!-- Experience will be inserted here by JavaScript -->
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Bottom Navigation Bar -->
|
||||
<div class="fixed bottom-6 left-1/2 -translate-x-1/2 w-[90%] max-w-md z-50">
|
||||
<div class="glass-dark rounded-full px-6 py-3 flex items-center justify-between border border-primary/30 shadow-2xl shadow-primary/20">
|
||||
<a class="flex flex-col items-center gap-1 text-primary" href="#">
|
||||
<span class="material-symbols-outlined fill-1">home</span>
|
||||
</a>
|
||||
<a class="flex flex-col items-center gap-1 text-slate-500" href="#">
|
||||
<span class="material-symbols-outlined">work</span>
|
||||
</a>
|
||||
<a class="flex flex-col items-center gap-1 text-slate-500" href="#">
|
||||
<span class="material-symbols-outlined">grid_view</span>
|
||||
</a>
|
||||
<a class="flex flex-col items-center gap-1 text-slate-500" href="#">
|
||||
<span class="material-symbols-outlined">mail</span>
|
||||
</a>
|
||||
<a class="flex flex-col items-center gap-1 text-slate-500" href="#">
|
||||
<span class="material-symbols-outlined">person</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="/js/main.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
+280
@@ -0,0 +1,280 @@
|
||||
// Translation data
|
||||
const translations = {
|
||||
en: {
|
||||
hero: {
|
||||
title: "Vanguard Designer",
|
||||
subtitle: "Crafting Digital Excellence"
|
||||
},
|
||||
about: {
|
||||
title: "About Me",
|
||||
description: "A sophisticated designer specializing in high-end digital experiences with a focus on dark aesthetics, glassmorphism, and modern typography. Transforming complex problems into elegant, intuitive interfaces.",
|
||||
downloadCV: "Download CV",
|
||||
contact: "Contact"
|
||||
},
|
||||
skills: {
|
||||
title: "Core Expertise"
|
||||
},
|
||||
projects: {
|
||||
title: "Latest Work",
|
||||
viewAll: "View All"
|
||||
},
|
||||
experience: {
|
||||
title: "Experience"
|
||||
}
|
||||
},
|
||||
es: {
|
||||
hero: {
|
||||
title: "Diseñadora Vanguardista",
|
||||
subtitle: "Creando Excelencia Digital"
|
||||
},
|
||||
about: {
|
||||
title: "Sobre Mí",
|
||||
description: "Una diseñadora sofisticada especializada en experiencias digitales de alta gama con un enfoque en estéticas oscuras, glassmorfismo y tipografía moderna. Transformando problemas complejos en interfaces elegantes e intuitivas.",
|
||||
downloadCV: "Descargar CV",
|
||||
contact: "Contacto"
|
||||
},
|
||||
skills: {
|
||||
title: "Competencias Clave"
|
||||
},
|
||||
projects: {
|
||||
title: "Trabajos Recientes",
|
||||
viewAll: "Ver Todos"
|
||||
},
|
||||
experience: {
|
||||
title: "Experiencia"
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Projects data
|
||||
const projects = [
|
||||
{
|
||||
id: 1,
|
||||
title: {
|
||||
en: 'Luminary App',
|
||||
es: 'App Luminary'
|
||||
},
|
||||
description: {
|
||||
en: 'A fintech dashboard redesign for high-net-worth individuals.',
|
||||
es: 'Un rediseño de dashboard fintech para individuos de alto patrimonio.'
|
||||
},
|
||||
url: 'luminary-project.co',
|
||||
image: 'https://lh3.googleusercontent.com/aida-public/AB6AXuDuiRGNBP07ZrmaH7F-Q5XCG8XcmSnVisQQn-Tq4zMmt4oxFQYhnVmEZ16pqAEXpXmPJ29Xc42MlLHJHMla4Q1dMWqm2apfbWMmKQW4gH3fD35Piy_YM1xG2DEHO_es1DqVWQ1GzgmjaRrLehiCzLynVjvtlIg7p5NL8kDBwKBkPqk_nYfYK7jv1lDBrVN4AZ1Hz_j_sRfkerkDWmP2oaTSQh0gN2DLNyN-r34Nda4Dp3GWFWRjZSlivobGKj0mj0eg7QK_Fqcp5GU'
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
title: {
|
||||
en: 'Ether OS',
|
||||
es: 'Sistema Ether'
|
||||
},
|
||||
description: {
|
||||
en: 'A minimalist operating system concept based on spatial UI.',
|
||||
es: 'Un concepto de sistema operativo minimalista basado en UI espacial.'
|
||||
},
|
||||
url: 'ether-spatial.io',
|
||||
image: 'https://lh3.googleusercontent.com/aida-public/AB6AXuDvWd-Z_6rj37HlgWlrmx1VJHroq2bg6Pv0atKO0GnAF5_74-yfWaASnLWaWh5J6NiThTvt1W3avgzNI3bOpEG0GoVeYjwZxqMwZZRIiaaODFunpArG-H2otP37dkbfuWzOP_QoEWn6INmZ8YFm50k3YDvoCyZNrnv1dETjWlyg2cok9MP4IIqJLDVxp5Yi32R9BUDgxGlVWLUceUR71hTQRKQqKI9jsQPH7E0Y1OLKeCOZ1Wo-RKabzipc2Vtvmo6RtGvT2X0VoSE'
|
||||
}
|
||||
];
|
||||
|
||||
// Experience data
|
||||
const experience = [
|
||||
{
|
||||
period: '2022 - Present',
|
||||
title: {
|
||||
en: 'Senior UX Designer',
|
||||
es: 'Diseñadora UX Senior'
|
||||
},
|
||||
company: 'Studio Vanta • Remote',
|
||||
description: {
|
||||
en: 'Leading the design language for next-gen SaaS products and immersive web experiences.',
|
||||
es: 'Liderando el lenguaje de diseño para productos SaaS de próxima generación y experiencias web inmersivas.'
|
||||
},
|
||||
isActive: true,
|
||||
},
|
||||
{
|
||||
period: '2020 - 2022',
|
||||
title: {
|
||||
en: 'Product Designer',
|
||||
es: 'Diseñadora de Producto'
|
||||
},
|
||||
company: 'Flow Digital • Madrid',
|
||||
description: {
|
||||
en: 'Conceptualized and launched 4 mobile applications with over 1M combined downloads.',
|
||||
es: 'Conceptualicé y lancé 4 aplicaciones móviles con más de 1M de descargas combinadas.'
|
||||
},
|
||||
isActive: false,
|
||||
}
|
||||
];
|
||||
|
||||
// Theme Management
|
||||
class ThemeManager {
|
||||
constructor() {
|
||||
this.theme = localStorage.getItem('theme') || this.getSystemPreference();
|
||||
this.init();
|
||||
}
|
||||
|
||||
getSystemPreference() {
|
||||
return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';
|
||||
}
|
||||
|
||||
init() {
|
||||
this.applyTheme();
|
||||
this.setupEventListeners();
|
||||
}
|
||||
|
||||
applyTheme() {
|
||||
document.documentElement.classList.toggle('dark', this.theme === 'dark');
|
||||
this.updateThemeIcon();
|
||||
}
|
||||
|
||||
updateThemeIcon() {
|
||||
const icon = document.querySelector('#theme-toggle .material-symbols-outlined');
|
||||
if (icon) {
|
||||
icon.textContent = this.theme === 'dark' ? 'light_mode' : 'dark_mode';
|
||||
}
|
||||
}
|
||||
|
||||
toggle() {
|
||||
this.theme = this.theme === 'dark' ? 'light' : 'dark';
|
||||
localStorage.setItem('theme', this.theme);
|
||||
this.applyTheme();
|
||||
}
|
||||
|
||||
setupEventListeners() {
|
||||
const themeToggle = document.getElementById('theme-toggle');
|
||||
if (themeToggle) {
|
||||
themeToggle.addEventListener('click', () => this.toggle());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Language Management
|
||||
class LanguageManager {
|
||||
constructor() {
|
||||
this.currentLang = localStorage.getItem('language') || 'en';
|
||||
this.init();
|
||||
}
|
||||
|
||||
init() {
|
||||
this.applyLanguage();
|
||||
this.setupEventListeners();
|
||||
this.renderDynamicContent();
|
||||
}
|
||||
|
||||
applyLanguage() {
|
||||
document.documentElement.lang = this.currentLang;
|
||||
|
||||
// Update all elements with data-i18n attribute
|
||||
document.querySelectorAll('[data-i18n]').forEach(element => {
|
||||
const key = element.getAttribute('data-i18n');
|
||||
const translation = this.getTranslation(key);
|
||||
if (translation) {
|
||||
element.textContent = translation;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
getTranslation(key) {
|
||||
const keys = key.split('.');
|
||||
let value = translations[this.currentLang];
|
||||
|
||||
for (const k of keys) {
|
||||
value = value?.[k];
|
||||
}
|
||||
|
||||
return value || key;
|
||||
}
|
||||
|
||||
toggle() {
|
||||
this.currentLang = this.currentLang === 'en' ? 'es' : 'en';
|
||||
localStorage.setItem('language', this.currentLang);
|
||||
this.applyLanguage();
|
||||
this.renderDynamicContent();
|
||||
}
|
||||
|
||||
renderDynamicContent() {
|
||||
this.renderProjects();
|
||||
this.renderExperience();
|
||||
}
|
||||
|
||||
renderProjects() {
|
||||
const container = document.getElementById('projects-container');
|
||||
if (!container) return;
|
||||
|
||||
container.innerHTML = projects.map(project => `
|
||||
<div class="group relative rounded-xl overflow-hidden glass-dark">
|
||||
<div
|
||||
class="h-48 bg-cover bg-center"
|
||||
alt="Abstract purple 3D geometric shapes background"
|
||||
style="background-image: url('${project.image}')"
|
||||
></div>
|
||||
<div class="p-5">
|
||||
<h4 class="text-xl font-bold mb-1">${project.title[this.currentLang]}</h4>
|
||||
<p class="text-slate-400 text-sm mb-4">${project.description[this.currentLang]}</p>
|
||||
<div class="flex items-center gap-2">
|
||||
<span class="material-symbols-outlined text-primary text-sm">link</span>
|
||||
<span class="text-xs font-mono uppercase tracking-widest">${project.url}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`).join('');
|
||||
}
|
||||
|
||||
renderExperience() {
|
||||
const container = document.getElementById('experience-container');
|
||||
if (!container) return;
|
||||
|
||||
container.innerHTML = `
|
||||
<div class="space-y-8 relative before:absolute before:left-[11px] before:top-2 before:bottom-2 before:w-0.5 before:bg-primary/20">
|
||||
${experience.map(job => `
|
||||
<div class="relative pl-8">
|
||||
<div class="absolute left-0 top-1.5 w-[24px] h-[24px] rounded-full bg-background-dark border-2 flex items-center justify-center ${job.isActive ? 'border-primary' : 'border-primary/30'}">
|
||||
<div class="w-2 h-2 rounded-full ${job.isActive ? 'bg-primary' : 'bg-primary/30'}"></div>
|
||||
</div>
|
||||
<span class="text-xs font-bold text-primary mb-1 block uppercase tracking-tighter ${!job.isActive ? 'text-slate-500' : ''}">${job.period}</span>
|
||||
<h4 class="text-lg font-bold">${job.title[this.currentLang]}</h4>
|
||||
<p class="text-slate-400 text-sm">${job.company}</p>
|
||||
<p class="mt-2 text-sm leading-relaxed text-slate-500">${job.description[this.currentLang]}</p>
|
||||
</div>
|
||||
`).join('')}
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
setupEventListeners() {
|
||||
const languageToggle = document.getElementById('language-toggle');
|
||||
if (languageToggle) {
|
||||
languageToggle.addEventListener('click', () => this.toggle());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Initialize everything when DOM is ready
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
new ThemeManager();
|
||||
new LanguageManager();
|
||||
|
||||
// Add smooth scrolling
|
||||
document.querySelectorAll('a[href^="#"]').forEach(anchor => {
|
||||
anchor.addEventListener('click', function (e) {
|
||||
e.preventDefault();
|
||||
const target = document.querySelector(this.getAttribute('href'));
|
||||
if (target) {
|
||||
target.scrollIntoView({ behavior: 'smooth' });
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Add fade-in animation to sections
|
||||
const observer = new IntersectionObserver((entries) => {
|
||||
entries.forEach(entry => {
|
||||
if (entry.isIntersecting) {
|
||||
entry.target.classList.add('animate-fade-in');
|
||||
}
|
||||
});
|
||||
}, { threshold: 0.1 });
|
||||
|
||||
document.querySelectorAll('section').forEach(section => {
|
||||
observer.observe(section);
|
||||
});
|
||||
});
|
||||
@@ -1,21 +0,0 @@
|
||||
{
|
||||
"name": "personal-portfolio",
|
||||
"type": "module",
|
||||
"version": "0.0.1",
|
||||
"engines": {
|
||||
"node": ">=22.12.0"
|
||||
},
|
||||
"scripts": {
|
||||
"dev": "astro dev",
|
||||
"build": "astro build",
|
||||
"preview": "astro preview",
|
||||
"astro": "astro"
|
||||
},
|
||||
"dependencies": {
|
||||
"@astrojs/check": "^0.9.7",
|
||||
"@tailwindcss/vite": "^4.2.1",
|
||||
"astro": "^6.0.4",
|
||||
"astro-i18n": "^2.2.4",
|
||||
"tailwindcss": "^4.2.1"
|
||||
}
|
||||
}
|
||||
Generated
-3967
File diff suppressed because it is too large
Load Diff
-115
@@ -1,115 +0,0 @@
|
||||
export const translations = {
|
||||
en: {
|
||||
nav: {
|
||||
home: 'Home',
|
||||
projects: 'Projects',
|
||||
stack: 'Stack',
|
||||
contact: 'Contact',
|
||||
},
|
||||
hero: {
|
||||
available: 'Available for Projects',
|
||||
title: 'Product Designer &',
|
||||
gradientText: 'Tech Strategist',
|
||||
description: 'Fusing avant-garde aesthetics with technical functionality to create high-impact digital experiences.',
|
||||
startProject: 'Start a project',
|
||||
},
|
||||
about: {
|
||||
title: 'About Me',
|
||||
description: 'Specialized in transforming <span class="font-bold">complex infrastructures</span> into intuitive interfaces. My approach combines user-centered design with a solid <span class="italic">strategic vision</span> of product.',
|
||||
},
|
||||
projects: {
|
||||
title: 'Selected Works',
|
||||
subtitle: 'Featured case studies',
|
||||
viewAll: 'View All',
|
||||
viewProject: 'View Project',
|
||||
},
|
||||
techStack: {
|
||||
title: 'Tech Curated Stack',
|
||||
categories: {
|
||||
design: {
|
||||
title: 'Design',
|
||||
items: 'Figma, Framer, Adobe CC, Prototyping.',
|
||||
},
|
||||
frontend: {
|
||||
title: 'Frontend',
|
||||
items: 'React, Tailwind, Next.js, Typescript.',
|
||||
},
|
||||
stack: {
|
||||
title: 'Stack',
|
||||
items: 'PostgreSQL, Supabase, Node.js, API Design.',
|
||||
},
|
||||
product: {
|
||||
title: 'Product',
|
||||
items: 'Agile, SCRUM, Notion, Linear, Strategy.',
|
||||
},
|
||||
},
|
||||
},
|
||||
cta: {
|
||||
title: 'Ready to scale?',
|
||||
description: "Let's work together to take your product to the next level with world-class design.",
|
||||
letsTalk: "Let's talk",
|
||||
},
|
||||
experience: {
|
||||
title: 'Experience',
|
||||
present: 'Present',
|
||||
},
|
||||
},
|
||||
es: {
|
||||
nav: {
|
||||
home: 'Inicio',
|
||||
projects: 'Proyectos',
|
||||
stack: 'Stack',
|
||||
contact: 'Contacto',
|
||||
},
|
||||
hero: {
|
||||
available: 'Disponible para Proyectos',
|
||||
title: 'Diseñadora de Producto &',
|
||||
gradientText: 'Estratega Tecnológica',
|
||||
description: 'Fusionando estética vanguardista con funcionalidad técnica para crear experiencias digitales de alto impacto.',
|
||||
startProject: 'Iniciar proyecto',
|
||||
},
|
||||
about: {
|
||||
title: 'Sobre mí',
|
||||
description: 'Especializada en transformar <span class="font-bold">infraestructuras complejas</span> en interfaces intuitivas. Mi enfoque combina el diseño centrado en el usuario con una sólida <span class="italic">visión estratégica</span> de producto.',
|
||||
},
|
||||
projects: {
|
||||
title: 'Trabajos Seleccionados',
|
||||
subtitle: 'Casos de estudio destacados',
|
||||
viewAll: 'Ver Todos',
|
||||
viewProject: 'Ver Proyecto',
|
||||
},
|
||||
techStack: {
|
||||
title: 'Stack Tecnológico Curado',
|
||||
categories: {
|
||||
design: {
|
||||
title: 'Diseño',
|
||||
items: 'Figma, Framer, Adobe CC, Prototipado.',
|
||||
},
|
||||
frontend: {
|
||||
title: 'Frontend',
|
||||
items: 'React, Tailwind, Next.js, Typescript.',
|
||||
},
|
||||
stack: {
|
||||
title: 'Stack',
|
||||
items: 'PostgreSQL, Supabase, Node.js, Diseño API.',
|
||||
},
|
||||
product: {
|
||||
title: 'Producto',
|
||||
items: 'Agile, SCRUM, Notion, Linear, Estrategia.',
|
||||
},
|
||||
},
|
||||
},
|
||||
cta: {
|
||||
title: '¿Listo para escalar?',
|
||||
description: 'Trabajemos juntos para llevar tu producto al siguiente nivel con diseño de clase mundial.',
|
||||
letsTalk: 'Hablemos',
|
||||
},
|
||||
experience: {
|
||||
title: 'Experiencia',
|
||||
present: 'Actualidad',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
export type Language = keyof typeof translations;
|
||||
export type TranslationKey = keyof typeof translations.en;
|
||||
@@ -1,29 +0,0 @@
|
||||
---
|
||||
export interface Props {
|
||||
title: string;
|
||||
}
|
||||
|
||||
const { title } = Astro.props;
|
||||
---
|
||||
|
||||
<!doctype html>
|
||||
<html lang="en" class="light">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="description" content="Astro description" />
|
||||
<meta name="viewport" content="width=device-width" />
|
||||
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
|
||||
<meta name="generator" content={Astro.generator} />
|
||||
<title>{title}</title>
|
||||
</head>
|
||||
<body class="bg-background-light dark:bg-background-dark font-display text-slate-900 dark:text-slate-100 min-h-screen pb-24">
|
||||
<script src="/scripts/theme-toggle.js" is:inline />
|
||||
<slot />
|
||||
</body>
|
||||
</html>
|
||||
|
||||
<style>
|
||||
isolate {
|
||||
isolation: isolate;
|
||||
}
|
||||
</style>
|
||||
@@ -1,217 +0,0 @@
|
||||
---
|
||||
import Layout from '../layouts/Layout.astro';
|
||||
import '../styles/global.css';
|
||||
import { translations, type Language } from '../i18n/ui';
|
||||
|
||||
const lang: Language = 'en';
|
||||
const t = translations[lang];
|
||||
|
||||
const projects = [
|
||||
{
|
||||
id: 1,
|
||||
title: 'Luminary App',
|
||||
description: 'A fintech dashboard redesign for high-net-worth individuals.',
|
||||
url: 'luminary-project.co',
|
||||
image: 'https://lh3.googleusercontent.com/aida-public/AB6AXuDuiRGNBP07ZrmaH7F-Q5XCG8XcmSnVisQQn-Tq4zMmt4oxFQYhnVmEZ16pqAEXpXmPJ29Xc42MlLHJHMla4Q1dMWqm2apfbWMmKQW4gH3fD35Piy_YM1xG2DEHO_es1DqVWQ1GzgmjaRrLehiCzLynVjvtlIg7p5NL8kDBwKBkPqk_nYfYK7jv1lDBrVN4AZ1Hz_j_sRfkerkDWmP2oaTSQh0gN2DLNyN-r34Nda4Dp3GWFWRjZSlivobGKj0mj0eg7QK_Fqcp5GU',
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
title: 'Ether OS',
|
||||
description: 'A minimalist operating system concept based on spatial UI.',
|
||||
url: 'ether-spatial.io',
|
||||
image: 'https://lh3.googleusercontent.com/aida-public/AB6AXuDvWd-Z_6rj37HlgWlrmx1VJHroq2bg6Pv0atKO0GnAF5_74-yfWaASnLWaWh5J6NiThTvt1W3avgzNI3bOpEG0GoVeYjwZxqMwZZRIiaaODFunpArG-H2otP37dkbfuWzOP_QoEWn6INmZ8YFm50k3YDvoCyZNrnv1dETjWlyg2cok9MP4IIqJLDVxp5Yi32R9BUDgxGlVWLUceUR71hTQRKQqKI9jsQPH7E0Y1OLKeCOZ1Wo-RKabzipc2Vtvmo6RtGvT2X0VoSE',
|
||||
},
|
||||
];
|
||||
|
||||
const skills = [
|
||||
{ name: 'Visual Design', level: 95, category: 'Expert' },
|
||||
{ name: 'Prototyping', level: 88, category: 'Advanced' },
|
||||
{ name: 'Interaction Design', level: 82, category: 'Advanced' },
|
||||
];
|
||||
|
||||
const experience = [
|
||||
{
|
||||
period: '2022 - Present',
|
||||
title: 'Senior UX Designer',
|
||||
company: 'Studio Vanta • Remote',
|
||||
description: 'Leading the design language for next-gen SaaS products and immersive web experiences.',
|
||||
isActive: true,
|
||||
},
|
||||
{
|
||||
period: '2020 - 2022',
|
||||
title: 'Product Designer',
|
||||
company: 'Flow Digital • Madrid',
|
||||
description: 'Conceptualized and launched 4 mobile applications with over 1M combined downloads.',
|
||||
isActive: false,
|
||||
},
|
||||
];
|
||||
---
|
||||
|
||||
<Layout title="Itziar ZG - Vanguard CV">
|
||||
<!-- Top Navigation -->
|
||||
<nav class="sticky top-0 z-50 flex items-center justify-between p-4 glass-dark">
|
||||
<div class="flex items-center gap-2">
|
||||
<span class="material-symbols-outlined text-primary text-3xl">deployed_code</span>
|
||||
<h1 class="text-xl font-bold tracking-tight">Itziar ZG</h1>
|
||||
</div>
|
||||
<div class="flex items-center gap-2">
|
||||
<button
|
||||
onclick="toggleLanguage()"
|
||||
class="p-2 rounded-full hover:bg-primary/10 transition-colors"
|
||||
>
|
||||
<span class="material-symbols-outlined text-primary">translate</span>
|
||||
</button>
|
||||
<button
|
||||
onclick="toggleTheme()"
|
||||
class="p-2 rounded-full hover:bg-primary/10 transition-colors"
|
||||
>
|
||||
<span class="material-symbols-outlined text-primary">dark_mode</span>
|
||||
</button>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<!-- Hero Section -->
|
||||
<header class="relative px-6 pt-10 pb-16 overflow-hidden">
|
||||
<div class="absolute top-0 right-0 -z-10 w-64 h-64 bg-primary/20 rounded-full blur-[100px]"></div>
|
||||
<div class="absolute bottom-0 left-0 -z-10 w-48 h-48 bg-purple-600/10 rounded-full blur-[80px]"></div>
|
||||
|
||||
<div class="flex flex-col items-center text-center gap-6">
|
||||
<div class="relative p-1 rounded-full bg-gradient-to-tr from-primary to-purple-400">
|
||||
<div
|
||||
class="w-32 h-32 rounded-full bg-cover bg-center border-4 border-background-dark"
|
||||
data-alt="Professional portrait of a female digital designer"
|
||||
style="background-image: url('https://lh3.googleusercontent.com/aida-public/AB6AXuD6WeB0nJf-ZCuFJ6oa6vOkhHSa7HvieIuXVDVhw_U7ITO-kq3Gi8J9JWbH0WOiEd2zxiItpdWLWJY89C09LQncuy8iD4pjprH8H7aiGUya87L_ap88RqW2GuhhUJHNt74NW_m7y4KGn43RzotxT69wM9i-ri2HEEMQtBZRWPUtWgjSqSguENLtttWkpQrUrXBoy8TXkmvdya-d9S9QKMbaDSVa_6eVpI7uR_BAB1wRlMdbAFlVZVmzUG3HafS5P4jOA1I0nkvNChY')"
|
||||
></div>
|
||||
</div>
|
||||
|
||||
<div class="space-y-2">
|
||||
<h2 class="text-4xl font-bold tracking-tighter">Vanguard Designer</h2>
|
||||
<p class="text-primary font-medium tracking-widest uppercase text-sm">Crafting Digital Excellence</p>
|
||||
<div class="flex gap-2 justify-center mt-4">
|
||||
<span class="px-3 py-1 rounded-full text-xs font-semibold glass border border-primary/20">UI/UX</span>
|
||||
<span class="px-3 py-1 rounded-full text-xs font-semibold glass border border-primary/20">Motion</span>
|
||||
<span class="px-3 py-1 rounded-full text-xs font-semibold glass border border-primary/20">Strategy</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<!-- About Section -->
|
||||
<section class="px-6 mb-12">
|
||||
<div class="glass-dark rounded-xl p-6 space-y-4">
|
||||
<div class="flex items-center gap-2 text-primary">
|
||||
<span class="material-symbols-outlined">person</span>
|
||||
<h3 class="font-bold text-lg">About Me</h3>
|
||||
</div>
|
||||
<p class="text-slate-400 leading-relaxed">
|
||||
A sophisticated designer specializing in high-end digital experiences with a focus on dark aesthetics, glassmorphism, and modern typography. Transforming complex problems into elegant, intuitive interfaces.
|
||||
</p>
|
||||
<div class="flex gap-4 pt-2">
|
||||
<button class="flex-1 bg-primary text-white py-3 rounded-lg font-bold shadow-lg shadow-primary/20">Download CV</button>
|
||||
<button class="flex-1 border border-primary/30 text-primary py-3 rounded-lg font-bold glass">Contact</button>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Skills Section -->
|
||||
<section class="px-6 mb-12">
|
||||
<h3 class="text-2xl font-bold mb-6 px-1">Core Expertise</h3>
|
||||
<div class="grid grid-cols-1 gap-4">
|
||||
<div class="glass-dark p-5 rounded-xl border-l-4 border-primary">
|
||||
<div class="flex justify-between items-center mb-3">
|
||||
<span class="font-bold">Visual Design</span>
|
||||
<span class="text-xs text-primary bg-primary/10 px-2 py-1 rounded">Expert</span>
|
||||
</div>
|
||||
<div class="w-full bg-slate-800 h-1.5 rounded-full overflow-hidden">
|
||||
<div class="bg-primary h-full w-[95%]"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="glass-dark p-5 rounded-xl border-l-4 border-primary">
|
||||
<div class="flex justify-between items-center mb-3">
|
||||
<span class="font-bold">Prototyping</span>
|
||||
<span class="text-xs text-primary bg-primary/10 px-2 py-1 rounded">Advanced</span>
|
||||
</div>
|
||||
<div class="w-full bg-slate-800 h-1.5 rounded-full overflow-hidden">
|
||||
<div class="bg-primary h-full w-[88%]"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="glass-dark p-5 rounded-xl border-l-4 border-primary">
|
||||
<div class="flex justify-between items-center mb-3">
|
||||
<span class="font-bold">Interaction Design</span>
|
||||
<span class="text-xs text-primary bg-primary/10 px-2 py-1 rounded">Advanced</span>
|
||||
</div>
|
||||
<div class="w-full bg-slate-800 h-1.5 rounded-full overflow-hidden">
|
||||
<div class="bg-primary h-full w-[82%]"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Projects Section -->
|
||||
<section class="px-6 mb-12">
|
||||
<div class="flex justify-between items-end mb-6 px-1">
|
||||
<h3 class="text-2xl font-bold">Latest Work</h3>
|
||||
<a class="text-primary text-sm font-semibold" href="#">View All</a>
|
||||
</div>
|
||||
<div class="flex flex-col gap-6">
|
||||
{projects.map((project) => (
|
||||
<div class="group relative rounded-xl overflow-hidden glass-dark">
|
||||
<div
|
||||
class="h-48 bg-cover bg-center"
|
||||
data-alt="Abstract purple 3D geometric shapes background"
|
||||
style={`background-image: url('${project.image}')`}
|
||||
></div>
|
||||
<div class="p-5">
|
||||
<h4 class="text-xl font-bold mb-1">{project.title}</h4>
|
||||
<p class="text-slate-400 text-sm mb-4">{project.description}</p>
|
||||
<div class="flex items-center gap-2">
|
||||
<span class="material-symbols-outlined text-primary text-sm">link</span>
|
||||
<span class="text-xs font-mono uppercase tracking-widest">{project.url}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Experience Timeline -->
|
||||
<section class="px-6 mb-12">
|
||||
<h3 class="text-2xl font-bold mb-6 px-1">Experience</h3>
|
||||
<div class="space-y-8 relative before:absolute before:left-[11px] before:top-2 before:bottom-2 before:w-0.5 before:bg-primary/20">
|
||||
{experience.map((job) => (
|
||||
<div class="relative pl-8">
|
||||
<div class="absolute left-0 top-1.5 w-[24px] h-[24px] rounded-full bg-background-dark border-2 flex items-center justify-center" class:border-primary={job.isActive} class:border-primary/30={!job.isActive}>
|
||||
<div class="w-2 h-2 rounded-full bg-primary" class:bg-primary/30={!job.isActive}></div>
|
||||
</div>
|
||||
<span class="text-xs font-bold text-primary mb-1 block uppercase tracking-tighter" class:text-slate-500={!job.isActive}>{job.period}</span>
|
||||
<h4 class="text-lg font-bold">{job.title}</h4>
|
||||
<p class="text-slate-400 text-sm">{job.company}</p>
|
||||
<p class="mt-2 text-sm leading-relaxed text-slate-500">{job.description}</p>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Bottom Navigation Bar -->
|
||||
<div class="fixed bottom-6 left-1/2 -translate-x-1/2 w-[90%] max-w-md z-50">
|
||||
<div class="glass-dark rounded-full px-6 py-3 flex items-center justify-between border border-primary/30 shadow-2xl shadow-primary/20">
|
||||
<a class="flex flex-col items-center gap-1 text-primary" href="#">
|
||||
<span class="material-symbols-outlined fill-1">home</span>
|
||||
</a>
|
||||
<a class="flex flex-col items-center gap-1 text-slate-500" href="#">
|
||||
<span class="material-symbols-outlined">work</span>
|
||||
</a>
|
||||
<a class="flex flex-col items-center gap-1 text-slate-500" href="#">
|
||||
<span class="material-symbols-outlined">grid_view</span>
|
||||
</a>
|
||||
<a class="flex flex-col items-center gap-1 text-slate-500" href="#">
|
||||
<span class="material-symbols-outlined">mail</span>
|
||||
</a>
|
||||
<a class="flex flex-col items-center gap-1 text-slate-500" href="#">
|
||||
<span class="material-symbols-outlined">person</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="/scripts/language-toggle.js" is:inline />
|
||||
</Layout>
|
||||
@@ -1,74 +0,0 @@
|
||||
---
|
||||
import Layout from '../layouts/Layout.astro';
|
||||
---
|
||||
|
||||
<Layout title="Under Construction - Itziar ZG">
|
||||
<div class="min-h-screen flex items-center justify-center px-6">
|
||||
<div class="text-center space-y-8 max-w-2xl">
|
||||
<!-- Construction Icon -->
|
||||
<div class="flex justify-center">
|
||||
<div class="relative">
|
||||
<div class="w-32 h-32 bg-primary/20 rounded-full flex items-center justify-center animate-pulse">
|
||||
<span class="material-symbols-outlined text-6xl text-primary">construction</span>
|
||||
</div>
|
||||
<div class="absolute -top-2 -right-2 w-8 h-8 bg-yellow-400 rounded-full flex items-center justify-center">
|
||||
<span class="material-symbols-outlined text-sm text-slate-900">priority_high</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Main Content -->
|
||||
<div class="space-y-4">
|
||||
<h1 class="text-4xl font-bold tracking-tighter text-gradient">Under Construction</h1>
|
||||
<p class="text-xl text-slate-600 dark:text-slate-400">
|
||||
We're building something amazing!
|
||||
</p>
|
||||
<p class="text-slate-500 dark:text-slate-500 leading-relaxed">
|
||||
This portfolio is currently under development. I'm working hard to bring you an exceptional digital experience with cutting-edge design and innovative features.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<!-- Progress Indicator -->
|
||||
<div class="space-y-3">
|
||||
<div class="flex justify-between text-sm text-slate-500">
|
||||
<span>Development Progress</span>
|
||||
<span>85%</span>
|
||||
</div>
|
||||
<div class="w-full bg-slate-200 dark:bg-slate-700 h-2 rounded-full overflow-hidden">
|
||||
<div class="bg-primary h-full w-[85%] rounded-full animate-pulse"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Contact Options -->
|
||||
<div class="space-y-4">
|
||||
<p class="text-sm text-slate-500">
|
||||
Want to get in touch while I finish building?
|
||||
</p>
|
||||
<div class="flex gap-4 justify-center">
|
||||
<a href="mailto:contact@itziarzg.com" class="glass-dark px-6 py-3 rounded-lg text-primary font-medium flex items-center gap-2 hover:bg-primary/10 transition-colors">
|
||||
<span class="material-symbols-outlined">email</span>
|
||||
Email Me
|
||||
</a>
|
||||
<a href="#" class="glass-dark px-6 py-3 rounded-lg text-primary font-medium flex items-center gap-2 hover:bg-primary/10 transition-colors">
|
||||
<span class="material-symbols-outlined">schedule</span>
|
||||
Check Back Soon
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Footer Info -->
|
||||
<div class="pt-8 border-t border-slate-200 dark:border-slate-700">
|
||||
<p class="text-xs text-slate-400">
|
||||
© 2026 Itziar ZG • Portfolio coming soon • Built with Astro & Tailwind CSS
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Animated Background Elements -->
|
||||
<div class="fixed inset-0 -z-10 overflow-hidden">
|
||||
<div class="absolute top-20 left-20 w-64 h-64 bg-primary/10 rounded-full blur-3xl animate-pulse"></div>
|
||||
<div class="absolute bottom-20 right-20 w-48 h-48 bg-purple-500/10 rounded-full blur-2xl animate-pulse" style="animation-delay: 1s;"></div>
|
||||
<div class="absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 w-96 h-96 bg-primary/5 rounded-full blur-3xl animate-pulse" style="animation-delay: 2s;"></div>
|
||||
</div>
|
||||
</Layout>
|
||||
@@ -1,20 +0,0 @@
|
||||
(function () {
|
||||
const savedLang = localStorage.getItem("language") || "en";
|
||||
const htmlLang = document.documentElement.lang || "en";
|
||||
const currentLang = savedLang || htmlLang;
|
||||
|
||||
window.setLanguage = function (lang) {
|
||||
localStorage.setItem("language", lang);
|
||||
location.reload();
|
||||
};
|
||||
|
||||
window.getCurrentLanguage = function () {
|
||||
return localStorage.getItem("language") || "en";
|
||||
};
|
||||
|
||||
window.toggleLanguage = function () {
|
||||
const currentLang = getCurrentLanguage();
|
||||
const newLang = currentLang === "en" ? "es" : "en";
|
||||
setLanguage(newLang);
|
||||
};
|
||||
})();
|
||||
@@ -1,15 +0,0 @@
|
||||
(function() {
|
||||
const theme = localStorage.getItem('theme');
|
||||
const systemPrefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
|
||||
const initialTheme = theme || (systemPrefersDark ? 'dark' : 'light');
|
||||
|
||||
document.documentElement.classList.toggle('dark', initialTheme === 'dark');
|
||||
|
||||
window.toggleTheme = function() {
|
||||
const currentTheme = document.documentElement.classList.contains('dark') ? 'dark' : 'light';
|
||||
const newTheme = currentTheme === 'dark' ? 'light' : 'dark';
|
||||
|
||||
document.documentElement.classList.toggle('dark');
|
||||
localStorage.setItem('theme', newTheme);
|
||||
};
|
||||
})();
|
||||
@@ -1,41 +0,0 @@
|
||||
@import "tailwindcss";
|
||||
@import url("https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@300;400;500;600;700&display=swap");
|
||||
@import url("https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:wght@100..700,0..1&display=swap");
|
||||
|
||||
:root {
|
||||
--primary: #8c2bee;
|
||||
--background-light: #f7f6f8;
|
||||
--background-dark: #0d0614;
|
||||
}
|
||||
|
||||
.glass {
|
||||
background: rgba(140, 43, 238, 0.05);
|
||||
backdrop-filter: blur(12px);
|
||||
-webkit-backdrop-filter: blur(12px);
|
||||
border: 1px solid rgba(140, 43, 238, 0.1);
|
||||
}
|
||||
|
||||
.dark .glass {
|
||||
background: rgba(140, 43, 238, 0.05);
|
||||
backdrop-filter: blur(12px);
|
||||
-webkit-backdrop-filter: blur(12px);
|
||||
border: 1px solid rgba(140, 43, 238, 0.1);
|
||||
}
|
||||
|
||||
.glass-dark {
|
||||
background: rgba(20, 10, 30, 0.6);
|
||||
backdrop-filter: blur(16px);
|
||||
-webkit-backdrop-filter: blur(16px);
|
||||
border: 1px solid rgba(140, 43, 238, 0.2);
|
||||
}
|
||||
|
||||
.text-gradient {
|
||||
background: linear-gradient(135deg, #8c2bee 0%, #d4a5ff 100%);
|
||||
-webkit-background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
background-clip: text;
|
||||
}
|
||||
|
||||
body {
|
||||
min-height: max(884px, 100dvh);
|
||||
}
|
||||
+552
@@ -0,0 +1,552 @@
|
||||
/* Reset and Base Styles */
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
/* CSS Custom Properties for Theming */
|
||||
:root {
|
||||
--primary: #8c2bee;
|
||||
--primary-light: #d4a5ff;
|
||||
--background-light: #f7f6f8;
|
||||
--background-dark: #0d0614;
|
||||
--surface-light: #ffffff;
|
||||
--surface-dark: #1a0f2e;
|
||||
--text-primary-light: #0f172a;
|
||||
--text-primary-dark: #f8fafc;
|
||||
--text-secondary-light: #64748b;
|
||||
--text-secondary-dark: #94a3b8;
|
||||
--border-light: #e2e8f0;
|
||||
--border-dark: #334155;
|
||||
--glass-bg-light: rgba(140, 43, 238, 0.05);
|
||||
--glass-bg-dark: rgba(20, 10, 30, 0.6);
|
||||
--glass-border-light: rgba(140, 43, 238, 0.1);
|
||||
--glass-border-dark: rgba(140, 43, 238, 0.2);
|
||||
}
|
||||
|
||||
/* Typography */
|
||||
body {
|
||||
font-family: 'Space Grotesk', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
||||
line-height: 1.6;
|
||||
min-height: max(884px, 100dvh);
|
||||
}
|
||||
|
||||
.font-display {
|
||||
font-family: 'Space Grotesk', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
||||
}
|
||||
|
||||
/* Material Symbols */
|
||||
.material-symbols-outlined {
|
||||
font-variation-settings:
|
||||
'FILL' 0,
|
||||
'wght' 400,
|
||||
'GRAD' 0,
|
||||
'opsz' 24;
|
||||
}
|
||||
|
||||
.material-symbols-outlined.fill-1 {
|
||||
font-variation-settings:
|
||||
'FILL' 1,
|
||||
'wght' 400,
|
||||
'GRAD' 0,
|
||||
'opsz' 24;
|
||||
}
|
||||
|
||||
/* Layout */
|
||||
.sticky {
|
||||
position: sticky;
|
||||
}
|
||||
|
||||
.top-0 {
|
||||
top: 0;
|
||||
}
|
||||
|
||||
.z-50 {
|
||||
z-index: 50;
|
||||
}
|
||||
|
||||
.flex {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.items-center {
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.justify-between {
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.justify-center {
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.justify-end {
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
.gap-1 { gap: 0.25rem; }
|
||||
.gap-2 { gap: 0.5rem; }
|
||||
.gap-4 { gap: 1rem; }
|
||||
.gap-6 { gap: 1.5rem; }
|
||||
|
||||
/* Spacing */
|
||||
.p-1 { padding: 0.25rem; }
|
||||
.p-2 { padding: 0.5rem; }
|
||||
.p-3 { padding: 0.75rem; }
|
||||
.p-4 { padding: 1rem; }
|
||||
.p-5 { padding: 1.25rem; }
|
||||
.p-6 { padding: 1.5rem; }
|
||||
|
||||
.px-1 { padding-left: 0.25rem; padding-right: 0.25rem; }
|
||||
.px-2 { padding-left: 0.5rem; padding-right: 0.5rem; }
|
||||
.px-3 { padding-left: 0.75rem; padding-right: 0.75rem; }
|
||||
.px-6 { padding-left: 1.5rem; padding-right: 1.5rem; }
|
||||
|
||||
.py-1 { padding-top: 0.25rem; padding-bottom: 0.25rem; }
|
||||
.py-3 { padding-top: 0.75rem; padding-bottom: 0.75rem; }
|
||||
|
||||
.pt-10 { padding-top: 2.5rem; }
|
||||
.pt-16 { padding-top: 4rem; }
|
||||
.pb-16 { padding-bottom: 4rem; }
|
||||
.pb-24 { padding-bottom: 6rem; }
|
||||
|
||||
.mb-1 { margin-bottom: 0.25rem; }
|
||||
.mb-2 { margin-bottom: 0.5rem; }
|
||||
.mb-4 { margin-bottom: 1rem; }
|
||||
.mb-6 { margin-bottom: 1.5rem; }
|
||||
.mb-8 { margin-bottom: 2rem; }
|
||||
.mb-12 { margin-bottom: 3rem; }
|
||||
|
||||
.mt-2 { margin-top: 0.5rem; }
|
||||
.mt-4 { margin-top: 1rem; }
|
||||
|
||||
.ml-8 { margin-left: 2rem; }
|
||||
|
||||
/* Flexbox */
|
||||
.flex-col {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.flex-1 {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
/* Grid */
|
||||
.grid {
|
||||
display: grid;
|
||||
}
|
||||
|
||||
.grid-cols-1 {
|
||||
grid-template-columns: repeat(1, minmax(0, 1fr));
|
||||
}
|
||||
|
||||
/* Positioning */
|
||||
.relative {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.absolute {
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
.fixed {
|
||||
position: fixed;
|
||||
}
|
||||
|
||||
.top-0 { top: 0; }
|
||||
.right-0 { right: 0; }
|
||||
.bottom-0 { bottom: 0; }
|
||||
.left-0 { left: 0; }
|
||||
.left-1\/2 { left: 50%; }
|
||||
|
||||
.-z-10 {
|
||||
z-index: -10;
|
||||
}
|
||||
|
||||
.z-50 {
|
||||
z-index: 50;
|
||||
}
|
||||
|
||||
.-translate-x-1\/2 {
|
||||
transform: translateX(-50%);
|
||||
}
|
||||
|
||||
/* Sizing */
|
||||
.w-32 { width: 8rem; }
|
||||
.w-48 { width: 12rem; }
|
||||
.w-64 { width: 16rem; }
|
||||
.w-full { width: 100%; }
|
||||
.w-[90%] { width: 90%; }
|
||||
.w-[95%] { width: 95%; }
|
||||
.w-[88%] { width: 88%; }
|
||||
.w-[82%] { width: 82%; }
|
||||
|
||||
.h-32 { height: 8rem; }
|
||||
.h-48 { height: 12rem; }
|
||||
.h-64 { height: 16rem; }
|
||||
.h-1 { height: 0.25rem; }
|
||||
.h-1\.5 { height: 0.375rem; }
|
||||
.h-2 { height: 0.5rem; }
|
||||
.h-2\.5 { height: 0.625rem; }
|
||||
.h-24 { height: 6rem; }
|
||||
.h-full { height: 100%; }
|
||||
|
||||
.min-h-screen {
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
.max-w-md {
|
||||
max-width: 28rem;
|
||||
}
|
||||
|
||||
/* Border Radius */
|
||||
.rounded {
|
||||
border-radius: 0.25rem;
|
||||
}
|
||||
|
||||
.rounded-full {
|
||||
border-radius: 9999px;
|
||||
}
|
||||
|
||||
.rounded-lg {
|
||||
border-radius: 0.5rem;
|
||||
}
|
||||
|
||||
.rounded-xl {
|
||||
border-radius: 0.75rem;
|
||||
}
|
||||
|
||||
/* Backgrounds */
|
||||
.bg-background-light {
|
||||
background-color: var(--background-light);
|
||||
}
|
||||
|
||||
.bg-background-dark {
|
||||
background-color: var(--background-dark);
|
||||
}
|
||||
|
||||
.bg-primary {
|
||||
background-color: var(--primary);
|
||||
}
|
||||
|
||||
.bg-slate-800 {
|
||||
background-color: #1e293b;
|
||||
}
|
||||
|
||||
.bg-primary\/10 {
|
||||
background-color: rgba(140, 43, 238, 0.1);
|
||||
}
|
||||
|
||||
.bg-primary\/20 {
|
||||
background-color: rgba(140, 43, 238, 0.2);
|
||||
}
|
||||
|
||||
.bg-purple-600\/10 {
|
||||
background-color: rgba(147, 51, 234, 0.1);
|
||||
}
|
||||
|
||||
.bg-cover {
|
||||
background-size: cover;
|
||||
}
|
||||
|
||||
.bg-center {
|
||||
background-position: center;
|
||||
}
|
||||
|
||||
.bg-gradient-to-tr {
|
||||
background: linear-gradient(to top right, var(--primary), var(--primary-light));
|
||||
}
|
||||
|
||||
/* Glass Effects */
|
||||
.glass {
|
||||
background: var(--glass-bg-light);
|
||||
backdrop-filter: blur(12px);
|
||||
-webkit-backdrop-filter: blur(12px);
|
||||
border: 1px solid var(--glass-border-light);
|
||||
}
|
||||
|
||||
.dark .glass {
|
||||
background: var(--glass-bg-light);
|
||||
backdrop-filter: blur(12px);
|
||||
-webkit-backdrop-filter: blur(12px);
|
||||
border: 1px solid var(--glass-border-light);
|
||||
}
|
||||
|
||||
.glass-dark {
|
||||
background: var(--glass-bg-dark);
|
||||
backdrop-filter: blur(16px);
|
||||
-webkit-backdrop-filter: blur(16px);
|
||||
border: 1px solid var(--glass-border-dark);
|
||||
}
|
||||
|
||||
/* Borders */
|
||||
.border {
|
||||
border: 1px solid;
|
||||
}
|
||||
|
||||
.border-2 {
|
||||
border: 2px solid;
|
||||
}
|
||||
|
||||
.border-4 {
|
||||
border: 4px solid;
|
||||
}
|
||||
|
||||
.border-l-4 {
|
||||
border-left: 4px solid;
|
||||
}
|
||||
|
||||
.border-primary {
|
||||
border-color: var(--primary);
|
||||
}
|
||||
|
||||
.border-primary\/10 {
|
||||
border-color: rgba(140, 43, 238, 0.1);
|
||||
}
|
||||
|
||||
.border-primary\/20 {
|
||||
border-color: rgba(140, 43, 238, 0.2);
|
||||
}
|
||||
|
||||
.border-primary\/30 {
|
||||
border-color: rgba(140, 43, 238, 0.3);
|
||||
}
|
||||
|
||||
.border-background-dark {
|
||||
border-color: var(--background-dark);
|
||||
}
|
||||
|
||||
/* Text Colors */
|
||||
.text-slate-900 {
|
||||
color: var(--text-primary-light);
|
||||
}
|
||||
|
||||
.dark .text-slate-900 {
|
||||
color: var(--text-primary-dark);
|
||||
}
|
||||
|
||||
.text-slate-100 {
|
||||
color: var(--text-primary-dark);
|
||||
}
|
||||
|
||||
.text-slate-400 {
|
||||
color: var(--text-secondary-light);
|
||||
}
|
||||
|
||||
.dark .text-slate-400 {
|
||||
color: var(--text-secondary-dark);
|
||||
}
|
||||
|
||||
.text-slate-500 {
|
||||
color: #64748b;
|
||||
}
|
||||
|
||||
.text-primary {
|
||||
color: var(--primary);
|
||||
}
|
||||
|
||||
.text-white {
|
||||
color: white;
|
||||
}
|
||||
|
||||
/* Typography */
|
||||
.text-xs { font-size: 0.75rem; }
|
||||
.text-sm { font-size: 0.875rem; }
|
||||
.text-lg { font-size: 1.125rem; }
|
||||
.text-xl { font-size: 1.25rem; }
|
||||
.text-2xl { font-size: 1.5rem; }
|
||||
.text-3xl { font-size: 1.875rem; }
|
||||
.text-4xl { font-size: 2.25rem; }
|
||||
|
||||
.font-thin { font-weight: 100; }
|
||||
.font-light { font-weight: 300; }
|
||||
.font-normal { font-weight: 400; }
|
||||
.font-medium { font-weight: 500; }
|
||||
.font-semibold { font-weight: 600; }
|
||||
.font-bold { font-weight: 700; }
|
||||
|
||||
.tracking-tight { letter-spacing: -0.025em; }
|
||||
.tracking-tighter { letter-spacing: -0.05em; }
|
||||
.tracking-widest { letter-spacing: 0.1em; }
|
||||
.tracking-wider { letter-spacing: 0.05em; }
|
||||
|
||||
.uppercase { text-transform: uppercase; }
|
||||
.lowercase { text-transform: lowercase; }
|
||||
|
||||
.leading-relaxed { line-height: 1.625; }
|
||||
|
||||
.text-center { text-align: center; }
|
||||
|
||||
/* Effects */
|
||||
.transition-colors {
|
||||
transition-property: color, background-color, border-color;
|
||||
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
|
||||
transition-duration: 150ms;
|
||||
}
|
||||
|
||||
.shadow-lg {
|
||||
box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05);
|
||||
}
|
||||
|
||||
.shadow-primary\/20 {
|
||||
box-shadow: 0 10px 15px -3px rgba(140, 43, 238, 0.2), 0 4px 6px -2px rgba(140, 43, 238, 0.1);
|
||||
}
|
||||
|
||||
.shadow-2xl {
|
||||
box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.25);
|
||||
}
|
||||
|
||||
.shadow-primary\/20 {
|
||||
box-shadow: 0 25px 50px -12px rgba(140, 43, 238, 0.25);
|
||||
}
|
||||
|
||||
.blur-\[100px\] {
|
||||
filter: blur(100px);
|
||||
}
|
||||
|
||||
.blur-\[80px\] {
|
||||
filter: blur(80px);
|
||||
}
|
||||
|
||||
.overflow-hidden {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.space-y-2 > * + * {
|
||||
margin-top: 0.5rem;
|
||||
}
|
||||
|
||||
.space-y-4 > * + * {
|
||||
margin-top: 1rem;
|
||||
}
|
||||
|
||||
.space-y-8 > * + * {
|
||||
margin-top: 2rem;
|
||||
}
|
||||
|
||||
.space-x-2 > * + * {
|
||||
margin-left: 0.5rem;
|
||||
}
|
||||
|
||||
/* Hover States */
|
||||
.hover\:bg-primary\/10:hover {
|
||||
background-color: rgba(140, 43, 238, 0.1);
|
||||
}
|
||||
|
||||
/* Group States */
|
||||
.group:hover .group-hover\:scale-105 {
|
||||
transform: scale(1.05);
|
||||
}
|
||||
|
||||
/* Dark Mode */
|
||||
.dark {
|
||||
color-scheme: dark;
|
||||
}
|
||||
|
||||
.dark .bg-background-light {
|
||||
background-color: var(--background-dark);
|
||||
}
|
||||
|
||||
.dark .text-slate-900 {
|
||||
color: var(--text-primary-dark);
|
||||
}
|
||||
|
||||
.dark .text-slate-400 {
|
||||
color: var(--text-secondary-dark);
|
||||
}
|
||||
|
||||
/* Responsive */
|
||||
@media (min-width: 640px) {
|
||||
.sm\:grid-cols-2 {
|
||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
.md\:grid-cols-3 {
|
||||
grid-template-columns: repeat(3, minmax(0, 1fr));
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 1024px) {
|
||||
.lg\:grid-cols-4 {
|
||||
grid-template-columns: repeat(4, minmax(0, 1fr));
|
||||
}
|
||||
}
|
||||
|
||||
/* Utility Classes */
|
||||
.block {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.inline {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
.inline-block {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.hidden {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.opacity-0 { opacity: 0; }
|
||||
.opacity-30 { opacity: 0.3; }
|
||||
.opacity-100 { opacity: 1; }
|
||||
|
||||
.cursor-pointer {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.select-none {
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.pointer-events-none {
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
/* Focus States */
|
||||
.focus\:outline-none:focus {
|
||||
outline: 2px solid transparent;
|
||||
outline-offset: 2px;
|
||||
}
|
||||
|
||||
.focus\:ring-2:focus {
|
||||
box-shadow: 0 0 0 2px var(--primary);
|
||||
}
|
||||
|
||||
/* Animation */
|
||||
@keyframes fadeIn {
|
||||
from { opacity: 0; transform: translateY(10px); }
|
||||
to { opacity: 1; transform: translateY(0); }
|
||||
}
|
||||
|
||||
.animate-fade-in {
|
||||
animation: fadeIn 0.5s ease-out;
|
||||
}
|
||||
|
||||
/* Custom scrollbar */
|
||||
::-webkit-scrollbar {
|
||||
width: 8px;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-track {
|
||||
background: var(--background-light);
|
||||
}
|
||||
|
||||
.dark ::-webkit-scrollbar-track {
|
||||
background: var(--background-dark);
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb {
|
||||
background: var(--primary);
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb:hover {
|
||||
background: var(--primary-light);
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
/** @type {import('tailwindcss').Config} */
|
||||
export default {
|
||||
darkMode: 'class',
|
||||
content: ['./src/**/*.{astro,html,js,ts,jsx,tsx}'],
|
||||
theme: {
|
||||
extend: {
|
||||
colors: {
|
||||
primary: '#8c2bee',
|
||||
'background-light': '#f7f6f8',
|
||||
'background-dark': '#191022',
|
||||
},
|
||||
fontFamily: {
|
||||
display: ['Space Grotesk', 'sans-serif'],
|
||||
},
|
||||
borderRadius: {
|
||||
DEFAULT: '0.5rem',
|
||||
lg: '1rem',
|
||||
xl: '1.5rem',
|
||||
full: '9999px',
|
||||
},
|
||||
},
|
||||
},
|
||||
plugins: [],
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
{
|
||||
"extends": "astro/tsconfigs/strict",
|
||||
"include": [".astro/types.d.ts", "**/*"],
|
||||
"exclude": ["dist"]
|
||||
}
|
||||
Reference in New Issue
Block a user