diff --git a/.gitignore b/.gitignore
index 16d54bb..2bfc1c0 100644
--- a/.gitignore
+++ b/.gitignore
@@ -22,3 +22,7 @@ pnpm-debug.log*
# jetbrains setting folder
.idea/
+.gga
+diseño/
+.vscode/
+
diff --git a/README.md b/README.md
index ba563c6..5c0f264 100644
--- a/README.md
+++ b/README.md
@@ -1,85 +1,52 @@
-# Personal Portfolio
+# Personal Portfolio - Itziar ZG
-A framework-free, static portfolio website built with vanilla HTML, CSS, and JavaScript.
+A modern, static portfolio website for AI & Automation Developer. Built with HTML, Tailwind CSS, and minimal 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
+- **Modern Design**: Glassmorphism, gradients, fluid animations
+- **Responsive**: Mobile-first design with Tailwind CSS
+- **Fast Loading**: No build step, CDN-powered Tailwind
- **SEO Optimized**: Semantic HTML5 markup
-- **Fast Loading**: Minimal bundle size
+- **Smooth Navigation**: Scroll-to-section anchors
+- **Professional Layout**: Hero, About, Projects, Tech Stack, Contact sections
## Tech Stack
- **HTML5**: Semantic markup
-- **CSS3**: Custom properties, flexbox, grid, animations
-- **Vanilla JavaScript**: ES6+ modules, classes, localStorage
-- **Google Fonts**: Space Grotesk typography
+- **Tailwind CSS**: Utility-first styling via CDN
+- **Vanilla JavaScript**: Smooth scrolling, minimal interactions
+- **Google Fonts**: Space Grotesk & Instrument Serif
- **Material Symbols**: Icon system
-## Development
-### Prerequisites
+## Getting Started
-- Node.js (for dev server only)
-- Any modern web browser
-
-### Setup
+Simply open `index.html` in your browser. No build step required.
```bash
-# Install dev dependencies (optional)
-npm install
-
-# Start development server
-npm run dev
-
-# Or simply open index.html in your browser
+# Or use a local server
+python -m http.server 8000
+# Then visit http://localhost:8000
```
-### Project Structure
+## Project Structure
```
-├── index.html # Main HTML file
-├── styles/
-│ └── main.css # Complete stylesheet
-├── js/
-│ └── main.js # JavaScript functionality
-├── public/ # Static assets
-└── package.json # Dev dependencies only
+├── index.html # Main portfolio page (loads CSS and JS)
+├── css/ # Site-wide styles (e.g., styles.css)
+├── js/ # Site scripts (e.g., main.js)
+├── diseño/ # Original design files from Stitch
+└── README.md # This file
```
-## Features Implementation
+## Sections
-### Language Switching
-
-- Translations stored in JavaScript objects
-- No page reload required
-- Preference saved in localStorage
-- Dynamic content rendering
-
-### Theme Toggle
-
-- CSS custom properties for theming
-- System preference detection
-- Smooth transitions
-- Icon updates based on current theme
-
-### Performance
-
-- No build step required
-- Minimal HTTP requests
-- Optimized CSS with custom properties
-- Efficient DOM manipulation
-
-## Browser Support
-
-- Chrome 60+
-- Firefox 55+
-- Safari 12+
-- Edge 79+
+- **Hero**: Attention-grabbing intro with CTA buttons
+- **About**: Professional background and capabilities
+- **Selected Works**: 3 featured projects with tech tags
+- **Tech Stack**: Technologies and tools used
+- **Contact**: Call-to-action footer with email and social links
## License
diff --git a/css/styles.css b/css/styles.css
new file mode 100644
index 0000000..ac44f2d
--- /dev/null
+++ b/css/styles.css
@@ -0,0 +1,37 @@
+/* Glass Morphism Effect */
+.glass {
+ background: rgba(255, 255, 255, 0.4);
+ backdrop-filter: blur(12px);
+ -webkit-backdrop-filter: blur(12px);
+ border: 1px solid rgba(255, 255, 255, 0.3);
+}
+
+.dark .glass {
+ background: rgba(30, 20, 40, 0.4);
+ border: 1px solid rgba(255, 255, 255, 0.1);
+}
+
+/* Iridescent Background Gradient */
+.iridescent-bg {
+ background:
+ radial-gradient(
+ circle at 0% 0%,
+ rgba(140, 43, 238, 0.15) 0%,
+ transparent 50%
+ ),
+ radial-gradient(
+ circle at 100% 100%,
+ rgba(255, 182, 255, 0.2) 0%,
+ transparent 50%
+ ),
+ radial-gradient(
+ circle at 50% 50%,
+ rgba(140, 43, 238, 0.05) 0%,
+ transparent 100%
+ );
+}
+
+/* Fluid Blob Shapes */
+.fluid-shape {
+ border-radius: 60% 40% 30% 70% / 60% 30% 70% 40%;
+}
diff --git a/index.html b/index.html
index 151a230..d886fe8 100644
--- a/index.html
+++ b/index.html
@@ -1,212 +1,954 @@
-
+
-
-
-
- Itziar ZG - Vanguard CV
+
+
+ Itziar ZG | AI & Automation Developer
+
+
-
-
-
-
+
-
-
-
-
-
Under construction Itziar ZG
-
-
+
+
+
+
+
- translate
-
-
- dark_mode
-
-
-->
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+ auto_awesome
+
+
+
+ Itziar ZG
+
+
+
+ Sobre mí
+ Proyectos
+ Tech Stack
+ Contacto
+
+
+
+
+ dark_mode
+
+
+ light_mode
+
+
+
+ Hablemos
+
+
+
-
-
+
+
+
+
+
+
+ Disponible para nuevos proyectos
+
+
+ Arquitecta de
+ IA
+ & Automatización
+
+
+ Construyo automatizaciones y agentes de IA que conectan
+ herramientas, procesan información y transforman flujos de trabajo
+ en sistemas inteligentes.
+
+
+
+ Explorar Proyectos
+
+
+ Descargar CV
+
+
+
+
+
+
+
+
+
+
+
+ Sobre mí
+
+
+ Ingeniera de telecomunicaciones y desarrolladora especializada
+ en automatización de procesos, integración de APIs y creación de
+ agentes basados en inteligencia artificial. Construyo sistemas
+ que conectan herramientas, procesan información y crean flujos
+ automatizados que reducen trabajo manual.
+
+
+
+
router
+
Automatización
+
+ Optimización de procesos complejos con workflows
+ inteligentes.
+
+
+
+
psychology
+
Agentes IA
+
+ LLMs y flujos generativos autónomos.
+
+
+
+
hub
+
+ Integración APIs
+
+
+ Conexión fluida entre servicios SaaS.
+
+
+
+
terminal
+
Web Moderna
+
+ Desarrollo Frontend con Next.js y React.
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Selected Works
+
+
+ Proyectos destacados en automatización inteligente.
+
+
+
+ arrow_right_alt
+
+
+
+
+
+
+
+
+
+
+
+ AI Knowledge Pipeline
+
+
+ Sistema automatizado capaz de recibir audio, PDFs, vídeos o
+ texto. Transcribe el contenido, lo resume mediante IA y lo
+ almacena estructuradamente para su reutilización.
+
+
+ n8n
+ Supabase
+ APIs IA
+
+
+ Ver detalles
+
+
+
+
+
+
+
+
+
+
+
+
+ ChefGPT
+
+
+ Agente conversacional que sugiere recetas en función de los
+ ingredientes disponibles. Integra Telegram, Google Sheets y
+ n8n para automatizar consultas de inventario.
+
+
+ Telegram
+ Google Sheets
+ n8n
+
+
+ Ver detalles
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Tech Curated Stack
+
+
+
+
+
+ terminal
+
+
Next.js
+
+
+
+ code
+
+
JavaScript
+
+
+
+ model_training
+
+
LLMs
+
+
+
+ database
+
+
Supabase
+
+
+
+
+ palette
+
+
Tailwind CSS
+
+
+
+ chat
+
+
TypeScript
+
+
+
+
+
+
+
- -->
+
+
+
+
+
+
+
+
+ AI Knowledge Pipeline
+
+
+ ✕
+
+
+
+
+
+
+
+
+ Descripción
+
+
+ Sistema de ingesta y procesamiento inteligente de contenido
+ multimedia. Recibe audio, PDFs, vídeos y texto. Utiliza modelos
+ de IA para transcribir, resumir y extraer información clave,
+ almacenando todo en Supabase de forma estructurada para
+ reutilización posterior.
+
+
+
+
+
+ Funcionalidades
+
+
+ Ingestión de múltiples tipos de contenido
+ Transcripción automática con IA
+ Resumen inteligente y extracción de keywords
+ Almacenamiento vectorial para búsqueda semántica
+ Pipeline automatizado con n8n
+
+
+
+
+
+ Stack Tecnológico
+
+
+ n8n
+ Supabase (PostgreSQL + pgvector)
+ OpenAI API
+ Whisper (transcripción)
+
+
+
+
+
+ Resultado
+
+
+ Pipeline completamente automatizado que reduce el tiempo de
+ procesamiento de contenido en un 85% y permite reutilizar
+ información de forma inteligente mediante búsquedas semánticas.
+
+
+
+
+
+ Cerrar
+
+
+
+
+
+
+
+
+
+
+
+ ChefGPT
+
+
+ ✕
+
+
+
+
+
+
+
+
+ Descripción
+
+
+ Agente conversacional inteligente en Telegram que actúa como
+ asistente culinario personal. Consulta tu inventario en Supabase,
+ accede a un RAG especializado con recetas para evitar
+ alucinaciones, y sugiere platos personalizados basados en lo que
+ tienes disponible.
+
+
+
+
+
+ Funcionalidades
+
+
+ Integración bidireccional con Supabase
+ Consulta automática de inventario en base de datos
+ RAG (Retrieval-Augmented Generation) con recetas verificadas
+ Prevención de alucinaciones mediante fine-tuning de prompts
+ Generación de recetas personalizadas sin alucinar
+ Actualización automática del inventario
+ Conversación natural y contextual
+
+
+
+
+
+ Stack Tecnológico
+
+
+ Telegram Bot API
+ Supabase (PostgreSQL)
+ RAG (Retrieval)
+ OpenAI GPT
+ n8n
+
+
+
+
+
+ Resultado
+
+
+ Asistente culinario robusto que elimina la decisión de "qué
+ cocinar" sin generar recetas inexistentes. El RAG garantiza que
+ todas las sugerencias provienen de un corpus de recetas
+ verificadas, proporcionando fiabilidad y personalización sin
+ alucinaciones de la IA.
+
+
+
+
+
+ Cerrar
+
+
+
+
+
+
+
+
+
+
+
+ Content Processing Automation
+
+
+ ✕
+
+
+
+
+
+
+
+
+ Descripción
+
+
+ Pipeline integral de procesamiento de contenido multimedia que
+ automatiza desde la ingesta hasta la distribución. Transforma
+ múltiples formatos (audio, vídeo, PDFs, texto) en contenido
+ estructurado y lista para publicación en redes sociales.
+
+
+
+
+
+ Funcionalidades
+
+
+ Procesamiento de múltiples formatos multimedia
+ Transcripción y análisis automático
+ Generación de títulos, descripciones y hashtags con IA
+ Redimensionamiento y optimización de imágenes
+ Publicación automática en redes sociales
+
+
+
+
+
+ Stack Tecnológico
+
+
+ Workflow Automation
+ FFmpeg (vídeo)
+ OpenAI API
+ Social Media APIs
+
+
+
+
+
+ Resultado
+
+
+ Automatización completa de la cadena de producción de contenido,
+ reduciendo tiempo manual en un 90% y garantizando consistencia
+ en la calidad y el formato de publicaciones.
+
+
+
+
+
+ Cerrar
+
+
+
+
+
+
diff --git a/js/language-toggle.js b/js/language-toggle.js
deleted file mode 100644
index 8ef8ab0..0000000
--- a/js/language-toggle.js
+++ /dev/null
@@ -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);
- };
-})();
diff --git a/js/main.js b/js/main.js
index 69fa380..8dba210 100644
--- a/js/main.js
+++ b/js/main.js
@@ -1,280 +1,130 @@
-// 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"
- }
- }
-};
+// ============================================
+// Theme Toggle - Dark/Light Mode
+// ============================================
-// 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());
- }
- }
+/**
+ * Initialize theme on page load
+ * Checks localStorage for saved preference, falls back to light mode
+ */
+function initTheme() {
+ const savedTheme = localStorage.getItem("theme") || "light";
+ if (savedTheme === "dark") {
+ document.documentElement.classList.add("dark");
+ } else {
+ document.documentElement.classList.remove("dark");
+ }
}
-// 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 => `
-
-
-
-
${project.title[this.currentLang]}
-
${project.description[this.currentLang]}
-
- link
- ${project.url}
-
-
-
- `).join('');
- }
-
- renderExperience() {
- const container = document.getElementById('experience-container');
- if (!container) return;
-
- container.innerHTML = `
-
- ${experience.map(job => `
-
-
-
${job.period}
-
${job.title[this.currentLang]}
-
${job.company}
-
${job.description[this.currentLang]}
-
- `).join('')}
-
- `;
- }
-
- setupEventListeners() {
- const languageToggle = document.getElementById('language-toggle');
- if (languageToggle) {
- languageToggle.addEventListener('click', () => this.toggle());
- }
- }
+/**
+ * Toggle between dark and light theme
+ * Saves preference to localStorage
+ */
+function toggleTheme() {
+ const html = document.documentElement;
+ if (html.classList.contains("dark")) {
+ html.classList.remove("dark");
+ localStorage.setItem("theme", "light");
+ } else {
+ html.classList.add("dark");
+ localStorage.setItem("theme", "dark");
+ }
}
-// 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);
+// ============================================
+// Smooth Scrolling
+// ============================================
+
+/**
+ * Scroll to projects section
+ */
+function scrollToProjects() {
+ const projectsSection = document.getElementById("projects");
+ if (projectsSection) {
+ projectsSection.scrollIntoView({ behavior: "smooth" });
+ }
+}
+
+/**
+ * Scroll to contact section
+ */
+function scrollToContact() {
+ const contactSection = document.getElementById("contact");
+ if (contactSection) {
+ contactSection.scrollIntoView({ behavior: "smooth" });
+ }
+}
+
+// ============================================
+// Modal Management
+// ============================================
+
+/** Element that had focus before a modal was opened */
+let _modalPreviousFocus = null;
+
+/**
+ * Open modal by project ID.
+ * Saves the currently focused element and moves focus into the modal.
+ * @param {string} projectId - The project identifier
+ */
+function openModal(projectId) {
+ const modal = document.getElementById(projectId + "-modal");
+ if (modal) {
+ _modalPreviousFocus = document.activeElement;
+ modal.classList.remove("hidden");
+ document.body.style.overflow = "hidden";
+
+ // Move focus to the first focusable element inside the modal
+ const focusable = modal.querySelectorAll(
+ 'button, [href], input, select, textarea, [contenteditable="true"], [tabindex]:not([tabindex="-1"])'
+ );
+ if (focusable.length > 0) {
+ focusable[0].focus();
+ } else {
+ modal.setAttribute("tabindex", "-1");
+ modal.focus();
+ }
+ }
+}
+
+/**
+ * Close modal by project ID.
+ * Restores focus to the element that was focused before the modal opened.
+ * @param {string} projectId - The project identifier
+ */
+function closeModal(projectId) {
+ const modal = document.getElementById(projectId + "-modal");
+ if (modal) {
+ modal.classList.add("hidden");
+ document.body.style.overflow = "auto";
+
+ // Return focus to the element that triggered the modal
+ if (_modalPreviousFocus) {
+ _modalPreviousFocus.focus();
+ _modalPreviousFocus = null;
+ }
+ }
+}
+
+// ============================================
+// Event Listeners
+// ============================================
+
+/**
+ * Close modal when ESC key is pressed
+ */
+document.addEventListener("keydown", function (event) {
+ if (event.key === "Escape") {
+ const modals = document.querySelectorAll(
+ '[id$="-modal"]:not(.hidden)'
+ );
+ modals.forEach((modal) => {
+ const projectId = modal.id.replace("-modal", "");
+ closeModal(projectId);
});
+ }
});
+
+/**
+ * Initialize theme as early as possible
+ */
+initTheme();
diff --git a/js/theme-toggle.js b/js/theme-toggle.js
deleted file mode 100644
index c9b653a..0000000
--- a/js/theme-toggle.js
+++ /dev/null
@@ -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);
- };
-})();
diff --git a/styles/main.css b/styles/main.css
deleted file mode 100644
index d7d795b..0000000
--- a/styles/main.css
+++ /dev/null
@@ -1,552 +0,0 @@
-/* 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);
-}