refactor: 清理无用资源并更新项目配置

删除大量未使用的图标、图片和组件文件
更新.gitignore、tsconfig.json和astro配置
添加新的工具函数和UI组件
修改项目元数据和依赖项
This commit is contained in:
joyzhao
2025-06-13 12:03:15 +08:00
parent 43d830aa27
commit c1bfb0915e
145 changed files with 1901 additions and 13996 deletions

3
.gitignore vendored
View File

@@ -1,9 +1,6 @@
# build output
dist/
# vscode settings
.vscode/
# generated types
.astro/

View File

@@ -1,6 +1,6 @@
MIT License
Copyright (c) 2025 Fernando Aldair Lopez Ponce
Copyright (c) 2025 Rishikesh S
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal

340
README.md
View File

@@ -1,224 +1,186 @@
# Modern Portfolio Template
# NeonMint Template Documentation
A sleek, responsive portfolio website built with **Astro**, **React**, and **Tailwind CSS**, featuring modern animations and stunning glassmorphism effects.
![neonmint](https://github.com/user-attachments/assets/068da5e4-50c0-4134-99d3-8cb8ec867d9f)
![Portfolio Screenshot](https://github.com/user-attachments/assets/4f2466f1-1ebe-4cbe-857c-40eccd63c384)
## 🎯 Overview
## ✨ Features
**NeonMint** is a minimalist and modern template designed for developers and digital creatives. Its dark-toned aesthetic with mint green accents offers a clean, elegant, and functional visual experience, ideal for portfolios, dashboards, or tech landing pages.
- **Modern Design** Clean, professional layout with elegant glassmorphism
- **Animations** Smooth transitions and interactive UI via Framer Motion
- **Dark/Light Mode** Automatic theme switching with system preference detection
- **Fully Responsive** Optimized for mobile, tablet, and desktop
- **Blazing Fast** Powered by Astro for superior performance
- **Modular Structure** Built for easy customization and scalability
- **SEO Friendly** Structured content and meta tags for better visibility
## 📁 Project Structure
## 🚀 Demo
👉 [Live Demo](https://rishilol.vercel.app/)
## 🛠 Getting Started
### Prerequisites
- Node.js (v18+ recommended)
- npm / yarn / bun
### Installation
```bash
└── 📁NeonMint
└── 📁public
├── android-chrome-192x192.png
├── android-chrome-512x512.png
├── apple-touch-icon.png
├── favicon-16x16.png
├── favicon-32x32.png
├── favicon.ico
└── 📁images
├── 📁posts # Post images
└── 📁projects # Project images
└── site.webmanifest # PWA configuration file
└── 📁src
├── 📁components # Reusable UI components
│ ├── 📁blog # Blog components
│ ├── 📁layout # Layout components
│ ├── 📁portfolio # Portfolio components
│ └── 📁ui # UI components
├── 📁icons # Icons (.svg)
├── 📁layouts # Site layouts
│ ├── Layout.astro # Main application layout
│ ├── MarkdownAbout.astro # About-me page layout
│ ├── MarkdownPostLayout.astro # Posts page layout
│ └── ProjectLayout.astro # Projects page layout
├── 📁pages # Site pages
│ ├── about-me.md # About-me page
│ ├── 📁blog # All posts page
│ │ ├── index.astro # Blog home page
│ │ ├── 📁posts # Blog posts
├── │ ├── └── index.astro # All posts page
│ │ ├── 📁tags # Blog tags
│ │ └── 📁techs # Blog technologies
│ ├── index.astro # Home page
│ ├── 📁portfolio
│ │ └── 📁projects # Portfolio projects
│ ├── robots.txt.ts # robots.txt configuration
│ └── rss.xml.js # RSS configuration
├── 📁scripts
│ └── menu.js # Menu script
├── 📁styles
│ └── global.css # Global styles
└── 📁utils
└── languages.ts # Technology tools configuration
├── .gitignore
├── astro.config.mjs
├── package-lock.json
├── package.json
├── README.md
└── tsconfig.json
```
git clone https://github.com/yourusername/my-portfolio.git
cd my-portfolio
## 🛠️ Technology Stack
- **Framework**: Astro v5.6.1
- **UI Library**: Preact v10.26.2
- **Styling**: TailwindCSS v4.0.8
- **Icons**: astro-icon v1.1.5
- **Syntax Highlighting**: PrismJS v1.30.0
- **Animations**: tailwindcss-animated v2.0.0
- **Analytics**: @vercel/speed-insights v1.2.0
## ✨ Key Features
1. **🚀 Performance Optimized**
- Static site generation
- Partial hydration with Preact
- Optimized images and assets
2. **💻 Modern Development Experience**
- TypeScript support
- Hot module replacement
- ESLint integration
3. **🔍 SEO & Analytics**
- Built-in sitemap generation
- RSS feed support
- Vercel Speed Insights
4. **🎨 Styling & UI**
- TailwindCSS for utility-first styling
- Animated components
- Responsive design
- Dark mode support
## 🚀 Getting Started
1. **📦 Installation**
### 🚀**Astro Installation**
```bash
npm create astro@latest -- --template EFEELE/neonmint
```
or
### 🔧**Manual Installation**
#### Clone Repository
```bash
git clone https://github.com/EFEELE/NeonMint.git
```
#### Install Dependencies
```bash
# Install dependencies
npm install
```
# or
yarn install
# or
bun install
3. **⚡ Development**
```bash
# Start development server
npm run dev
# or
yarn dev
# or
bun dev
```
4. **🏗️ Build**
Visit `http://localhost:4321` in your browser to see it in action.
## 🧩 Customizing the Portfolio
All your content lives inside `src/lib/data.ts`. Update the following to make it yours:
### 1. Personal Info
```ts
export const personalInfo = {
name: "Your Name",
location: "Your Location",
email: "your.email@example.com",
github: "https://github.com/yourusername",
linkedin: "https://www.linkedin.com/in/yourusername/",
};
```
### 2. Work Experience
```ts
export const workExperience = [
{
company: "Company Name",
location: "Location",
position: "Your Position",
period: "Start Date - End Date",
achievements: [
"Achievement 1",
"Achievement 2",
],
},
];
```
### 3. Education
```ts
export const education = [
{
institution: "University Name",
location: "Location",
degree: "Your Degree",
period: "Start Date - End Date",
achievements: [
"Achievement 1",
"Achievement 2",
],
},
];
```
### 4. Skills
```ts
export const skills = {
programmingLanguages: ["TypeScript", "Python"],
frontendDevelopment: ["React", "Next.js"],
// and more...
};
```
### 5. Projects
```ts
export const projects = [
{
title: "Project Name",
github: "https://github.com/yourusername/project",
description: [
"What it does",
"Technologies used",
],
},
];
```
### 6. Awards
```ts
export const awards = [
{
name: "Award Name",
issuer: "Issuer",
date: "Date",
type: "Type",
position: "Position",
},
];
```
## 📦 Build for Production
```bash
npm run build
# or
yarn build
# or
bun run build
```
5. **👀 Preview**
To preview the production build locally:
```bash
npm run preview
# or
yarn preview
```
## ⚙️ Configuration
## 📤 Deployment
The project is configured through several key files:
Easily deploy to platforms like **Vercel**, **Netlify**, **GitHub Pages**, or any static host of your choice.
- `astro.config.mjs`: Main Astro configuration
- `tailwind.config.js`: TailwindCSS configuration
- `tsconfig.json`: TypeScript configuration
## 📝 License
## 🎨 Customization
This project is licensed under the MIT License. See the [LICENSE](LICENSE) file for details.
### 📄 Adding New Pages
## ©️ Copyright
Create new `.astro` files in the `src/pages` directory. The file name will determine the route.
© 2025 **Rishikesh S.** All rights reserved.
### 🔧 Adding New Languages or Technologies
To incorporate a new programming language or technological tool into the site's capsules, follow these steps:
1. **🖼️ Add the SVG icon**: Place the SVG file of the language or tool in the `src/icons` folder.
> **💡 Recommendation**: For SVG icons, I recommend using [SVGL](https://svgl.app/), an excellent library of high-quality vectors that offers optimized icons for most popular languages and technologies.
2. **📝 Register the language**: Open the `utils/languages.ts` file and add a new entry to the languages object following this format:
```typescript
html: {
name: "HTML 5",
iconName: "html",
},
```
Where:
- `html`: Is the unique identifier for the language
- `name`: Is the name that will be displayed visibly in the interface
- `iconName`: Is the name of the SVG file without the extension (must match exactly with the file name in `src/icons`)
Once these steps are completed, the new language or technology will be available for use in the site's capsules. You can select it when creating or editing projects or posts, and the corresponding icon will be displayed correctly in the interface.
If you encounter any issues during this process, try restarting the development server. In some cases, changes to configuration files or static resources require a restart to be detected correctly.
To verify that the new language has been added correctly, check the list of available technologies in the user interface after restarting the server.
Youre welcome to use this template for your own portfolio — just update `data.ts` and tweak the design as needed. Please keep attribution to the original author.
---
### 🧷 Favicon Setup
## 🌟 Like it?
To customize your site's favicon and web app icons, you can generate all the necessary variants using [favicon.io](https://favicon.io/favicon-converter/). Upload your logo or icon, and the tool will create a full set of optimized files for various devices and platforms.
Place the generated files in the `📂 public` directory as follows:
```bash
📂 public
├── 📄 android-chrome-192x192.png
├── 📄 android-chrome-512x512.png
├── 📄 apple-touch-icon.png
├── 📄 favicon-16x16.png
├── 📄 favicon-32x32.png
├── 📄 favicon.ico
└── 📄 site.webmanifest
```
> 💡 Dont forget to update the contents of `site.webmanifest` to match your apps name, description, and theme color for a complete PWA experience.
If you found this helpful or inspiring, **please consider leaving a star** ⭐ on the repo — it helps others discover it too!
---
### 🎨 Styling
- Use TailwindCSS classes for styling
- Add custom styles in `src/styles/global.css`
### 🧩 Components
- Create reusable components in `src/components`
- Import icons using `astro-icon`
## 🚀 Deployment
The site is configured for deployment on Vercel, but can be deployed to any static hosting service.
## 🤝 Contributing
1. Fork the repository
2. Create a feature branch
3. Commit your changes
4. Push to the branch
5. Create a Pull Request
## 📄 License
This project is licensed under the MIT License - see the LICENSE file for details.
## 🙏 Acknowledgments
- [Astro](https://astro.build/)
- [React](https://reactjs.org/)
- [Tailwind CSS](https://tailwindcss.com/)
- [Framer Motion](https://www.framer.com/motion/)
- [Lucide Icons](https://lucide.dev/)

View File

@@ -1,25 +1,14 @@
// @ts-check
import { defineConfig } from 'astro/config';
import tailwindcss from "@tailwindcss/vite";
import preact from "@astrojs/preact";
import sitemap from "@astrojs/sitemap"
import icon from "astro-icon";
import react from "@astrojs/react";
// https://astro.build/config
export default defineConfig({
site: "https://neonmint.efeele.dev",
integrations: [preact(), icon(), sitemap({
filter: (page) =>
!page.includes("/blog/tags") &&
!page.includes("/blog/techs"),
}),],
vite: {
plugins: [tailwindcss()],
},
markdown: {
shikiConfig: {
theme: 'github-dark'
},
},
integrations: [react()]
});

21
components.json Normal file
View File

@@ -0,0 +1,21 @@
{
"$schema": "https://ui.shadcn.com/schema.json",
"style": "new-york",
"rsc": false,
"tsx": true,
"tailwind": {
"config": "",
"css": "src/styles/global.css",
"baseColor": "neutral",
"cssVariables": true,
"prefix": ""
},
"aliases": {
"components": "@/components",
"utils": "@/lib/utils",
"ui": "@/components/ui",
"lib": "@/lib",
"hooks": "@/hooks"
},
"iconLibrary": "lucide"
}

8033
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,7 +1,14 @@
{
"name": "site",
"name": "zhaoguiyang.site",
"type": "module",
"version": "0.0.1",
"description": "Modern portfolio template with animations and glassmorphism effects",
"author": "Joy Zhao",
"license": "MIT",
"repository": {
"type": "git",
"url": "https://github.com/rishikesh2003/my-portfolio"
},
"scripts": {
"dev": "astro dev",
"build": "astro build",
@@ -9,21 +16,21 @@
"astro": "astro"
},
"dependencies": {
"@astrojs/preact": "^4.0.8",
"@astrojs/rss": "^4.0.11",
"@astrojs/sitemap": "^3.3.0",
"@tailwindcss/vite": "^4.1.8",
"@vercel/speed-insights": "^1.2.0",
"alpinejs": "^3.14.9",
"astro": "^5.6.1",
"astro-icon": "^1.1.5",
"preact": "^10.26.2",
"prismjs": "^1.30.0",
"tailwindcss": "^4.1.8"
},
"devDependencies": {
"eslint": "^9.22.0",
"eslint-plugin-astro": "^1.3.1",
"tailwindcss-animated": "^2.0.0"
"@astrojs/react": "^4.2.1",
"@radix-ui/react-slot": "^1.1.2",
"@tailwindcss/vite": "^4.0.14",
"@types/react": "^19.0.12",
"@types/react-dom": "^19.0.4",
"aos": "^2.3.4",
"astro": "^5.5.3",
"class-variance-authority": "^0.7.1",
"clsx": "^2.1.1",
"framer-motion": "^12.5.0",
"lucide-react": "^0.483.0",
"react": "^19.0.0",
"react-dom": "^19.0.0",
"tailwind-merge": "^3.0.2",
"tailwindcss": "^4.0.14",
"tw-animate-css": "^1.2.4"
}
}

2163
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 314 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 638 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

9
public/favicon.svg Normal file
View File

@@ -0,0 +1,9 @@
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 128 128">
<path d="M50.4 78.5a75.1 75.1 0 0 0-28.5 6.9l24.2-65.7c.7-2 1.9-3.2 3.4-3.2h29c1.5 0 2.7 1.2 3.4 3.2l24.2 65.7s-11.6-7-28.5-7L67 45.5c-.4-1.7-1.6-2.8-2.9-2.8-1.3 0-2.5 1.1-2.9 2.7L50.4 78.5Zm-1.1 28.2Zm-4.2-20.2c-2 6.6-.6 15.8 4.2 20.2a17.5 17.5 0 0 1 .2-.7 5.5 5.5 0 0 1 5.7-4.5c2.8.1 4.3 1.5 4.7 4.7.2 1.1.2 2.3.2 3.5v.4c0 2.7.7 5.2 2.2 7.4a13 13 0 0 0 5.7 4.9v-.3l-.2-.3c-1.8-5.6-.5-9.5 4.4-12.8l1.5-1a73 73 0 0 0 3.2-2.2 16 16 0 0 0 6.8-11.4c.3-2 .1-4-.6-6l-.8.6-1.6 1a37 37 0 0 1-22.4 2.7c-5-.7-9.7-2-13.2-6.2Z" />
<style>
path { fill: #000; }
@media (prefers-color-scheme: dark) {
path { fill: #FFF; }
}
</style>
</svg>

After

Width:  |  Height:  |  Size: 749 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 114 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 91 KiB

BIN
public/profile.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

View File

@@ -1 +0,0 @@
{"name":"","short_name":"","icons":[{"src":"/android-chrome-192x192.png","sizes":"192x192","type":"image/png"},{"src":"/android-chrome-512x512.png","sizes":"512x512","type":"image/png"}],"theme_color":"#ffffff","background_color":"#ffffff","display":"standalone"}

View File

@@ -0,0 +1,65 @@
import React from "react";
import { awards } from "@/lib/data";
import { Trophy } from "lucide-react";
import MotionWrapper from "./MotionWrapper";
import { GlassCard } from "./ui/glass-card";
import { motion } from "framer-motion";
export default function AwardsSection() {
return (
<section
id="awards"
className="py-12 bg-gradient-to-b from-background to-muted/10"
>
<div className="container max-w-4xl mx-auto px-6 md:px-4">
<MotionWrapper>
<h2 className="text-2xl font-bold mb-8 text-center md:text-left">
🏆 Awards
</h2>
</MotionWrapper>
<div className="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 gap-4">
{awards.map((award, index) => (
<MotionWrapper key={award.name + award.date} delay={index * 0.1}>
<GlassCard className="p-4 dark:border-purple-500/10 hover:border-purple-500/30 transition-all duration-300 flex flex-col h-full">
<div className="flex items-center mb-2">
<motion.div
whileHover={{ rotate: 20 }}
transition={{ type: "spring", stiffness: 500 }}
className="flex items-center justify-center bg-gradient-to-r from-amber-500 to-yellow-500 rounded-full p-1.5 mr-2"
>
<Trophy className="h-4 w-4 text-white" />
</motion.div>
<h3 className="font-medium">{award.name}</h3>
</div>
<p className="text-xs text-muted-foreground mb-1 pl-8">
🏢 {award.issuer}
</p>
<div className="flex flex-col space-y-2 mt-auto">
<div className="flex justify-between items-center">
<span className="text-xs text-muted-foreground bg-background/50 px-2 py-1 rounded-md">
📅 {award.date}
</span>
<motion.span
className="text-xs px-2 py-1 bg-purple-500/10 rounded-full"
whileHover={{ scale: 1.05 }}
>
{award.position}
</motion.span>
</div>
<motion.span
className="text-xs text-muted-foreground/80 bg-background/50 px-2 py-1 rounded-md w-fit"
whileHover={{ scale: 1.05 }}
>
{award.type === "International" ? "🌎 " : "🇮🇳 "}
{award.type}
</motion.span>
</div>
</GlassCard>
</MotionWrapper>
))}
</div>
</div>
</section>
);
}

View File

@@ -0,0 +1,72 @@
import { education } from "@/lib/data";
import TimelineItem from "./TimelineItem";
import { Award } from "lucide-react";
import MotionWrapper from "./MotionWrapper";
import { motion } from "framer-motion";
export default function EducationSection() {
return (
<section
id="education"
className="py-12 bg-gradient-to-b from-muted/10 to-background"
>
<div className="container max-w-4xl mx-auto px-6 md:px-4">
<MotionWrapper>
<h2 className="text-2xl font-bold mb-8 text-center md:text-left">
🎓 Education
</h2>
</MotionWrapper>
<div className="mb-8">
{education.map((edu, index) => (
<TimelineItem
key={edu.institution}
title={`🎓 ${edu.degree}`}
subtitle={`🏛️ ${edu.institution}`}
date={`📅 ${edu.period}`}
isLast={index === education.length - 1}
index={index}
>
<p className="text-sm text-muted-foreground mb-3">
📍 {edu.location}
</p>
{edu.achievements && edu.achievements.length > 0 && (
<motion.div
className="mt-3 p-4 bg-background/80 backdrop-blur-sm backdrop-filter rounded-lg border border-purple-500/20 dark:bg-card/10 dark:border-purple-500/10 shadow-sm"
initial={{ opacity: 0, y: 20 }}
whileInView={{ opacity: 1, y: 0 }}
transition={{ duration: 0.5, delay: 0.2 }}
viewport={{ once: true }}
>
<div className="flex items-center mb-3">
<div className="h-6 w-6 flex items-center justify-center rounded-full bg-purple-500/10 mr-2">
<Award className="h-4 w-4 text-purple-500" />
</div>
<h4 className="text-sm font-medium">
Achievements & Activities
</h4>
</div>
<ul className="list-none ml-4 space-y-2 text-sm">
{edu.achievements.map((achievement, i) => (
<motion.li
key={i}
className="text-muted-foreground relative pl-6"
initial={{ opacity: 0, x: -10 }}
whileInView={{ opacity: 1, x: 0 }}
transition={{ duration: 0.3, delay: 0.1 * i }}
viewport={{ once: true }}
>
{achievement}
</motion.li>
))}
</ul>
</motion.div>
)}
</TimelineItem>
))}
</div>
</div>
</section>
);
}

View File

@@ -0,0 +1,72 @@
import { workExperience } from "@/lib/data";
import TimelineItem from "./TimelineItem";
import { Briefcase } from "lucide-react";
import { motion } from "framer-motion";
import MotionWrapper from "./MotionWrapper";
export default function ExperienceSection() {
return (
<section
id="experience"
className="py-12 bg-gradient-to-b from-muted/20 to-background"
>
<div className="container max-w-4xl mx-auto px-6 md:px-4">
<MotionWrapper>
<h2 className="text-2xl font-bold mb-8 text-center md:text-left flex items-center md:inline-block">
<motion.span
className="inline-block mr-2"
initial={{ rotate: 0 }}
whileInView={{ rotate: [0, -10, 10, -5, 5, 0] }}
transition={{ duration: 0.5, delay: 0.2 }}
viewport={{ once: true }}
>
💼
</motion.span>{" "}
Work Experience
</h2>
</MotionWrapper>
<div className="mb-8">
{workExperience.map((job, index) => (
<TimelineItem
key={job.company + job.period}
title={`👨‍💻 ${job.position} | ${job.company}`}
subtitle={`🌍 ${job.location}`}
date={`📅 ${job.period}`}
isLast={index === workExperience.length - 1}
index={index}
>
<motion.div
className="mt-3 p-4 bg-background/80 backdrop-blur-sm backdrop-filter rounded-lg border border-purple-500/20 dark:bg-card/10 dark:border-purple-500/10 shadow-sm"
initial={{ opacity: 0, y: 20 }}
whileInView={{ opacity: 1, y: 0 }}
transition={{ duration: 0.5, delay: 0.2 }}
viewport={{ once: true }}
>
<div className="flex items-center mb-3">
<div className="h-6 w-6 flex items-center justify-center rounded-full bg-purple-500/10 mr-2">
<Briefcase className="h-4 w-4 text-purple-500" />
</div>
<h4 className="text-sm font-medium">Key Achievements</h4>
</div>
<ul className="list-none ml-4 space-y-2 text-sm">
{job.achievements.map((achievement, i) => (
<motion.li
key={i}
className="text-muted-foreground relative pl-6"
initial={{ opacity: 0, x: -10 }}
whileInView={{ opacity: 1, x: 0 }}
transition={{ duration: 0.3, delay: 0.1 * i }}
viewport={{ once: true }}
>
{achievement}
</motion.li>
))}
</ul>
</motion.div>
</TimelineItem>
))}
</div>
</div>
</section>
);
}

58
src/components/Footer.tsx Normal file
View File

@@ -0,0 +1,58 @@
import { personalInfo } from "@/lib/data";
import { motion } from "framer-motion";
export default function Footer() {
return (
<footer className="border-t border-purple-500/10 py-6 bg-gradient-to-b from-background to-muted/20 backdrop-blur-sm">
<div className="container max-w-4xl mx-auto px-6 md:px-4">
<motion.div
className="flex flex-col md:flex-row justify-between items-center"
initial={{ opacity: 0, y: 20 }}
whileInView={{ opacity: 1, y: 0 }}
transition={{ duration: 0.5 }}
viewport={{ once: true }}
>
<motion.p
className="text-sm text-muted-foreground text-center md:text-left"
whileHover={{ scale: 1.01 }}
>
&copy; {new Date().getFullYear()} {personalInfo.name}. All rights
reserved.
</motion.p>
<motion.p
className="text-sm text-muted-foreground mt-2 md:mt-0 text-center md:text-left"
initial={{ opacity: 0 }}
whileInView={{ opacity: 1 }}
transition={{ delay: 0.2, duration: 0.5 }}
viewport={{ once: true }}
whileHover={{ scale: 1.01 }}
>
Built with{" "}
<motion.span
className="inline-block"
initial={{ rotate: 0 }}
whileHover={{ rotate: 360 }}
transition={{ duration: 0.5 }}
>
💻
</motion.span>{" "}
and{" "}
<motion.span
className="inline-block"
animate={{
scale: [1, 1.2, 1],
}}
transition={{
repeat: Infinity,
repeatType: "reverse",
duration: 1.5,
}}
>
</motion.span>
</motion.p>
</motion.div>
</div>
</footer>
);
}

View File

@@ -0,0 +1,100 @@
import ThemeToggle from "./ui/theme-toggle";
import { personalInfo } from "@/lib/data";
import { useState } from "react";
import { Menu, X } from "lucide-react";
import { motion, AnimatePresence } from "framer-motion";
export default function GlassHeader() {
const [isMenuOpen, setIsMenuOpen] = useState(false);
const toggleMenu = () => setIsMenuOpen(!isMenuOpen);
return (
<header className="sticky z-50 w-full backdrop-blur-md backdrop-filter bg-background/70 dark:bg-background/40 border-b border-border/40 supports-[backdrop-filter]:bg-background/60">
<div className="container max-w-4xl mx-auto p-4 flex justify-between items-center">
<motion.a
className="flex items-center text-lg font-medium"
href="/"
whileHover={{ scale: 1.05 }}
whileTap={{ scale: 0.95 }}
>
{personalInfo.name}
</motion.a>
{/* Desktop Navigation */}
<nav className="hidden md:flex items-center space-x-6 text-sm font-medium">
{["experience", "skills", "projects", "awards", "education"].map(
(item, index) => (
<motion.a
key={item}
href={`#${item}`}
className="transition-colors hover:text-foreground/80 text-foreground/60"
initial={{ opacity: 0, y: -10 }}
animate={{ opacity: 1, y: 0 }}
transition={{ duration: 0.2, delay: index * 0.1 }}
whileHover={{ y: -2 }}
>
{item === "experience" && "💼 "}
{item === "skills" && "🛠️ "}
{item === "projects" && "🚀 "}
{item === "awards" && "🏆 "}
{item === "education" && "🎓 "}
{item.charAt(0).toUpperCase() + item.slice(1)}
</motion.a>
)
)}
</nav>
<div className="flex items-center space-x-2">
<ThemeToggle />
{/* Mobile Menu Button */}
<motion.button
className="md:hidden p-2 text-foreground"
onClick={toggleMenu}
aria-label="Toggle menu"
whileTap={{ scale: 0.95 }}
>
{isMenuOpen ? <X size={24} /> : <Menu size={24} />}
</motion.button>
</div>
</div>
{/* Mobile Navigation */}
<AnimatePresence>
{isMenuOpen && (
<motion.div
className="md:hidden py-4 px-4 border-t border-border/10 backdrop-blur-md backdrop-filter bg-background/80 dark:bg-background/40"
initial={{ opacity: 0, height: 0 }}
animate={{ opacity: 1, height: "auto" }}
exit={{ opacity: 0, height: 0 }}
transition={{ duration: 0.3 }}
>
<nav className="flex flex-col space-y-4 text-sm font-medium">
{["experience", "skills", "projects", "awards", "education"].map(
(item, index) => (
<motion.a
key={item}
href={`#${item}`}
className="transition-colors hover:text-foreground/80 text-foreground/60 py-2"
onClick={toggleMenu}
initial={{ opacity: 0, x: -20 }}
animate={{ opacity: 1, x: 0 }}
transition={{ duration: 0.2, delay: index * 0.1 }}
>
{item === "experience" && "💼 "}
{item === "skills" && "🛠️ "}
{item === "projects" && "🚀 "}
{item === "awards" && "🏆 "}
{item === "education" && "🎓 "}
{item.charAt(0).toUpperCase() + item.slice(1)}
</motion.a>
)
)}
</nav>
</motion.div>
)}
</AnimatePresence>
</header>
);
}

View File

@@ -0,0 +1,140 @@
import { personalInfo } from "@/lib/data";
import { Mail, Github, MapPin, Linkedin } from "lucide-react";
import { motion } from "framer-motion";
import MotionWrapper from "./MotionWrapper";
export default function HeroSection() {
const containerVariants = {
hidden: { opacity: 0 },
visible: {
opacity: 1,
transition: {
staggerChildren: 0.2,
delayChildren: 0.3,
},
},
};
const childVariants = {
hidden: { opacity: 0, y: 20 },
visible: {
opacity: 1,
y: 0,
transition: {
duration: 0.5,
},
},
};
return (
<section className="py-16 md:py-24 relative overflow-hidden">
<div className="container max-w-4xl mx-auto px-6 md:px-4 relative z-10">
<motion.div
className="flex flex-col md:flex-row md:items-center justify-between mb-8"
variants={containerVariants}
initial="hidden"
animate="visible"
>
<div className="text-center md:text-left">
<motion.h1
className="text-4xl font-bold mb-2"
variants={childVariants}
>
{personalInfo.name}{" "}
<span className="inline-block animate-pulse"></span>
</motion.h1>
<motion.p
className="text-xl text-muted-foreground mb-6"
variants={childVariants}
>
Software Engineer 👨💻
</motion.p>
<motion.div
className="flex flex-col gap-2 items-center md:items-start"
variants={containerVariants}
>
<motion.div
className="flex items-center text-sm text-muted-foreground"
variants={childVariants}
whileHover={{ scale: 1.05, color: "#4b5563" }}
>
<MapPin className="h-4 w-4 mr-2" />
📍 {personalInfo.location}
</motion.div>
<motion.a
href={`mailto:${personalInfo.email}`}
className="flex items-center text-sm text-muted-foreground hover:text-foreground transition-colors"
variants={childVariants}
whileHover={{ scale: 1.05, color: "#4b5563" }}
>
<Mail className="h-4 w-4 mr-2" />
{personalInfo.email}
</motion.a>
<motion.a
href={personalInfo.github}
target="_blank"
rel="noopener noreferrer"
className="flex items-center text-sm text-muted-foreground hover:text-foreground transition-colors"
variants={childVariants}
whileHover={{ scale: 1.05, color: "#4b5563" }}
>
<Github className="h-4 w-4 mr-2" />
🌟 GitHub
</motion.a>
<motion.a
href={personalInfo.linkedin}
target="_blank"
rel="noopener noreferrer"
className="flex items-center text-sm text-muted-foreground hover:text-foreground transition-colors"
variants={childVariants}
whileHover={{ scale: 1.05, color: "#4b5563" }}
>
<Linkedin className="h-4 w-4 mr-2" />
🔗 LinkedIn
</motion.a>
</motion.div>
</div>
<motion.div
className="mt-6 md:mt-0 flex justify-center"
variants={childVariants}
whileHover={{ scale: 1.05 }}
whileTap={{ scale: 0.95 }}
>
<div className="relative">
<div className="absolute -inset-1 bg-gradient-to-r from-pink-500 to-purple-500 rounded-full blur opacity-30 group-hover:opacity-100 transition duration-1000 group-hover:duration-200"></div>
<img
src="/profile.jpg"
alt="Profile"
className="w-48 md:w-60 rounded-full relative ring-2 ring-purple-500/50"
style={{ objectFit: "cover" }}
/>
</div>
</motion.div>
</motion.div>
<MotionWrapper>
<div className="bg-gradient-to-r from-purple-500/10 to-pink-500/10 backdrop-blur-sm backdrop-filter p-4 rounded-lg border border-purple-500/20 dark:border-purple-500/10 shadow-sm">
<p className="text-muted-foreground pl-4 py-2 mb-4 relative">
<span className="absolute left-0 top-0 h-full w-1 bg-gradient-to-b from-purple-500 to-pink-500 rounded-full"></span>
🚀 Passionate software engineer with a versatile skill set
spanning multiple domains. I thrive on solving complex challenges
across different platforms and environments, adapting quickly to
new technologies and methodologies. My holistic approach combines
technical expertise with creative problem-solving, allowing me to
develop solutions that are both innovative and practical. I'm
driven by continuous learning and a commitment to excellence,
whether working independently or collaborating with diverse teams
to create impactful, scalable solutions.
</p>
</div>
</MotionWrapper>
</div>
</section>
);
}

View File

@@ -0,0 +1,41 @@
import React from "react";
import { motion } from "framer-motion";
import type { MotionProps } from "framer-motion";
interface MotionWrapperProps extends MotionProps {
children: React.ReactNode;
delay?: number;
}
// Default animations for sections
const defaultAnimations = {
hidden: { opacity: 0, y: 20 },
visible: (delay: number = 0) => ({
opacity: 1,
y: 0,
transition: {
duration: 0.6,
delay: delay,
ease: "easeOut",
},
}),
};
export default function MotionWrapper({
children,
delay = 0,
...props
}: MotionWrapperProps) {
return (
<motion.div
initial="hidden"
whileInView="visible"
viewport={{ once: true, margin: "-100px" }}
variants={defaultAnimations}
custom={delay}
{...props}
>
{children}
</motion.div>
);
}

View File

@@ -0,0 +1,70 @@
import React from "react";
import { projects } from "@/lib/data";
import {
CardContent,
CardDescription,
CardFooter,
CardHeader,
CardTitle,
} from "./ui/card";
import { Github } from "lucide-react";
import { GlassCard } from "./ui/glass-card";
import MotionWrapper from "./MotionWrapper";
import { motion } from "framer-motion";
export default function ProjectsSection() {
return (
<section id="projects" className="py-12 relative">
<div className="container max-w-4xl mx-auto px-6 md:px-4">
<MotionWrapper>
<h2 className="text-2xl font-bold mb-8 text-center md:text-left">
🚀 Projects
</h2>
</MotionWrapper>
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
{projects.map((project, index) => (
<MotionWrapper key={project.title} delay={index * 0.2}>
<GlassCard className="group overflow-hidden dark:border-purple-500/10 h-full flex flex-col">
<CardHeader className="bg-gradient-to-r from-purple-500/5 to-pink-500/5">
<CardTitle className="text-center md:text-left group-hover:text-purple-500 transition-colors duration-300">
{project.title}
</CardTitle>
</CardHeader>
<CardContent className="flex-grow">
<ul className="list-disc ml-4 space-y-1 text-sm group-hover:space-y-2 transition-all duration-300">
{project.description.map((desc, i) => (
<motion.li
key={i}
className="text-muted-foreground"
initial={{ opacity: 0, x: -10 }}
whileInView={{ opacity: 1, x: 0 }}
transition={{ delay: i * 0.1 }}
viewport={{ once: true }}
>
{desc}
</motion.li>
))}
</ul>
</CardContent>
<CardFooter className="flex justify-center md:justify-start items-center border-t border-border/30 bg-gradient-to-r from-purple-500/5 to-pink-500/5">
<motion.a
href={project.github}
target="_blank"
rel="noopener noreferrer"
className="flex items-center text-sm text-muted-foreground hover:text-purple-500 transition-colors group/link pt-8"
whileHover={{ scale: 1.05 }}
whileTap={{ scale: 0.95 }}
>
<Github className="h-4 w-4 mr-2 group-hover/link:rotate-12 transition-transform duration-300" />
View on GitHub 🔗
</motion.a>
</CardFooter>
</GlassCard>
</MotionWrapper>
))}
</div>
</div>
</section>
);
}

View File

@@ -0,0 +1,148 @@
import React from "react";
import { skills } from "@/lib/data";
import { motion } from "framer-motion";
import MotionWrapper from "./MotionWrapper";
import { GlassCard } from "./ui/glass-card";
function SkillTag({ skill, index }: { skill: string; index: number }) {
return (
<motion.div
initial={{ opacity: 0, scale: 0.8 }}
whileInView={{ opacity: 1, scale: 1 }}
transition={{
type: "spring",
stiffness: 260,
damping: 20,
delay: 0.05 * index,
}}
whileHover={{ scale: 1.05, y: -2 }}
className="px-3 py-1 bg-muted/80 backdrop-blur-sm rounded-md text-sm border border-purple-500/10 shadow-sm"
>
{skill}
</motion.div>
);
}
const containerVariants = {
hidden: { opacity: 0 },
visible: {
opacity: 1,
transition: {
staggerChildren: 0.1,
},
},
};
const skillCategoryVariants = {
hidden: { opacity: 0, y: 20 },
visible: {
opacity: 1,
y: 0,
transition: {
duration: 0.5,
},
},
};
export default function SkillsSection() {
return (
<section
id="skills"
className="py-12 bg-gradient-to-b from-background to-muted/20"
>
<div className="container max-w-4xl mx-auto px-6 md:px-4">
<MotionWrapper>
<h2 className="text-2xl font-bold mb-8 text-center md:text-left">
🛠 Skills
</h2>
</MotionWrapper>
<motion.div
className="space-y-6"
variants={containerVariants}
initial="hidden"
whileInView="visible"
viewport={{ once: true, margin: "-50px" }}
>
<motion.div variants={skillCategoryVariants}>
<GlassCard className="p-4">
<h3 className="text-lg font-medium mb-3 text-center md:text-left flex items-center">
<span className="mr-2 text-xl">💻</span> Programming Languages
</h3>
<div className="flex flex-wrap gap-2 justify-center md:justify-start">
{skills.programmingLanguages.map((skill, index) => (
<SkillTag key={skill} skill={skill} index={index} />
))}
</div>
</GlassCard>
</motion.div>
<motion.div variants={skillCategoryVariants}>
<GlassCard className="p-4">
<h3 className="text-lg font-medium mb-3 text-center md:text-left flex items-center">
<span className="mr-2 text-xl">🎨</span> Frontend Development
</h3>
<div className="flex flex-wrap gap-2 justify-center md:justify-start">
{skills.frontendDevelopment.map((skill, index) => (
<SkillTag key={skill} skill={skill} index={index} />
))}
</div>
</GlassCard>
</motion.div>
<motion.div variants={skillCategoryVariants}>
<GlassCard className="p-4">
<h3 className="text-lg font-medium mb-3 text-center md:text-left flex items-center">
<span className="mr-2 text-xl"></span> Backend Development
</h3>
<div className="flex flex-wrap gap-2 justify-center md:justify-start">
{skills.backendDevelopment.map((skill, index) => (
<SkillTag key={skill} skill={skill} index={index} />
))}
</div>
</GlassCard>
</motion.div>
<motion.div variants={skillCategoryVariants}>
<GlassCard className="p-4">
<h3 className="text-lg font-medium mb-3 text-center md:text-left flex items-center">
<span className="mr-2 text-xl">🗄</span> Database & Storage
</h3>
<div className="flex flex-wrap gap-2 justify-center md:justify-start">
{skills.databaseAndStorage.map((skill, index) => (
<SkillTag key={skill} skill={skill} index={index} />
))}
</div>
</GlassCard>
</motion.div>
<motion.div variants={skillCategoryVariants}>
<GlassCard className="p-4">
<h3 className="text-lg font-medium mb-3 text-center md:text-left flex items-center">
<span className="mr-2 text-xl"></span> Cloud & DevOps
</h3>
<div className="flex flex-wrap gap-2 justify-center md:justify-start">
{skills.cloudAndDevOps.map((skill, index) => (
<SkillTag key={skill} skill={skill} index={index} />
))}
</div>
</GlassCard>
</motion.div>
<motion.div variants={skillCategoryVariants}>
<GlassCard className="p-4">
<h3 className="text-lg font-medium mb-3 text-center md:text-left flex items-center">
<span className="mr-2 text-xl">🧰</span> Tools & Services
</h3>
<div className="flex flex-wrap gap-2 justify-center md:justify-start">
{skills.toolsAndServices.map((skill, index) => (
<SkillTag key={skill} skill={skill} index={index} />
))}
</div>
</GlassCard>
</motion.div>
</motion.div>
</div>
</section>
);
}

View File

@@ -0,0 +1,76 @@
import * as React from "react";
import { cn } from "@/lib/utils";
import { motion } from "framer-motion";
interface TimelineItemProps {
title: string;
subtitle: string;
date: string;
isLast?: boolean;
index?: number;
children?: React.ReactNode;
}
export default function TimelineItem({
title,
subtitle,
date,
isLast = false,
index = 0,
children,
}: TimelineItemProps) {
return (
<motion.div
className="relative flex gap-6"
initial={{ opacity: 0, y: 20 }}
whileInView={{ opacity: 1, y: 0 }}
transition={{ duration: 0.5, delay: index * 0.2 }}
viewport={{ once: true, margin: "-50px" }}
>
<div className="flex flex-col items-center">
<motion.div
className="flex h-[18px] w-[18px] rounded-full border border-purple-500/50 bg-background dark:bg-muted z-10"
initial={{ scale: 0 }}
whileInView={{ scale: 1 }}
transition={{
type: "spring",
stiffness: 300,
damping: 15,
delay: index * 0.2 + 0.2,
}}
viewport={{ once: true, margin: "-50px" }}
/>
{!isLast && (
<motion.div
className="w-px grow bg-gradient-to-b from-purple-500/50 to-pink-500/30 dark:from-purple-500/30 dark:to-pink-500/10"
initial={{ height: 0 }}
whileInView={{ height: "100%" }}
transition={{ duration: 0.8, delay: index * 0.2 + 0.3 }}
viewport={{ once: true, margin: "-50px" }}
/>
)}
</div>
<div className={cn("pb-8", isLast ? "pb-0" : "")}>
<motion.div
className="flex flex-col gap-0.5"
initial={{ opacity: 0, x: -20 }}
whileInView={{ opacity: 1, x: 0 }}
transition={{ duration: 0.5, delay: index * 0.2 + 0.1 }}
viewport={{ once: true, margin: "-50px" }}
>
<h3 className="font-medium">{title}</h3>
<p className="text-sm text-muted-foreground">{subtitle}</p>
<p className="text-xs text-muted-foreground/70 mb-2">{date}</p>
</motion.div>
<motion.div
initial={{ opacity: 0 }}
whileInView={{ opacity: 1 }}
transition={{ duration: 0.5, delay: index * 0.2 + 0.4 }}
viewport={{ once: true, margin: "-50px" }}
>
{children}
</motion.div>
</div>
</motion.div>
);
}

View File

@@ -1,31 +0,0 @@
---
const { title, url, date, image, tags = [], languages = [] } = Astro.props;
import Tag from "../ui/Tag.astro";
import ReadMore from "../ui/ReadMore.astro";
import DatePub from "./DatePub.astro";
import Capsule from "../ui/Capsule.astro";
---
<article class="bg-white dark:bg-zinc-900/25 dark:border dark:border-zinc-800 dark:hover:border-mint-300 hover:backdrop-blur-none backdrop-blur-lg shadow-sm overflow-auto hover:shadow-[5px_5px_rgba(0,98,90,0.4),10px_10px_rgba(0,98,90,0.3),15px_15px_rgba(0,98,90,0.2),20px_20px_rgba(0,98,90,0.1),25px_25px_rgba(0,98,90,0.05)] p-8 max-md:p-6 w-full flex justify-between items-center bg-linear-to-r hover:from-teal-200 hover:to-emerald-200 dark:hover:from-riptide-500 dark:hover:to-mint-500 transition-all hover:scale-105 duration-200 ease-in-out gap-8 max-md:gap-4 rounded-3xl max-md:flex-col-reverse">
<div class="flex flex-col">
<a href={url} class="flex flex-col gap-4 w-full">
<DatePub date={date} />
<h2 class="dark:text-mint-50 text-blacktext text-3xl font-bold text-pretty">{title}</h2>
<ReadMore />
</a>
<div class="gap-3 mt-3 flex flex-col">
<div class="flex gap-2 flex-wrap">
{languages.length > 0 && languages.map((language: string) => <Capsule lang={language} />)}
</div>
<div class="gap-2 flex flex-wrap justify-start items-center">
{tags.length > 0 && tags.map((tag: string) => <Tag tag={tag}>{tag}</Tag>)}
</div>
</div>
</div>
{image?.url && (
<a href={url} style={{ backgroundImage: `url(${image.url})` }} class="shrink-0 rounded-2xl bg-center bg-cover aspect-video max-md:aspect-video w-2/6 max-md:w-full" />
)}
</article>

View File

@@ -1,28 +0,0 @@
---
const {date, class: className} = Astro.props;
---
<span
class={`flex flex-row center text-sm font-semibold items-center gap-3 text-blacktext dark:text-riptide-50 ${className || ''}`}
>
<svg
width="15"
height="15"
viewBox="0 0 15 15"
fill="none"
xmlns="http://www.w3.org/2000/svg"
><path
d="M4.5 1C4.77614 1 5 1.22386 5 1.5V2H10V1.5C10 1.22386 10.2239 1 10.5 1C10.7761 1 11 1.22386 11 1.5V2H12.5C13.3284 2 14 2.67157 14 3.5V12.5C14 13.3284 13.3284 14 12.5 14H2.5C1.67157 14 1 13.3284 1 12.5V3.5C1 2.67157 1.67157 2 2.5 2H4V1.5C4 1.22386 4.22386 1 4.5 1ZM10 3V3.5C10 3.77614 10.2239 4 10.5 4C10.7761 4 11 3.77614 11 3.5V3H12.5C12.7761 3 13 3.22386 13 3.5V5H2V3.5C2 3.22386 2.22386 3 2.5 3H4V3.5C4 3.77614 4.22386 4 4.5 4C4.77614 4 5 3.77614 5 3.5V3H10ZM2 6V12.5C2 12.7761 2.22386 13 2.5 13H12.5C12.7761 13 13 12.7761 13 12.5V6H2ZM7 7.5C7 7.22386 7.22386 7 7.5 7C7.77614 7 8 7.22386 8 7.5C8 7.77614 7.77614 8 7.5 8C7.22386 8 7 7.77614 7 7.5ZM9.5 7C9.22386 7 9 7.22386 9 7.5C9 7.77614 9.22386 8 9.5 8C9.77614 8 10 7.77614 10 7.5C10 7.22386 9.77614 7 9.5 7ZM11 7.5C11 7.22386 11.2239 7 11.5 7C11.7761 7 12 7.22386 12 7.5C12 7.77614 11.7761 8 11.5 8C11.2239 8 11 7.77614 11 7.5ZM11.5 9C11.2239 9 11 9.22386 11 9.5C11 9.77614 11.2239 10 11.5 10C11.7761 10 12 9.77614 12 9.5C12 9.22386 11.7761 9 11.5 9ZM9 9.5C9 9.22386 9.22386 9 9.5 9C9.77614 9 10 9.22386 10 9.5C10 9.77614 9.77614 10 9.5 10C9.22386 10 9 9.77614 9 9.5ZM7.5 9C7.22386 9 7 9.22386 7 9.5C7 9.77614 7.22386 10 7.5 10C7.77614 10 8 9.77614 8 9.5C8 9.22386 7.77614 9 7.5 9ZM5 9.5C5 9.22386 5.22386 9 5.5 9C5.77614 9 6 9.22386 6 9.5C6 9.77614 5.77614 10 5.5 10C5.22386 10 5 9.77614 5 9.5ZM3.5 9C3.22386 9 3 9.22386 3 9.5C3 9.77614 3.22386 10 3.5 10C3.77614 10 4 9.77614 4 9.5C4 9.22386 3.77614 9 3.5 9ZM3 11.5C3 11.2239 3.22386 11 3.5 11C3.77614 11 4 11.2239 4 11.5C4 11.7761 3.77614 12 3.5 12C3.22386 12 3 11.7761 3 11.5ZM5.5 11C5.22386 11 5 11.2239 5 11.5C5 11.7761 5.22386 12 5.5 12C5.77614 12 6 11.7761 6 11.5C6 11.2239 5.77614 11 5.5 11ZM7 11.5C7 11.2239 7.22386 11 7.5 11C7.77614 11 8 11.2239 8 11.5C8 11.7761 7.77614 12 7.5 12C7.22386 12 7 11.7761 7 11.5ZM9.5 11C9.22386 11 9 11.2239 9 11.5C9 11.7761 9.22386 12 9.5 12C9.77614 12 10 11.7761 10 11.5C10 11.2239 9.77614 11 9.5 11Z"
fill="currentColor"
fill-rule="evenodd"
clip-rule="evenodd"></path></svg
>
{
new Date(date).toLocaleDateString("en-US", {
timeZone: "UTC", // Avoid timezone adjustments
day: "numeric",
month: "long",
year: "numeric",
})
}</span
>

View File

@@ -1,103 +0,0 @@
---
import Button from "../ui/Button.astro";
import LastPost from "../blog/LastPost.astro";
import Languages from "../blog/Languages.astro";
import { Icon } from "astro-icon/components";
import Heading from "../ui/Heading.astro";
import { AstroError } from "astro/errors";
import { getCollection} from "astro:content";
const [staticData] = await getCollection('staticData');
if (!staticData) {
throw new AstroError("JSON data not found");
}
---
<section class="py-8 px-8 max-sm:px-4 max-sm:py-2">
<div
class="grid md:grid-cols-4 md:grid-rows-2 gap-4 max-sm:gap-3 grid-cols-2 grid-rows-4 max-w-7xl mx-auto max-md:h-[80vh] max-sm:h-auto max-sm:grid-rows-[auto_200px_auto_auto] max-xl:h-[550px] xl:h-[700px]"
>
<div
class="p-8 max-md:gap-0 max-xl:p-5 h-full max-md:p-4 max-lg:gap-1 gap-3 flex flex-col border border-emerald-50 rounded-2xl dark:bg-zinc-800 bg-linear-to-r from-riptide-200 to-mint-200 dark:from-riptide-500 dark:to-mint-500 dark:border-zinc-800 dark:border-2 dark:bg-gradient-radial md:col-start-4 col-start-2 row-start-2"
>
<Heading text={staticData.data.techsTitle} textGradient="" level={3}/>
<div class="overflow-y-auto">
<Languages />
</div>
</div>
<div
class="group hover:shadow-[0_20px_50px_rgba(13,188,130,0.4)] hover:scale-105 z-40 rounded-2xl transition-all ease-in duration-150 col-start-1 row-start-2 md:col-start-3 bg-linear-to-r from-mint-300 dark:from-mint-600 to-mint-50 dark:to-mint-200/5 hover:to-mint-300/30 dark:hover:to-mint-600/30 p-[.2rem] "
>
<div class="w-full h-full overflow-hidden rounded-2xl dark:bg-zinc-900">
<div
class="w-full h-full relative overflow-hidden rounded-2xl bg-linear-to-tr from-riptide-100 to-white dark:from-transparent dark:bg-linear-to-bl dark:to-transparent "
>
<a target="_blank" href={staticData.data.github}>
<div
class="p-8 h-full relative max-xl:p-5 max-md:p-4 flex flex-col gap-8 dark:before:bg-[radial-gradient(circle,rgba(13,188,130)_0,rgba(1,45,34)_100%)] before:bg-[radial-gradient(circle,rgba(95,255,202)_0,rgba(144,253,210)_100%)] before:h-[30%] before:absolute before:aspect-square xl:before:bottom-10 before:left-30 before:bottom-30 before:rounded-full before:blur-3xl before:opacity-90 before:transition before:z-0"
>
<div class="z-2">
<Heading
text={staticData.data.githubText}
textGradient=""
level={3}
/>
</div>
<Icon
class="group-hover:animate-pulse ease-in-out size-50 absolute -bottom-10 xl:size-56 xl:-bottom-5 left-30 max-sm:left-10 max-md:left-30 xl:-right-24 text-mint-500/30"
name="github"
/>
</div>
</a>
</div>
</div>
</div>
<div
class="flex col-span-2 col-start-1 row-start-1 md:col-start-3 bg-linear-to-r rounded-2xl from-mint-300 dark:from-mint-600 to-mint-50 dark:to-mint-200/5 hover:to-mint-300/30 dark:hover:to-mint-600/30 p-[.2rem] "
>
<article
class="group hover:shadow-[0_10px_50px_rgba(13,188,130,0.2)] w-full h-full overflow-hidden p-4 max-md:p-4 gap-4 max-md:gap-1 max-lg:gap-0 rounded-2xl bg-linear-to-tr from-riptide-100 to-mint-50 flex dark:bg-linear-to-r z-0 dark:overflow-hidden relative dark:from-mint-900 dark:to-mint-950 dark:before:bg-[radial-gradient(circle,rgba(13,188,130)_0,rgba(1,45,34)_100%)] before:bg-[radial-gradient(circle,rgba(95,255,202)_0,rgba(144,253,210)_100%)] dark:before:h-[80%] before:h-[30%] before:absolute before:aspect-square dark:before:left-30 before:left-50 dark:before:-bottom-0 before:bottom-40 before:rounded-full dark:before:blur-3xl before:blur-2xl dark:before:opacity-80 before:opacity-100 before:-z-10 before:transition"
>
<div
class="group-hover:scale-103 ease-in-out duration-500 w-5/12 max-sm:w-auto flex justify-center items-center"
>
<div
aria-label={staticData.data.profileAlt}
class="h-full w-full max-sm:rounded-full rounded-2xl max-sm:size-20 bg-center bg-cover"
style={`background-image: url(${staticData.data.profileImage})`}
>
<a href={staticData.data.profileLink} class="h-full w-full flex"></a>
</div>
</div>
<div class="p-4 w-7/12 flex flex-col justify-center gap-4 max-sm:w-fit max-md:gap-2">
<span
class="font-extrabold text-lg max-xl:text-base max-lg:text-sm max-lg:flex max-lg:flex-col-reverse max-md:flex-row leading-normal max-sm:leading-none"
><b
class="bg-linear-to-r from-riptide-400 to-mint-400 dark:from-riptide-200 dark:to-mint-400 text-transparent bg-clip-text"
>{staticData.data.profileTitle}</b
> 🚀</span
>
<Heading
text={staticData.data.profileName}
level={3}
/>
<Button
link={staticData.data.profileLink}
text="About Me"
iconName="person"
class="drop-shadow-xl"
/>
</div>
</article>
</div>
<div class="col-span-2 row-span-2 md:col-start-1 md:row-start-1 bg-conic/[from_var(--border-angle)] dark:from-mint-200/30 dark:via-mint-500 dark:to-mint-200/20 from-mint-300/30 via-mint-500 to-mint-300/20 from-20% to-80% animate-rotate-border rounded-2xl p-[.2rem]">
<LastPost />
</div>
</div>
</section>

View File

@@ -1,27 +0,0 @@
---
const allPosts = await Astro.glob("../../pages/blog/posts/*.md");
const languages = [
...new Set(allPosts.map((post) => post.frontmatter.languages).flat()),
];
import Capsule from "../ui/Capsule.astro";
const { variant = "default" } = Astro.props;
const baseClasses = "flex flex-wrap";
const variantClasses = {
default: "gap-3 max-lg:gap-1",
vertical: "gap-6 flex-col"
} as const;
const classes = `${baseClasses} ${variantClasses[variant as keyof typeof variantClasses] || variantClasses.default}`;
---
<div class={classes}>
{languages.map((language) => (
<Capsule lang={language} linkEnabled={true} size="md" />
))}
</div>

View File

@@ -1,83 +0,0 @@
---
const allPosts = await Astro.glob("../../pages/blog/posts/*.md");
import Tag from "../ui/Tag.astro";
import ReadMore from "../ui/ReadMore.astro";
import Capsule from "../ui/Capsule.astro";
import DatePub from "./DatePub.astro";
// Get the latest post using reduce
const latestPost = allPosts.reduce((latest, current) => {
const latestDate = new Date(latest.frontmatter.pubDate).getTime();
const currentDate = new Date(current.frontmatter.pubDate).getTime();
return currentDate > latestDate ? current : latest;
});
const tags = [...new Set(latestPost.frontmatter.tags ?? [])];
const languages = [...new Set(latestPost.frontmatter.languages ?? [])];
const image = latestPost.frontmatter.image.url;
const imageAlt =
latestPost.frontmatter.image.alt || latestPost.frontmatter.title;
---
{
latestPost && (
<div
style={{ backgroundImage: `url(${image})` }}
class="h-full hover:shadow-[0_20px_50px_rgba(13,188,130,0.2)] flex flex-col overflow-hidden rounded-2xl bg-linear-to-br bg-center bg-cover transition-all ease-in-out duration-200"
role="article"
aria-labelledby="post-title"
>
<article class="h-full flex flex-col justify-between max-sm:bg-zinc-900 max-sm:relative sm:bg-linear-to-t from-black/95 from-25% to-transparent max-sm:from-60% p-8 max-md:p-6 max-sm:mp-0 max-sm:p-0">
<a
href=""
class="sm:hidden relative top-0 left-0 w-full h-auto -z-0"
aria-hidden="true"
>
<img
src={image}
alt={imageAlt}
class="w-full h-auto"
loading="lazy"
/>
</a>
<div
class="w-full flex pb-5 gap-2 flex-wrap justify-end z-10 max-sm:px-6 max-sm:pt-6"
role="list"
aria-label="Programming languages"
>
{languages.map((language: unknown) => (
<Capsule lang={language?.toString() || ""} />
))}
</div>
<a
href={latestPost.url}
class="text-mint-50 gap-3 h-full flex items-end max-sm:px-6 rounded-lg transition-all"
aria-label={`Read article: ${latestPost.frontmatter.title}`}
>
<div class="gap-3 flex flex-col justify-end drop-shadow-[1px_6px_1px_rgba(0,0,0,0.3)]">
<DatePub date={latestPost.frontmatter.pubDate} class="text-mint-50" />
<h2
id="post-title"
class="text-4xl max-xl:text-3xl max-sm:text-2xl font-bold"
>
<span>{latestPost.frontmatter.title}</span>
</h2>
<ReadMore class="text-mint-50" />
</div>
</a>
<div
class="gap-2 mt-3 justify-start items-center flex flex-row flex-wrap max-sm:px-6 max-sm:pb-6"
role="list"
aria-label="Article tags"
>
{tags.map((tag) => (
<Tag tag={tag} forceDark="true">{tag}</Tag>
))}
</div>
</article>
</div>
)
}

View File

@@ -1,82 +0,0 @@
---
import BlogPost from "./BlogPost.astro";
import Heading from "../ui/Heading.astro";
// Prop to determine whether to exclude the latest post or a specific post
export interface Props {
excludeLatest?: boolean;
currentPostUrl?: string;
all?: boolean;
}
const { excludeLatest = false, currentPostUrl = "", all = false } = Astro.props;
const allPosts = await Astro.glob("../../pages/blog/posts/*.md");
// Sort by date in descending order (newest first)
allPosts.sort((a, b) => {
const dateA = new Date(a.frontmatter.pubDate).getTime();
const dateB = new Date(b.frontmatter.pubDate).getTime();
return dateB - dateA;
});
// Filter posts according to props
let postsToShow = allPosts;
if (currentPostUrl) {
// Exclude current post if its URL is provided
postsToShow = postsToShow.filter((post) => {
if (!post.url) return false; // If no URL, keep the post
// Normalize URLs for comparison
const normalizedPostUrl = post.url.replace(/\/$/, ""); // Remove trailing slash if exists
const normalizedCurrentUrl = currentPostUrl.replace(/\/$/, ""); // Remove trailing slash if exists
return normalizedPostUrl !== normalizedCurrentUrl;
});
} else if (excludeLatest) {
// If no specific URL but want to exclude the latest
postsToShow = postsToShow.slice(1);
}
// Limit to 4 posts if all is false
if (!all) {
postsToShow = postsToShow.slice(0, 4);
}
---
<section
class="py-8 max-lg:px-4 max-md:px-8 max-sm:px-0 max-md:py-4 max-w-4xl mx-auto"
>
{
all && (
<div class="flex gap-4 pb-6 items-center text-center justify-center">
<Heading text="All" textGradient="Posts" level={2} />
</div>
)
}
<div class="flex flex-col gap-8 w-full mx-auto">
{
postsToShow.map((post) => (
<BlogPost
url={post.url}
title={post.frontmatter.title}
date={post.frontmatter.pubDate}
tags={post.frontmatter.tags}
languages={post.frontmatter.languages}
image={post.frontmatter.image}
/>
))
}
</div>
{
!all && (
<div id="morePosts" class="w-full flex justify-center text-center my-12">
<a
href="/blog/posts/"
class="font-bold cursor-pointer text-mint-400 dark:text-mint-100 hover:text-mint-500 dark:hover:text-mint-300 transition-all"
>
View all posts...
</a>
</div>
)
}
</section>

View File

@@ -1,32 +0,0 @@
---
const allPosts = await Astro.glob("../../pages/blog/posts/*.md");
import Tag from "../ui/Tag.astro";
const tags = [...new Set(allPosts.map((post) => post.frontmatter.tags).flat())];
type VariantType = "default" | "vertical" | "compact";
const { variant = "default" } = Astro.props as { variant?: VariantType };
// Common base classes
const baseClasses = "max-w-7xl";
// Variant-specific classes
const variantClasses: Record<VariantType, string> = {
default: "max-lg:px-8 py-8 max-md:py-4 flex-wrap mx-auto gap-4 max-sm:gap-3 justify-center items-center flex flex-row",
vertical: "gap-6 justify-start items-start flex flex-col",
compact: "flex-wrap mx-auto gap-2 max-sm:gap-3 justify-start flex flex-row"
};
// Combine base classes with variant-specific classes
const classes = `${baseClasses} ${variantClasses[variant]}`;
---
<div id="tags" class={classes}>
{tags.map((tag) => <Tag tag={tag}></Tag>)}
</div>

View File

@@ -1,47 +0,0 @@
---
import Social from "../ui/Social.astro";
import { Icon } from "astro-icon/components";
import { AstroError } from "astro/errors";
import { getCollection} from "astro:content";
const [staticData] = await getCollection('staticData');
if (!staticData) {
throw new AstroError("JSON data not found");
}
---
<footer
class="relative bottom-0 w-full px-4 py-8 font-medium text-blacktext dark:bg-transparent dark:border-b-2 dark:border-zinc-800 dark:text-zinc-300 max-lg:mt-3"
role="contentinfo"
aria-label="Site footer"
>
<nav
class="mx-auto flex max-w-7xl flex-row items-center justify-between gap-4 text-xl max-xl:px-6 max-sm:flex-col"
aria-label="Footer navigation"
>
<div
class="relative h-6 cursor-pointer before:absolute before:left-1/2 before:top-1/2 before:h-full before:w-[40%] before:-translate-x-1/2 before:-translate-y-1/2 before:rounded-full before:bg-[#50fd8f25] before:blur-3xl before:opacity-80 before:-z-1 hover:text-mint-500 transition-all [text-shadow:0_1px_2px_#000]"
>
<a href="/" aria-label="Return to homepage">
<!-- This icon represents the logo -->
<Icon name="logo" aria-hidden="true" />
</a>
</div>
<div class="text-center">
<a
href={staticData.data.github}
class="flex items-center justify-center gap-3 text-base font-normal italic max-sm:text-sm"
aria-label="About the website development"
><Icon name="code" aria-hidden="true" /> Developed by <strong>{staticData.data.alias}</strong>, with Astro</a
>
</div>
<div class="flex items-center justify-center gap-5" role="list" aria-label="Social media links">
<Social link={`mailto:${staticData.data.email}`} iconName={staticData.data.emailIconName} label={`Send email to ${staticData.data.email}`} />
<Social link={staticData.data.instagram} iconName={staticData.data.instagramIconName} label={`Visit ${staticData.data.alias} on Instagram`} />
<Social link={staticData.data.youtube} iconName={staticData.data.youtubeIconName} label={`Visit ${staticData.data.alias} on YouTube`} />
<Social link={staticData.data.github} iconName={staticData.data.githubIconName} label={`Visit ${staticData.data.alias} on GitHub`} />
<Social link={staticData.data.linkedin} iconName={staticData.data.linkedinIconName} label={`Visit ${staticData.data.alias} on LinkedIn`} />
</div>
</nav>
</footer>

View File

@@ -1,63 +0,0 @@
---
import Navigation from "./Navigation.astro";
import ThemeIcon from "../ui/ThemeIcon.astro";
import Social from "../ui/Social.astro";
import { Icon } from "astro-icon/components";
import { AstroError } from "astro/errors";
import { getCollection} from "astro:content";
const [staticData] = await getCollection('staticData');
if (!staticData) {
throw new AstroError("JSON data not found");
}
const currentPath = Astro.url.pathname;
const routes = ["/", "/portfolio", "/about-me", ];
// Check if the current route is in the list of routes
const isActiveRoute = routes.includes(currentPath);
const navItems = isActiveRoute
? ["home", "experience", "projects", "about", "blog",]
: ["home", "blog", "about"]; // Change the items
---
<header
role="banner"
aria-label="Main navigation"
class="sticky top-0 z-50 w-full p-4 font-medium text-blacktext dark:text-zinc-300 dark:bg-[#0E0E11]/80 dark:border-b dark:border-zinc-800 bg-white/90 backdrop-blur-xs dark:backdrop-blur-xs max-md:z-50 max-md:px-0 transition-all"
>
<div
class="relative mx-auto flex max-w-7xl flex-row items-center justify-between max-xl:px-6"
>
<a href="/" aria-label="Go to home">
<Icon
name="logo"
class="h-6 cursor-pointer transition-all hover:text-mint-300"
aria-hidden="true"
/>
</a>
<Navigation items={navItems} />
<div class="flex items-center justify-between gap-5 text-xl">
<div class="max-md:hidden flex items-center justify-center gap-5" role="list">
<Social link={staticData.data.github} iconName={staticData.data.githubIconName} />
<Social link={staticData.data.linkedin} iconName={staticData.data.linkedinIconName} />
</div>
</div>
<div class="flex items-center gap-5 text-xl md:pl-5">
<ThemeIcon />
<button
class="hamburger"
aria-label="Open menu"
aria-expanded="false"
aria-controls="mobile-menu"
>
<Icon name="bars" class="hamburger-icon bars-icon" aria-hidden="true" />
<Icon name="xmark" class="hamburger-icon xmark-icon" aria-hidden="true" />
</button>
</div>
</div>
</header>

View File

@@ -1,92 +0,0 @@
---
const { title } = Astro.props;
---
<div class="max-xl:hidden ">
<div id="nav-content" class="bg-white dark:bg-transparent sticky w-72 mt-8 rounded-2xl dark:border-0 border border-neutral-100 top-14 max-h-[calc(100svh-3.5rem)] overflow-x-hidden px-6 pt-8 pb-12">
<div class="flex flex-col gap-4 pl-0">
<div>
<h3 class="dark:text-zinc-400 text-blacktext/90 font-black tracking-wide text-md uppercase">Table of Contents</h3>
</div>
<div class="flex flex-col gap-2 pr-6 text-neutral-500 dark:text-neutral-300 ">
<ul id="toc-list" class="leading-loose text-base gap-2 border-l dark:border-neutral-500/20 border-blacktext/20">
<li class="leading-loose">
<a class="inline-block leading-5 pl-4 font-bold text-white border-l dark:border-white border-blacktext dark:hover:border-white hover:border-blacktext" href="#">{title}</a>
</li>
</ul>
</div>
</div>
</div>
</div>
<script>
document.addEventListener("DOMContentLoaded", function () {
const tocList = document.getElementById("toc-list");
const content = document.getElementById("content");
if (!tocList || !content) return;
const headers = content.querySelectorAll("h2, h3");
let currentUl = tocList;
headers.forEach((header, index) => {
if (!header.id) {
header.id = header.textContent?.trim().toLowerCase().replace(/\s+/g, "-") + "-" + index;
// 👈 Add the class
}
const li = document.createElement("li");
const link = document.createElement("a");
link.href = `#${header.id}`;
link.textContent = header.textContent?.trim() || header.id;
// If the header is H2, keep pl-6, and if it's H3, use pl-12
link.classList.add("inline-block","leading-5", "hover:text-mint-400", "py-2", "border-l", "border-transparent", "dark:hover:border-white","hover:border-blacktext");
link.classList.add(header.tagName === "H2" ? "pl-6" : "pl-12");
console.log("classes removed 2");
li.appendChild(link);
if (header.tagName === "H2") {
currentUl = document.createElement("ul");
currentUl.classList.add("border-neutral-400","dark:hover:border-white","hover:border-blacktext", "pl-0");
console.log("classes removed 3");
const h2Li = document.createElement("li");
h2Li.appendChild(link);
h2Li.appendChild(currentUl);
tocList.appendChild(h2Li);
} else {
currentUl.appendChild(li);
}
// Smooth scroll when clicking on a link
link.addEventListener("click", function (e) {
e.preventDefault();
document.getElementById(header.id)?.scrollIntoView({ behavior: "smooth", block: "start" });
});
});
// 👇 Detect the active header
const observer = new IntersectionObserver(
(entries) => {
entries.forEach((entry) => {
const id = entry.target.getAttribute("id");
const link = document.querySelector(`a[href="#${id}"]`);
if (entry.isIntersecting) {
// Remove class from all and add only to the active one
document.querySelectorAll("#toc-list a").forEach((el) => {
el.classList.remove("font-semibold", "dark:text-mint-300!", "text-blacktext!", "dark:border-white!", "border-blacktext!" );
el.classList.add("dark:text-neutral-300","text-neutral-500" );
console.log("classes removed 4");
});
link?.classList.add("font-semibold", "dark:text-mint-300!", "text-blacktext!", "border-l", "dark:border-white!", "border-blacktext!");
}
});
},
{ rootMargin: "-30% 0px -65% 0px", threshold: 0.1 } // Adjusted to improve visibility
);
headers.forEach((header) => observer.observe(header));
});
</script>

View File

@@ -1,168 +0,0 @@
---
import Social from "../ui/Social.astro";
import { AstroError } from "astro/errors";
import { getCollection} from "astro:content";
const [staticData] = await getCollection('staticData');
if (!staticData) {
throw new AstroError("JSON data not found");
}
const { items = [] }: { items: (keyof typeof menu)[] } = Astro.props as {
items: (keyof typeof menu)[];
};
const menu = {
about: { name: "About Me", path: "/about-me" },
blog: {
name: "Blog",
path: "/blog/",
dropdown: [
{ name: "All Posts", path: "/blog/posts/" },
]
},
home: { name: "Home", path: "/#home" },
experience: { name: "Experience", path: "/#experience" },
projects: { name: "Projects", path: "/#projects" },
};
// Common base classes
const baseClasses = {
nav: "nav-links flex w-full justify-center gap-6 max-md:gap-3 max-md:py-6",
link: "px-2 py-2 transition-all hover:text-mint-300 max-md:mx-auto max-md:w-full max-md:px-6 max-md:py-2 ",
socialContainer: "flex items-center justify-center gap-5 md:hidden",
dropdown: "relative group flex items-center",
dropdownMenu: "absolute left-0 top-full hidden group-hover:block bg-white dark:bg-zinc-800 shadow-lg rounded-md py-2 min-w-[200px] z-50",
dropdownItem: "block px-4 py-2 text-sm hover:bg-mint-100 dark:hover:bg-zinc-700 transition-colors"
} as const;
---
<script>
document.addEventListener("DOMContentLoaded", () => {
const isHome = window.location.pathname === "/";
// Classes for link states
const linkClasses = {
active: ["text-mint-500","dark:text-mint-400", "font-bold", "[text-shadow:1px_1px_11px_rgba(208,251,229,0.7)]"],
inactive: ["dark:text-zinc-300", "text-blacktext"]
};
function toggleLinkClasses(link: Element, isActive: boolean) {
if (isActive) {
link.classList.add(...linkClasses.active);
link.classList.remove(...linkClasses.inactive);
link.setAttribute('aria-current', 'page');
} else {
link.classList.remove(...linkClasses.active);
link.classList.add(...linkClasses.inactive);
link.removeAttribute('aria-current');
}
}
function updateActiveLink() {
const currentPath = window.location.pathname;
const currentHash = window.location.hash ? `#${window.location.hash.substring(1)}` : "";
document.querySelectorAll("nav a").forEach((link) => {
const path = link.getAttribute("data-path");
toggleLinkClasses(link, path === currentPath || path === currentHash);
});
}
function setupScrollSpy() {
if (!isHome) return;
const sections = document.querySelectorAll("section[id]");
const navLinks = document.querySelectorAll("nav a");
const observerOptions = {
root: null,
rootMargin: "-50% 0px",
threshold: 0
};
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
const sectionId = entry.target.getAttribute("id");
if (sectionId) {
navLinks.forEach(link => {
const path = link.getAttribute("data-path");
toggleLinkClasses(link, path === `/#${sectionId}`);
});
}
}
});
}, observerOptions);
sections.forEach(section => observer.observe(section));
}
updateActiveLink();
setupScrollSpy();
window.addEventListener("hashchange", updateActiveLink);
});
</script>
<nav
class={baseClasses.nav}
role="navigation"
aria-label="Main Navigation"
>
{
items.map((key: string) => {
const item = menu[key as keyof typeof menu];
if (!item) return null;
if ('dropdown' in item) {
return (
<div class={baseClasses.dropdown}>
<a
href={item.path}
class={baseClasses.link}
data-path={item.path}
aria-label={item.name}
aria-current={item.path === Astro.url.pathname ? 'page' : undefined}
>
{item.name}
</a>
<div class={baseClasses.dropdownMenu}>
{item.dropdown.map((dropdownItem) => (
<a
href={dropdownItem.path}
class={baseClasses.dropdownItem}
data-path={dropdownItem.path}
aria-label={dropdownItem.name}
>
{dropdownItem.name}
</a>
))}
</div>
</div>
);
}
return (
<a
href={item.path}
class={baseClasses.link}
data-path={item.path}
aria-label={item.name}
aria-current={item.path === Astro.url.pathname ? 'page' : undefined}
>
{item.name}
</a>
);
})
}
<div
class={baseClasses.socialContainer}
role="group"
aria-label="Social Media Links"
>
<Social link={staticData.data.github} iconName={staticData.data.githubIconName} />
<Social link={staticData.data.linkedin} iconName={staticData.data.linkedinIconName} />
</div>
</nav>

View File

@@ -1,42 +0,0 @@
---
const allPosts = await Astro.glob("../../pages/blog/posts/*.md");
// Ensure posts have a date before sorting them
const sortedPosts = allPosts
.filter(post => post.frontmatter.pubDate)
.sort((a, b) => new Date(b.frontmatter.pubDate).getTime() - new Date(a.frontmatter.pubDate).getTime());
const currentSlug = Astro.url.pathname.split("/").filter(Boolean).pop();
const currentIndex = sortedPosts.findIndex((post) =>
post.url && post.url.includes(currentSlug || "")
);
const nextPost = currentIndex > 0 ? sortedPosts[currentIndex - 1] : null;
const prevPost = currentIndex < sortedPosts.length - 1 ? sortedPosts[currentIndex + 1] : null;
console.log({ prevPost, nextPost });
---
<nav class="mt-8 flex flex-row gap-2 w-full p-6 max-xl:p-3 max-lg:p-2">
{prevPost && (
<a
href={prevPost.url}
style="width: -webkit-fill-available;"
class="relative flex min-w-1/2 items-center justify-start gap-2 font-semibold dark:text-white text-blacktext text-left text-pretty max-sm:text-xs max-md:text-sm max-md:leading-4 hover:text-mint-300 hover:[text-shadow:1px_1px_11px_rgba(208,251,229,0.7)] transition-all before:absolute before:-top-5 before:left-0 before:text-sm before:font-light before:content-['Previous_Post']"
>
<svg width="15" height="15" viewBox="0 0 15 15" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M6.85355 3.85355C7.04882 3.65829 7.04882 3.34171 6.85355 3.14645C6.65829 2.95118 6.34171 2.95118 6.14645 3.14645L2.14645 7.14645C1.95118 7.34171 1.95118 7.65829 2.14645 7.85355L6.14645 11.8536C6.34171 12.0488 6.65829 12.0488 6.85355 11.8536C7.04882 11.6583 7.04882 11.3417 6.85355 11.1464L3.20711 7.5L6.85355 3.85355ZM12.8536 3.85355C13.0488 3.65829 13.0488 3.34171 12.8536 3.14645C12.6583 2.95118 12.3417 2.95118 12.1464 3.14645L8.14645 7.14645C7.95118 7.34171 7.95118 7.65829 8.14645 7.85355L12.1464 11.8536C12.3417 12.0488 12.6583 12.0488 12.8536 11.8536C13.0488 11.6583 13.0488 11.3417 12.8536 11.1464L9.20711 7.5L12.8536 3.85355Z" fill="currentColor" fill-rule="evenodd" clip-rule="evenodd"></path></svg>
{prevPost.frontmatter.title}
</a>
)}
{nextPost && (
<a
href={nextPost.url}
style="width: -webkit-fill-available;"
class="relative flex min-w-1/2 items-center justify-end gap-2 font-semibold dark:text-white text-blacktext text-right text-pretty max-sm:text-xs max-md:text-sm max-md:leading-4 hover:text-mint-300 hover:[text-shadow:1px_1px_11px_rgba(208,251,229,0.7)] transition-all before:absolute before:-top-5 before:right-0 before:text-sm before:font-light before:content-['Next_Post']"
>
{nextPost.frontmatter.title}
<svg width="15" height="15" viewBox="0 0 15 15" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M2.14645 11.1464C1.95118 11.3417 1.95118 11.6583 2.14645 11.8536C2.34171 12.0488 2.65829 12.0488 2.85355 11.8536L6.85355 7.85355C7.04882 7.65829 7.04882 7.34171 6.85355 7.14645L2.85355 3.14645C2.65829 2.95118 2.34171 2.95118 2.14645 3.14645C1.95118 3.34171 1.95118 3.65829 2.14645 3.85355L5.79289 7.5L2.14645 11.1464ZM8.14645 11.1464C7.95118 11.3417 7.95118 11.6583 8.14645 11.8536C8.34171 12.0488 8.65829 12.0488 8.85355 11.8536L12.8536 7.85355C13.0488 7.65829 13.0488 7.34171 12.8536 7.14645L8.85355 3.14645C8.65829 2.95118 8.34171 2.95118 8.14645 3.14645C7.95118 3.34171 7.95118 3.65829 8.14645 3.85355L11.7929 7.5L8.14645 11.1464Z" fill="currentColor" fill-rule="evenodd" clip-rule="evenodd"></path></svg>
</a>
)}
</nav>

View File

@@ -1,40 +0,0 @@
---
import Heading from "../ui/Heading.astro";
import Button from "../ui/Button.astro";
import { AstroError } from "astro/errors";
import { getCollection} from "astro:content";
const [staticData] = await getCollection('staticData');
if (!staticData) {
throw new AstroError("JSON data not found");
}
---
<section>
<div
class="w-full border-b bg-linear-to-b from-mint-100 to-transparent dark:from-mint-800 dark:border-mint-950 border-mint-100"
>
<div class="mx-auto max-w-5xl px-8 py-24 max-sm:py-12">
<div class="flex items-center justify-between max-sm:flex-col max-sm:gap-8 max-sm:text-center">
<div class="max-w-lg">
<Heading
text={staticData.data.contactSectionSubtitle}
textGradient={staticData.data.contactSectionSubtitle}
level={2}
/>
</div>
<div
class="transition-all duration-500 group-hover:animate-jump group-hover:animate-duration-[300ms] group-hover:animate-ease-in-out group-hover:scale-105 hover:scale-125"
>
<Button
variant="big"
link={`mailto:${staticData.data.email}`}
text={staticData.data.contactSectionButtonText}
iconName={staticData.data.contactSectionButtonIcon}
/>
</div>
</div>
</div>
</div>
</section>

View File

@@ -1,39 +0,0 @@
---
import ExperienceItem from "./ExperienceItem.astro";
const EXPERIENCE = [
{
date: "2021 - Present",
title: "Software Development Coordinator",
company: "EFEELE.DEV",
description:
"I lead the planning, development, and implementation of software projects to optimize administrative processes and improve digital services. I manage and provide support for technology platforms, coordinating development teams to deliver efficient solutions.",
},
{
date: "2019 - 2020",
title: "Software Development Coordinator",
company: "EFEELE.DEV",
description:
"I lead the planning, development, and implementation of software projects to optimize administrative processes and improve digital services. I manage and provide support for technology platforms, coordinating development teams to deliver efficient solutions.",
},
];
---
<div class="relative max-md:mt-0 mt-8" aria-label="Professional experience">
<ol class="relative mt-10">
{
EXPERIENCE.map((experience, index) => (
<li class="">
<article role="article" aria-labelledby={`experience-title-${index}`}>
<div
class="flex flex-col gap-2 text-zinc-00 dark:text-zinc-300 md:col-span-3"
aria-describedby={`experience-title-${index}`}
>
<ExperienceItem {...experience} />
</div>
</article>
</li>
))
}
</ol>
</div>

View File

@@ -1,41 +0,0 @@
---
interface Props {
title: string;
company: string;
description: string;
link?: string;
date: string;
}
const { title, company, description, link, date } = Astro.props;
---
<div
class="relative mx-12 pb-12 grid md:grid-cols-5 md:gap-10 before:absolute before:left-[-35px] before:block before:h-full before:border-l-2 before:border-black/20 dark:before:border-white/15 before:content-['']"
>
<div class="pb-12 md:col-span-2">
<div class="sticky top-0">
<span
class="absolute -left-[42px] text-5xl text-mint-400 rounded-full drop-shadow-[0px_0px_8px_rgba(0,255,94,1)]"
>&bull;</span
>
<h3
class="text-xl font-bold text-mint-400"
>
{title}
</h3>
<h4 class="text-xl font-semibold text-zinc-600 dark:text-white">
{company}
</h4>
<time datetime={date} class="text-sm text-zinc-600/80 dark:text-white/80">
{date}
</time>
</div>
</div>
<div
class="flex flex-col gap-2 pb-4 text-zinc-00 dark:text-zinc-300 md:col-span-3"
>
{description}
</div>
</div>

View File

@@ -1,206 +0,0 @@
---
import Button from "../ui/Button.astro";
import Heading from "../ui/Heading.astro";
import Tools from "../portfolio/Tools.astro";
import { Icon } from "astro-icon/components";
import Hobbies from "../portfolio/Hobbies.astro";
import { AstroError } from "astro/errors";
import { getCollection} from "astro:content";
const [staticData] = await getCollection('staticData');
if (!staticData) {
throw new AstroError("JSON data not found");
}
---
<section
class="scroll-m-16 px-8 max-sm:px-4 py-8"
id="home"
aria-label="Professional profile and introduction"
>
<div
class="mx-auto mb-4 h-96 w-full max-w-7xl rounded-2xl bg-linear-to-r from-mint-300 dark:from-mint-600 to-mint-50 dark:to-mint-200/5 hover:to-mint-300/30 dark:hover:to-mint-600/30 p-[.2rem] max-md:h-auto"
>
<div
class="group relative z-0 flex h-full items-center justify-center gap-8 overflow-hidden rounded-2xl bg-linear-to-tr from-riptide-100 to-white p-4 transition-all hover:shadow-[0_10px_50px_rgba(13,188,130,0.2)] dark:bg-linear-to-r dark:from-mint-950 dark:to-zinc-950 dark:overflow-hidden max-md:w-full max-md:gap-3 max-lg:gap-2 max-sm:flex-col dark:before:bg-[radial-gradient(circle,rgba(13,188,130)_0,rgba(1,45,34)_100%)] before:bg-[radial-gradient(circle,rgba(95,255,202)_0,rgba(144,253,210)_100%)] before:absolute before:left-65 before:top-10 before:h-[40%] before:aspect-square before:rounded-full before:blur-3xl before:opacity-80 before:-z-10 before:transition hover:before:animate-pulse"
>
<div class="aspect-square h-4/5 max-md:size-32">
<div
class="group-hover:scale-105 relative z-10 flex w-full cursor-pointer items-center overflow-hidden rounded-full p-[2px] transition-all duration-500"
>
<div
class="absolute inset-0 h-full w-full rounded-fullfrom-transparent to-riptide-500 dark:from-transparent f dark:to-mint-300 animate-rotate-border bg-conic/[from_var(--border-angle)] "
>
</div>
<div class="relative z-20 flex w-full rounded-full bg-mint-900">
<div
class="w-full aspect-square rounded-full bg-center bg-cover"
style={`background-image: url(${staticData.data.profileImage})`}
aria-label={staticData.data.profileAlt}
>
<a
href={staticData.data.profileLink}
class="flex h-full w-full"
aria-label="View about me page"></a>
</div>
</div>
</div>
</div>
<div
class="flex h-full w-7/12 flex-col justify-center gap-4 p-4 max-md:w-full max-md:gap-2"
>
<span
class="relative inline-flex items-center text-xs font-semibold leading-0 dark:text-white text-blacktext max-md:font-medium max-sm:justify-center"
>
<span
class="before:mr-2 before:block before:h-1.5 before:w-1.5 before:rounded-full before:bg-green-400 before:shadow-[0px_0px_0px_3px_rgba(34,197,94,0.5)] before:animate-pulse before:content-['']"
></span>
Available for work
</span>
<h1
class="text-4xl font-black leading-none text-blacktext dark:text-white max-xl:text-3xl max-lg:text-2xl max-sm:text-center"
>
{staticData.data.profileName} 👋
</h1>
<p
class="mb-0 text-lg font-semibold leading-8 text-blacktext dark:text-gray-200 max-xl:text-base"
>
<span
class="bg-linear-to-r from-riptide-500 to-mint-500 bg-clip-text font-black text-transparent dark:from-riptide-300 dark:to-mint-200"
>{staticData.data.profileTitle}</span
> with <span
class="bg-linear-to-r from-riptide-500 to-mint-500 bg-clip-text font-black text-transparent dark:from-riptide-300 dark:to-mint-200"
>8 years of experience</span
>, passionate about development, technology, and coffee that sparks ideas. I love bringing digital projects to life. 🚀☕
</p>
<div class="flex gap-4 max-sm:flex-col max-sm:items-center">
<Button
link={"mailto:" + staticData.data.email}
text={staticData.data.contactSectionButtonText}
iconName={staticData.data.emailIconName}
/>
<Button
link={staticData.data.profileLink}
text="About Me"
iconName="person"
variant="dark"
/>
</div>
</div>
</div>
</div>
<div
class="mx-auto grid max-w-7xl grid-cols-2 grid-rows-4 max-sm:gap-3 gap-4 max-md:h-[80vh] max-sm:h-[900px] max-xl:h-[550px] xl:h-[700px] md:grid-cols-4 md:grid-rows-2"
>
<div
class="col-start-2 row-start-2 flex flex-col gap-3 rounded-2xl border border-emerald-50 bg-linear-to-r from-riptide-200 to-mint-200 p-8 dark:border-zinc-800 dark:border-2 dark:bg-zinc-800 dark:bg-gradient-radial dark:from-riptide-500 dark:to-mint-500 max-md:gap-0 max-xl:p-5 max-md:p-4 max-lg:gap-1 md:col-start-4"
>
<div class="flex flex-col-reverse items-start gap-4 max-md:gap-2">
<Heading text="Beyond the Code" level={3} />
</div>
<div class="overflow-y-auto">
<Hobbies />
</div>
</div>
<div
class="col-start-1 row-start-2 rounded-2xl bg-linear-to-r from-mint-300 dark:from-mint-600 to-mint-50 dark:to-mint-200/5 hover:to-mint-300/30 dark:hover:to-mint-600/30 p-[.2rem] transition-all ease-in duration-150 hover:scale-105 hover:shadow-[0_20px_50px_rgba(13,188,130,0.4)] z-40 md:col-start-3"
>
<div class="h-full w-full overflow-hidden rounded-2xl dark:bg-zinc-900">
<div
class="relative h-full w-full overflow-hidden rounded-2xl bg-linear-to-tr from-riptide-100 to-white dark:from-transparent dark:bg-linear-to-bl dark:to-transparent "
>
<a
target="_blank"
href={staticData.data.github}
aria-label="View this site's code repository on GitHub"
>
<div
class="relative flex h-full flex-col gap-8 p-8 dark:before:bg-[radial-gradient(circle,rgba(13,188,130)_0,rgba(1,45,34)_100%)] before:bg-[radial-gradient(circle,rgba(95,255,202)_0,rgba(144,253,210)_100%)] before:absolute before:left-30 before:bottom-30 before:h-[30%] before:aspect-square before:rounded-full before:blur-3xl before:opacity-90 before:transition before:z-0 max-xl:p-5 max-md:p-4 xl:before:bottom-10"
>
<div class="z-2">
<Heading text="Do you like this site's design?" level={3}/>
</div>
<Icon
class="absolute -bottom-10 left-30 size-50 text-mint-500/30 group-hover:animate-pulse ease-in-out max-sm:left-10 max-md:left-30 xl:size-56 xl:-bottom-5 xl:-right-24"
name="github"
aria-hidden="true"
/>
</div>
</a>
</div>
</div>
</div>
<div
class="col-span-2 col-start-1 row-start-1 rounded-2xl bg-linear-to-r from-mint-300 dark:from-mint-600 to-mint-50 dark:to-mint-200/5 hover:to-mint-300/30 dark:hover:to-mint-600/30 p-[.2rem] md:col-start-3"
>
<article
class="group relative z-0 flex h-full w-full flex-col overflow-hidden rounded-2xl bg-linear-to-tr from-riptide-100 to-mint-100 p-6 transition hover:shadow-[0_10px_50px_rgba(13,188,130,0.2)] dark:bg-linear-to-r dark:from-mint-900 dark:to-mint-950 dark:overflow-hidden max-md:p-4 gap-6 max-md:gap-3 max-lg:gap-4 dark:before:bg-[radial-gradient(circle,rgba(13,188,130)_0,rgba(1,45,34)_100%)] before:bg-[radial-gradient(circle,rgba(95,255,202)_0,rgba(144,253,210)_100%)] before:absolute before:left-30 before:-bottom-0 before:h-[80%] before:aspect-square before:rounded-full before:blur-3xl dark:before:opacity-80 before:opacity-30 before:-z-10 before:transition"
>
<div class="flex items-center gap-4 max-md:gap-2">
<Icon
class="text-3xl dark:text-white text-mint-500 max-md:text-2xl max-sm:text-sm"
name="dashboard"
aria-hidden="true"
/>
<Heading text="Tech" textGradient="Stack" level={3} />
</div>
<div class="overflow-y-auto">
<Tools />
</div>
</article>
</div>
<div
class="col-span-2 row-span-2 rounded-2xl bg-linear-to-r from-mint-300 dark:from-mint-600 to-mint-50 dark:to-mint-200/5 p-[.2rem] hover:to-mint-300/30 dark:hover:to-mint-600/30 md:col-start-1 md:row-start-1"
>
<article
class="group relative flex h-full flex-col justify-start overflow-hidden rounded-2xl bg-linear-to-br from-riptide-100 to-white dark:from-mint-950 dark:to-zinc-950 p-8 transition-all hover:shadow-[0_20px_50px_rgba(13,188,130,0.4)] max-md:p-6 dark:before:bg-[radial-gradient(circle,rgba(13,188,130)_0,rgba(1,45,34)_100%)] before:bg-[radial-gradient(circle,rgba(95,255,202)_0,rgba(144,253,210)_100%)] before:absolute before:left-1/2 before:bottom-30 before:h-[30%] before:aspect-square before:rounded-full before:blur-3xl before:opacity-70 before:transition before:-z-0 hover:before:animate-pulse xl:before:bottom-2/5"
>
<a
href="#projects"
class="absolute left-0 top-0 z-40 h-full w-full bg-transparent"
aria-label="View projects section"></a>
<div class="flex items-center gap-4 max-md:gap-2">
<Icon
class="text-3xl dark:text-white text-mint-500 max-md:text-2xl max-sm:text-xl"
name="code"
aria-hidden="true"
/>
<Heading text="Projects" level={3}/>
</div>
<p
class="z-2 my-6 text-lg font-semibold leading-6 dark:text-gray-200 text-blacktext max-xl:text-base max-w-[90%] max-md:max-w-[85%]"
>
I love <span
class="bg-linear-to-r from-riptide-500 to-mint-500 bg-clip-text font-black text-transparent dark:from-riptide-300 dark:to-mint-200"
>turning ideas into real projects.</span
>
<br /> Here I show you some of the <span
class="bg-linear-to-r from-riptide-500 to-mint-500 bg-clip-text font-black text-transparent dark:from-riptide-300 dark:to-mint-200"
>developments</span
> I've worked on, applying technology, design, and lots of creativity.
<span
class="bg-linear-to-r from-riptide-500 to-mint-500 font-black bg-clip-text text-transparent dark:from-riptide-300 dark:to-mint-200"
>Check them out!</span
>
</p>
<img
class="relative left-0 z-0 mt-40 w-full object-cover transition-all ease-in-out duration-500 group-hover:rotate-2 group-hover:scale-185 max-xl:mt-28 max-lg:mt-10 max-sm:mt-0 max-md:scale-100 max-sm:scale-125 scale-180 max-md:group-hover:scale-105 before:bg-[radial-gradient(circle,rgba(13,188,130)_0,rgba(1,45,34)_100%)] before:absolute before:left-30 before:-bottom-0 before:h-[80%] before:aspect-square before:rounded-full before:blur-3xl before:opacity-80 before:-z-10 before:transition"
src={staticData.data.portfolioImage}
alt="View of two website interfaces with modern and dark design. The first screen shows the title 'Behind the Code' with a rocket and dark background, explaining the origin of a community software project. The second screen presents a platform for finding speakers, with an attractive design, expert photos, and a prominent search button."
loading="lazy"
width="480"
height="320"
/>
</article>
</div>
</div>
</section>

View File

@@ -1,9 +0,0 @@
---
const { tag } = Astro.props;
---
<span
class="px-4 py-1 rounded-full text-sm font-medium text-zinc-500 dark:text-neutral-400 hover:text-blacktext bg-riptide-50 dark:bg-zinc-800 hover:bg-mint-200 cursor-default transition-all ease-in-out duration-300"
>
{tag}
</span>

View File

@@ -1,37 +0,0 @@
---
interface Props {
variant?: 'default' | 'vertical';
}
const hobbies = [
"Writing",
"Camping",
"Coffee",
"Music",
"Movies",
"Board Games"
];
import Hobbie from "./Hobbie.astro";
const baseClasses = "max-w-7xl gap-3 py-4 max-md:py-3";
const variants = {
default: `${baseClasses} flex-wrap mx-auto max-md:gap-2 max-sm:gap-1 justify-start items-center flex flex-row`,
vertical: `${baseClasses} max-sm:gap-2 justify-start items-start flex flex-col`
} as const;
const { variant = "default" } = Astro.props as Props;
const classes = variants[variant];
---
<div id="tags" class={classes}>
{hobbies.map((hobby) => <Hobbie tag={hobby} />)}
</div>

View File

@@ -1,61 +0,0 @@
---
import Project from "./Project.astro";
const allPosts = await Astro.glob("../../pages/portfolio/projects/*.md");
// Sort by descending date (most recent first)
allPosts.sort(
(a, b) =>
new Date(b.frontmatter.pubDate).getTime() -
new Date(a.frontmatter.pubDate).getTime(),
);
---
<section class="relative pt-8 pb-32 max-2xl:px-8 max-md:pt-4">
<div class="mx-auto max-w-7xl py-8">
<slot />
</div>
<div
id="containerProjects"
class="mx-auto max-w-7xl grid grid-cols-3 max-lg:grid-cols-2 max-md:grid-cols-1 gap-5 p-2 py-4 max-h-[150vh] overflow-hidden transition-[max-height] duration-500 ease-in-out"
>
{
allPosts.map((post) => (
<Project
url={post.url}
title={post.frontmatter.title}
description={post.frontmatter.description}
date={post.frontmatter.pubDate}
languages={post.frontmatter.languages}
image={post.frontmatter.image}
/>
))
}
</div>
<div
id="moreProjects"
class="absolute bottom-0 left-0 w-full flex justify-center text-center bg-linear-to-t from-[#FBFEFD] dark:from-[#0e0e10] from-55% to-transparent to-100% pb-30 pt-52"
>
<button
class="absolute font-bold cursor-pointer text-mint-400 dark:text-mint-100 hover:text-mint-500 dark:hover:text-mint-300 transition-all"
>
View More Projects...
</button>
</div>
</section>
<script>
document.querySelector("#moreProjects")?.addEventListener("click", () => {
const contenedor = document.querySelector("#containerProjects") as HTMLElement;
const moreprojects = document.querySelector("#moreProjects");
if (contenedor && moreprojects) {
// Use a very large max height to show all content
contenedor.style.maxHeight = "15000px";
// Hide the view more button
setTimeout(() => {
moreprojects.classList.add("hidden");
}, 5000);
}
});
</script>

View File

@@ -1,32 +0,0 @@
---
const { title, url, image, languages, description, size = "xs" } = Astro.props;
import Capsule from "../ui/Capsule.astro";
---
<a href={url} class="w-full h-full hover:scale-105 transition-all duration-300 ease-in-out rounded-3xl bg-linear-to-br from-mint-50/50 to-mint-300/10 dark:from-zinc-800 dark:to-mint-800/10">
<article class="group h-full gap-4 p-4 max-md:p-6 flex flex-col justify-start items-center cursor-pointer transition-all duration-200 ease-in-out rounded-3xl bg-transparent backdrop-blur-lg hover:backdrop-blur-none overflow-hidden hover:shadow-[0_10px_10px_rgba(0,0,0,0.05)] dark:border-0 dark:hover:shadow-[0_10px_10px_rgba(13,188,130,0.05)] before:absolute before:size-36 before:aspect-square before:rounded-full before:blur-3xl dark:before:blur-3xl dark:before:opacity-20 before:opacity-5 before:transition before:-z-1 before:left-7/12 before:bottom-50 xl:before:-bottom-0 before:bg-[radial-gradient(circle,rgba(71,255,194)_0,rgba(0,255,191)_100%)] dark:before:bg-[radial-gradient(circle,rgba(7,255,173)_0,rgba(1,45,34)_100%)] after:absolute after:size-40 after:aspect-square after:rounded-full dark:after:blur-2xl after:blur-3xl dark:after:opacity-20 after:opacity-10 after:transition after:-z-1 after:-left-10 after:top-1/2 after:bg-[radial-gradient(circle,rgba(0,255,217)_0,rgba(121,249,255,65%)_70%)] dark:after:bg-[radial-gradient(circle,rgba(0,255,218)_0,rgba(2,181,190,65%)_70%)]">
<div class="overflow-hidden rounded-xl">
<img class="h-auto rounded-xl transition-all duration-300 ease-in-out group-hover:scale-105" src={image.url} alt={image.alt} />
</div>
<div class="flex flex-col p-2">
<div class="flex flex-col gap-3 w-full">
<h2 class="text-3xl font-bold text-blacktext dark:text-mint-50">
{title}
</h2>
<div class="flex flex-wrap gap-3">
{
languages.map((language: string) => (
<Capsule size={size} linkEnabled={false} lang={language} />
))
}
</div>
<p class="text-lg max-xl:text-base w-full max-md:max-w-[85%] my-2 leading-6 font-medium text-blacktext dark:text-gray-200">
{description}
</p>
</div>
</div>
</article>
</a>

View File

@@ -1,54 +0,0 @@
---
const allTools = [
"html",
"javascript",
"ts",
"angular",
"astro",
"node",
"css",
"tailwind",
"sass",
"bootstrap",
"mongo",
"firebase",
"mysql",
"cloudflare",
"figma",
"vercel",
"netlify",
"git",
"markdown",
"php",
"wordpress",
];
import Capsule from "../ui/Capsule.astro";
type ToolVariant = "default" | "center";
// Base classes that are common to all variants
const baseClasses = "flex flex-wrap gap-4 max-lg:gap-1 grid-auto-efe";
// Variant-specific classes
const variantClasses: Record<ToolVariant, string> = {
default: "cursor-default",
center: "justify-center cursor-default",
};
const { variant = "default", linkEnabled = false, size = "md" } = Astro.props;
// Combine base classes with variant-specific classes
const classes = `${baseClasses} ${variantClasses[variant as ToolVariant]}`;
---
<div class={classes}>
{allTools.map((tool) => <Capsule lang={tool} linkEnabled={linkEnabled} size={size} />)}
</div>

View File

@@ -1,166 +0,0 @@
---
type ButtonVariant = "default" | "big" | "dark";
interface Props {
link: string;
text: string;
iconName?: string;
variant?: ButtonVariant;
ariaLabel?: string;
disabled?: boolean;
isLoading?: boolean;
isExternal?: boolean;
isActive?: boolean;
class?: string;
}
const {
link,
text,
iconName,
variant = "default",
ariaLabel,
disabled = false,
isLoading = false,
isExternal = false,
isActive = false,
class: className = ""
} = Astro.props as Props;
import { Icon } from "astro-icon/components";
// Common base classes for all buttons
const baseClasses = `
z-2
text-center
cursor-pointer
leading-none
hover:scale-110
w-fit
font-medium
flex
gap-2
transition-all
ease-in-out
justify-center
items-center
rounded-full
disabled:opacity-50
disabled:cursor-not-allowed
disabled:hover:scale-100
disabled:hover:bg-none
disabled:hover:shadow-none
aria-disabled:opacity-50
aria-disabled:cursor-not-allowed
aria-disabled:hover:scale-100
aria-disabled:hover:bg-none
aria-disabled:hover:shadow-none
`;
// Specific classes for each variant
const variantClasses = {
default: `
text-blacktext/90
dark:text-mint-50
dark:hover:text-white
px-6
py-4
max-xl:px-5
max-sm:py-2
max-sm:px-3
text-lg
max-xl:text-base
max-sm:text-sm
hover:bg-linear-to-l
bg-linear-to-r
from-riptide-300
to-mint-300
dark:from-riptide-500
dark:to-mint-500
`,
big: `
font-normal
gap-3
max-md:gap-1
text-blacktext
dark:text-mint-50
dark:hover:text-white
px-8
max-sm:py-3
py-5
max-xl:px-6
max-sm:px-3
text-2xl
max-xl:text-xl
max-sm:text-lg
hover:bg-linear-to-l
bg-linear-to-r
from-riptide-200
to-mint-200
dark:from-riptide-500
dark:to-mint-500
`,
dark: `
group
dark:text-mint-50
text-blacktext
dark:hover:text-white
px-6
py-4
max-xl:px-5
max-sm:py-2
max-sm:px-3
text-lg
max-xl:text-base
max-sm:text-sm
dark:bg-zinc-800
bg-white
dark:hover:bg-mint-500
`,
};
// Icon classes for each variant
const iconClasses = {
default: "size-5",
big: "size-5",
dark: "size-5 dark:text-mint-300 text-blacktext group-hover:text-blacktext dark:group-hover:text-white transition-colors",
};
// Combine base classes with variant-specific classes
const buttonClasses = `${baseClasses} ${variantClasses[variant]}`;
// Generate aria-label if not provided
const buttonAriaLabel = ariaLabel || (iconName ? `${text} ${iconName}` : text);
// Determine if it's an external link
const isExternalLink = isExternal || link.startsWith('http');
// Additional attributes for external links
const externalAttributes = isExternalLink ? {
target: '_blank',
rel: 'noopener noreferrer'
} : {};
// Loading state
const loadingText = isLoading ? 'Loading...' : text;
const loadingAriaLabel = isLoading ? `${buttonAriaLabel} - Loading` : buttonAriaLabel;
---
<div
class="w-fit h-fit from-transparent via-riptide-300 to-transparent dark:from-transparent dark:via-mint-500 dark:to-transparent from-40% to-60% animate-rotate-border bg-conic/[from_var(--border-angle)] p-px hover:shadow-lg
hover:shadow-mint-500/30 rounded-full"
>
<a
class:list={[buttonClasses, className]}
href={disabled ? '#' : link}
aria-label={loadingAriaLabel}
role="button"
aria-disabled={disabled}
aria-busy={isLoading}
aria-pressed={isActive}
{...externalAttributes}
>
{iconName && <Icon name={iconName} class={iconClasses[variant]} aria-hidden="true" />}
{isLoading && <Icon name="mdi:loading" class="animate-spin" aria-hidden="true" />}
{loadingText}
</a>
</div>

View File

@@ -1,87 +0,0 @@
---
import { Icon } from "astro-icon/components";
import { getLanguage } from "../../utils/languages";
interface Props {
lang: string;
size?: "xs" | "md";
linkEnabled?: boolean;
}
const { size = "md", lang, linkEnabled = true } = Astro.props as Props;
const baseClasses = {
container: [
"flex items-center w-fit",
"pl-2 pr-2 py-0.5 gap-1",
"text-sm font-semibold leading-3",
"bg-white shadow rounded-full",
"transition-all duration-300 ease-in-out hover:bg-zinc-800 hover:text-white",
"max-sm:pl-1 max-sm:pr-1.5 max-sm:text-xs max-sm:gap-0.5",
].join(" "),
iconContainer: [
"flex items-center justify-center",
"aspect-square",
"bg-black rounded-full p-1",
].join(" "),
};
const sizeClasses = {
xs: "size-5",
md: "size-7",
};
const selectedLanguage = getLanguage(lang);
const getContainerClasses = () => {
const textSize = selectedLanguage.name.length > 10 ? "text-sm" : "text-base";
return `${baseClasses.container} ${textSize}`;
};
const getIconContainerClasses = () => {
return `${baseClasses.iconContainer} ${sizeClasses[size]} max-lg:size-6 max-sm:size-5 ${
selectedLanguage.className ? selectedLanguage.className : ""
}`;
};
---
{
linkEnabled ? (
<a
class="cursor-pointer"
href={`/blog/techs/${lang}`}
aria-label={`View articles about ${selectedLanguage.name}`}
role="link"
>
<span
class={getContainerClasses()}
role="presentation"
aria-hidden="true"
>
<div
class={getIconContainerClasses()}
role="img"
aria-label={`${selectedLanguage.name} icon`}
>
<Icon class="w-full!" name={selectedLanguage.iconName} />
</div>
{selectedLanguage.name}
</span>
</a>
) : (
<span
class={`${getContainerClasses()} cursor-default`}
role="presentation"
aria-hidden="true"
>
<div
class={getIconContainerClasses()}
role="img"
aria-label={`${selectedLanguage.name} icon`}
>
<Icon class="w-full!" name={selectedLanguage.iconName} />
</div>
{selectedLanguage.name}
</span>
)
}

View File

@@ -1,35 +0,0 @@
---
interface Props {
text?: string;
textGradient?: string;
level?: 1 | 2 | 3;
className?: string;
}
const { text = "", textGradient = "", level = 1, className = "" } = Astro.props;
const Tag = `h${level}`;
---
<Tag class:list={[
"font-extrabold text-4xl max-xl:text-3xl",
level === 2 && "max-md:text-3xl ",
level === 3 && "max-md:text-xl ",
"dark:text-white text-blacktext",
className
]}>
{text && (
<>
{text}
{textGradient && " "}
</>
)}
{textGradient && (
<b
class:list={[
"bg-linear-to-r from-riptide-500 to-mint-400 dark:from-riptide-500 dark:to-mint-500 text-transparent bg-clip-text",
level === 1
]}
>{textGradient}</b>
)}
</Tag>

View File

@@ -1,10 +0,0 @@
---
const {class: className} = Astro.props;
import { Icon } from "astro-icon/components";
---
<div
class={`flex justify-start items-center gap-2 text-blacktext dark:text-mint-50 ${className || ''}`}
>
<span class="font-medium tracking-wider">Read more </span>
<Icon name="arrow-left" class="size-4 rotate-180" />
</div>

View File

@@ -1,41 +0,0 @@
---
import { Icon } from "astro-icon/components";
const { tweetText, currentUrl } = Astro.props;
const shareLinks = [
{
name: "Twitter",
icon: "twitter",
href: `https://twitter.com/intent/tweet?text=${tweetText}&url=${currentUrl}`,
},
{
name: "Facebook",
icon: "facebook",
href: `https://www.facebook.com/sharer/sharer.php?u=${currentUrl}`,
},
{
name: "WhatsApp",
icon: "whatsapp",
href: `https://api.whatsapp.com/send?text=${encodeURIComponent(`${currentUrl}`)}`,
},
];
---
<div class="flex items-center gap-5 text-lg" role="group" aria-label="Share on social media">
<span class="text-base font-bold text-blacktext dark:text-white">Share </span>
{
shareLinks.map((link) => (
<a
href={link.href}
class="bg-blacktext rounded-full p-2"
target="_blank"
rel="noopener noreferrer"
aria-label={`Share on ${link.name}`}
title={`Share on ${link.name}`}
>
<Icon name={link.icon} />
</a>
))
}
</div>

View File

@@ -1,26 +0,0 @@
---
import { Icon } from "astro-icon/components"
interface Props {
iconName: string;
link: string;
label?: string;
}
const { iconName, link, label = `Link to ${iconName}` } = Astro.props;
// Validate required props
if (!iconName || !link) {
throw new Error('Social component requires both iconName and link props');
}
---
<a
class="hover:text-mint-300 hover:scale-150 transition-all"
target="_blank"
href={link}
rel="noopener noreferrer"
aria-label={label}
>
<Icon name={iconName} aria-hidden="true" />
</a>

View File

@@ -1,10 +0,0 @@
---
const { tag, forceDark = false } = Astro.props;
---
<a
href={`/blog/tags/${tag}`}
class={`max-md:text-xs text-sm font-medium ${forceDark ? 'text-neutral-400 bg-zinc-800' : 'text-zinc-500 dark:text-neutral-400 hover:text-blacktext'} transition-all ease-in-out duration-300 px-4 py-1 max-md:px-3 rounded-full ${forceDark ? 'bg-zinc-800' : 'bg-mint-950/5 dark:bg-zinc-800 hover:bg-mint-200'}`}
>
{tag}
</a>

View File

@@ -1,75 +0,0 @@
---
import { Icon } from "astro-icon/components";
---
<button id="themeToggle" class="hover:cursor-pointer hover:text-mint-400 transition-all">
<Icon name="sun" class="sun"/>
<Icon name="moon" class="moon"/>
</button>
<style>
#themeToggle {
border: 0;
background: none;
}
.sun {
display: block;
}
.moon {
display: none;
}
:global(.dark) .sun {
display: none;
}
:global(.dark) .moon {
display: block;
}
</style>
<script is:inline>
// Execute immediately before the page loads
(function() {
const theme = (() => {
if (typeof localStorage !== "undefined" && localStorage.getItem("theme")) {
return localStorage.getItem("theme");
}
if (window.matchMedia("(prefers-color-scheme: dark)").matches) {
return "dark";
}
return "light";
})();
if (theme === "light") {
document.documentElement.classList.remove("dark");
} else {
document.documentElement.classList.add("dark");
}
window.localStorage.setItem("theme", theme);
})();
// Listen for changes in system preferences
window.matchMedia("(prefers-color-scheme: dark)").addEventListener("change", (e) => {
if (!localStorage.getItem("theme")) {
if (e.matches) {
document.documentElement.classList.add("dark");
} else {
document.documentElement.classList.remove("dark");
}
}
});
const handleToggleClick = () => {
const element = document.documentElement;
element.classList.toggle("dark");
const isDark = element.classList.contains("dark");
localStorage.setItem("theme", isDark ? "dark" : "light");
};
document
.getElementById("themeToggle")
.addEventListener("click", handleToggleClick);
</script>

View File

@@ -0,0 +1,56 @@
import * as React from "react";
import { Slot } from "@radix-ui/react-slot";
import { cva, type VariantProps } from "class-variance-authority";
import { cn } from "@/lib/utils";
const buttonVariants = cva(
"inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50",
{
variants: {
variant: {
default:
"bg-primary text-primary-foreground shadow hover:bg-primary/90",
destructive:
"bg-destructive text-destructive-foreground shadow-sm hover:bg-destructive/90",
outline:
"border border-input bg-background shadow-sm hover:bg-accent hover:text-accent-foreground",
secondary:
"bg-secondary text-secondary-foreground shadow-sm hover:bg-secondary/80",
ghost: "hover:bg-accent hover:text-accent-foreground",
link: "text-primary underline-offset-4 hover:underline",
},
size: {
default: "h-9 px-4 py-2",
sm: "h-8 rounded-md px-3 text-xs",
lg: "h-10 rounded-md px-8",
icon: "h-9 w-9",
},
},
defaultVariants: {
variant: "default",
size: "default",
},
}
);
export interface ButtonProps
extends React.ButtonHTMLAttributes<HTMLButtonElement>,
VariantProps<typeof buttonVariants> {
asChild?: boolean;
}
const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
({ className, variant, size, asChild = false, ...props }, ref) => {
const Comp = asChild ? Slot : "button";
return (
<Comp
className={cn(buttonVariants({ variant, size, className }))}
ref={ref}
{...props}
/>
);
}
);
Button.displayName = "Button";
export { Button, buttonVariants };

View File

@@ -0,0 +1,82 @@
import * as React from "react";
import { cn } from "@/lib/utils";
const Card = React.forwardRef<
HTMLDivElement,
React.HTMLAttributes<HTMLDivElement>
>(({ className, ...props }, ref) => (
<div
ref={ref}
className={cn(
"rounded-lg border bg-card text-card-foreground shadow-sm",
className
)}
{...props}
/>
));
Card.displayName = "Card";
const CardHeader = React.forwardRef<
HTMLDivElement,
React.HTMLAttributes<HTMLDivElement>
>(({ className, ...props }, ref) => (
<div
ref={ref}
className={cn("flex flex-col space-y-1.5 p-6", className)}
{...props}
/>
));
CardHeader.displayName = "CardHeader";
const CardTitle = React.forwardRef<
HTMLParagraphElement,
React.HTMLAttributes<HTMLHeadingElement>
>(({ className, ...props }, ref) => (
<h3
ref={ref}
className={cn("text-lg font-medium leading-none tracking-tight", className)}
{...props}
/>
));
CardTitle.displayName = "CardTitle";
const CardDescription = React.forwardRef<
HTMLParagraphElement,
React.HTMLAttributes<HTMLParagraphElement>
>(({ className, ...props }, ref) => (
<p
ref={ref}
className={cn("text-sm text-muted-foreground", className)}
{...props}
/>
));
CardDescription.displayName = "CardDescription";
const CardContent = React.forwardRef<
HTMLDivElement,
React.HTMLAttributes<HTMLDivElement>
>(({ className, ...props }, ref) => (
<div ref={ref} className={cn("p-6 pt-0", className)} {...props} />
));
CardContent.displayName = "CardContent";
const CardFooter = React.forwardRef<
HTMLDivElement,
React.HTMLAttributes<HTMLDivElement>
>(({ className, ...props }, ref) => (
<div
ref={ref}
className={cn("flex items-center p-6 pt-0", className)}
{...props}
/>
));
CardFooter.displayName = "CardFooter";
export {
Card,
CardHeader,
CardFooter,
CardTitle,
CardDescription,
CardContent,
};

View File

@@ -0,0 +1,37 @@
import * as React from "react";
import { cn } from "@/lib/utils";
import { motion } from "framer-motion";
import type { HTMLMotionProps } from "framer-motion";
interface GlassCardProps extends HTMLMotionProps<"div"> {
hoverEffect?: boolean;
}
const GlassCard = React.forwardRef<HTMLDivElement, GlassCardProps>(
({ className, hoverEffect = true, ...props }, ref) => {
return (
<motion.div
ref={ref}
className={cn(
"rounded-lg border border-border/50 bg-background/80 backdrop-blur-md backdrop-filter shadow-sm dark:bg-card/30 dark:backdrop-blur-md",
hoverEffect &&
"hover:shadow-md transition-all duration-300 ease-in-out",
className
)}
whileHover={
hoverEffect
? {
y: -5,
transition: { duration: 0.2 },
}
: undefined
}
{...props}
/>
);
}
);
GlassCard.displayName = "GlassCard";
export { GlassCard };

View File

@@ -0,0 +1,36 @@
import { Moon, Sun } from "lucide-react";
import { Button } from "./button";
import { useEffect, useState } from "react";
export default function ThemeToggle() {
const [theme, setTheme] = useState<"light" | "dark">("light");
useEffect(() => {
const isDark = document.documentElement.classList.contains("dark");
setTheme(isDark ? "dark" : "light");
}, []);
const toggleTheme = () => {
const isDark = document.documentElement.classList.contains("dark");
const newTheme = isDark ? "light" : "dark";
document.documentElement.classList.toggle("dark");
setTheme(newTheme);
};
return (
<Button
variant="ghost"
size="icon"
onClick={toggleTheme}
className="rounded-full cursor-pointer"
>
{theme === "light" ? (
<Moon className="h-5 w-5" />
) : (
<Sun className="h-5 w-5" />
)}
<span className="sr-only">Toggle theme</span>
</Button>
);
}

View File

@@ -1,36 +0,0 @@
// src/content/config.ts
import { defineCollection, z } from 'astro:content';
const jsonDataCollection = defineCollection({
type: 'data',
schema: z.object({
//Define JSON-file structure
profileImage: z.string(),
profileAlt: z.string(),
profileLink: z.string(),
profileTitle: z.string(),
profileName: z.string(),
github: z.string().url(),
githubText: z.string(),
portfolioImage: z.string(),
email: z.string().email(),
linkedin: z.string().url(),
instagram: z.string().url(),
youtube: z.string().url(),
alias: z.string(),
contactSectionTitle: z.string(),
contactSectionSubtitle: z.string(),
contactSectionButtonText: z.string(),
contactSectionButtonIcon: z.string(),
techsTitle: z.string(),
instagramIconName: z.string(),
youtubeIconName: z.string(),
githubIconName: z.string(),
linkedinIconName: z.string(),
emailIconName: z.string()
}),
});
export const collections = {
staticData: jsonDataCollection,
};

View File

@@ -1,25 +0,0 @@
{
"profileImage": "/images/efeeleprofile.webp",
"profileAlt": "Photo of Fernando Aldair López Ponce (EFEELE) for the blog",
"profileLink": "/about-me",
"profileTitle": "FrontEnd Developer",
"profileName": "Fernando López",
"github": "https://github.com/EFEELE/NeonMint",
"githubText": "Do you like this blog's design?",
"portfolioImage": "/images/portfolio.webp",
"email": "hello@efeele.dev",
"linkedin": "https://www.linkedin.com/in/efeele/",
"instagram": "https://www.instagram.com/efeele.dev/",
"youtube": "https://www.youtube.com/@efeeledev",
"alias": "EFEELE",
"contactSectionTitle": "Ready to take your idea to the next level?",
"contactSectionSubtitle": "Let's work together.",
"contactSectionButtonText": "Contact Me",
"contactSectionButtonIcon": "paperplane",
"techsTitle": "TECHS",
"instagramIconName": "instagram",
"youtubeIconName": "youtube",
"githubIconName": "github",
"linkedinIconName": "linkedin",
"emailIconName": "envelope"
}

2
src/env.d.ts vendored
View File

@@ -1,2 +0,0 @@
/// <reference types="astro/client" />
/// <reference path="../.astro/types.d.ts" />

View File

@@ -1,15 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" fill="none" class="w-full h-full" viewBox="0 0 242 256">
<g clip-path="url(#a)">
<mask id="b" width="242" height="256" x="0" y="0" maskUnits="userSpaceOnUse">
<path fill="#fff" d="M0 0h242v256H0z"/>
</mask>
<g mask="url(#b)">
<path fill="#C80D9D" d="m241 43-9 136L149 0l92 43Zm-58 176-62 36-63-36 12-31h101l12 31ZM121 68l32 80H88l33-80ZM9 179 0 43 92 0 9 179Z"/>
</g>
</g>
<defs>
<clipPath id="a">
<path fill="#fff" d="M0 0h242v256H0z"/>
</clipPath>
</defs>
</svg>

Before

Width:  |  Height:  |  Size: 555 B

View File

@@ -1 +0,0 @@
<svg width="15" height="15" viewBox="0 0 15 15" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M6.85355 3.14645C7.04882 3.34171 7.04882 3.65829 6.85355 3.85355L3.70711 7H12.5C12.7761 7 13 7.22386 13 7.5C13 7.77614 12.7761 8 12.5 8H3.70711L6.85355 11.1464C7.04882 11.3417 7.04882 11.6583 6.85355 11.8536C6.65829 12.0488 6.34171 12.0488 6.14645 11.8536L2.14645 7.85355C1.95118 7.65829 1.95118 7.34171 2.14645 7.14645L6.14645 3.14645C6.34171 2.95118 6.65829 2.95118 6.85355 3.14645Z" fill="currentColor" fill-rule="evenodd" clip-rule="evenodd"></path></svg>

Before

Width:  |  Height:  |  Size: 563 B

View File

@@ -1,13 +0,0 @@
<svg
class="w-full"
viewBox="0 0 256 366"
xmlns="http://www.w3.org/2000/svg"
preserveAspectRatio="xMidYMid"
><path
fill="#fff"
d="M182.022 9.147c2.982 3.702 4.502 8.697 7.543 18.687L256 246.074a276.467 276.467 0 0 0-79.426-26.891L133.318 73.008a5.63 5.63 0 0 0-10.802.017L79.784 219.11A276.453 276.453 0 0 0 0 246.04L66.76 27.783c3.051-9.972 4.577-14.959 7.559-18.654a24.541 24.541 0 0 1 9.946-7.358C88.67 0 93.885 0 104.314 0h47.683c10.443 0 15.664 0 20.074 1.774a24.545 24.545 0 0 1 9.95 7.373Z"
></path><path
fill="#FF5D01"
d="M189.972 256.46c-10.952 9.364-32.812 15.751-57.992 15.751-30.904 0-56.807-9.621-63.68-22.56-2.458 7.415-3.009 15.903-3.009 21.324 0 0-1.619 26.623 16.898 45.14 0-9.615 7.795-17.41 17.41-17.41 16.48 0 16.46 14.378 16.446 26.043l-.001 1.041c0 17.705 10.82 32.883 26.21 39.28a35.685 35.685 0 0 1-3.588-15.647c0-16.886 9.913-23.173 21.435-30.48 9.167-5.814 19.353-12.274 26.372-25.232a47.588 47.588 0 0 0 5.742-22.735c0-5.06-.786-9.938-2.243-14.516Z"
></path></svg
>

Before

Width:  |  Height:  |  Size: 1.3 KiB

View File

@@ -1 +0,0 @@
<svg width="15" height="15" viewBox="0 0 15 15" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M1.5 3C1.22386 3 1 3.22386 1 3.5C1 3.77614 1.22386 4 1.5 4H13.5C13.7761 4 14 3.77614 14 3.5C14 3.22386 13.7761 3 13.5 3H1.5ZM1 7.5C1 7.22386 1.22386 7 1.5 7H13.5C13.7761 7 14 7.22386 14 7.5C14 7.77614 13.7761 8 13.5 8H1.5C1.22386 8 1 7.77614 1 7.5ZM1 11.5C1 11.2239 1.22386 11 1.5 11H13.5C13.7761 11 14 11.2239 14 11.5C14 11.7761 13.7761 12 13.5 12H1.5C1.22386 12 1 11.7761 1 11.5Z" fill="currentColor" fill-rule="evenodd" clip-rule="evenodd"></path></svg>

Before

Width:  |  Height:  |  Size: 560 B

View File

@@ -1,3 +0,0 @@
<svg width="182" height="218" viewBox="0 0 182 218" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M179.304 2.68965C177.498 0.887307 175.358 0 172.913 0H9.08607C6.61311 0 4.50136 0.887307 2.69526 2.68965C0.889156 4.49199 0 6.62707 0 9.06716V118.067C0 126.192 1.58381 134.26 4.75144 142.274C7.91906 150.26 11.8647 157.358 16.5606 163.569C21.2564 169.753 26.8414 175.798 33.3434 181.676C39.8454 187.554 45.8472 192.407 51.3211 196.289C56.8227 200.171 62.5467 203.831 68.5207 207.297C74.4947 210.763 78.746 213.092 81.2467 214.312C83.7475 215.532 85.7759 216.503 87.2763 217.14C88.4156 217.695 89.6382 218 90.9719 218C92.3056 218 93.5282 217.723 94.6675 217.14C96.1957 216.475 98.1963 215.532 100.725 214.312C103.226 213.092 107.477 210.735 113.451 207.297C119.425 203.831 125.149 200.171 130.651 196.289C136.152 192.407 142.154 187.527 148.656 181.676C155.158 175.798 160.743 169.78 165.439 163.569C170.135 157.358 174.053 150.287 177.248 142.274C180.416 134.288 181.999 126.219 181.999 118.067V9.09489C182.027 6.62707 181.11 4.49199 179.304 2.68965ZM158.187 119.093C158.187 158.551 90.9997 192.545 90.9997 192.545V23.3472H158.187C158.187 23.3472 158.187 79.6357 158.187 119.093Z" fill="#175DDC"/>
</svg>

Before

Width:  |  Height:  |  Size: 1.2 KiB

View File

@@ -1 +0,0 @@
<svg viewBox="0 0 256 204" xmlns="http://www.w3.org/2000/svg" width="256" height="204" preserveAspectRatio="xMidYMid"><path fill="#7E13F8" d="M53.172 0C38.565 0 27.756 12.785 28.24 26.65c.465 13.32-.139 30.573-4.482 44.642C19.402 85.402 12.034 94.34 0 95.488v12.956c12.034 1.148 19.402 10.086 23.758 24.197 4.343 14.069 4.947 31.32 4.482 44.641-.484 13.863 10.325 26.65 24.934 26.65h149.673c14.608 0 25.414-12.785 24.93-26.65-.464-13.32.139-30.572 4.482-44.641 4.359-14.11 11.707-23.05 23.741-24.197V95.488c-12.034-1.148-19.382-10.086-23.74-24.196-4.344-14.067-4.947-31.321-4.483-44.642C228.261 12.787 217.455 0 202.847 0H53.17h.002ZM173.56 125.533c0 19.092-14.24 30.67-37.872 30.67h-40.23a4.339 4.339 0 0 1-4.338-4.339V52.068a4.339 4.339 0 0 1 4.339-4.34h39.999c19.705 0 32.637 10.675 32.637 27.063 0 11.503-8.7 21.801-19.783 23.604v.601c15.089 1.655 25.248 12.104 25.248 26.537Zm-42.26-64.05h-22.937v32.4h19.32c14.934 0 23.17-6.014 23.17-16.764 0-10.073-7.082-15.636-19.552-15.636Zm-22.937 45.256v35.705h23.782c15.548 0 23.786-6.239 23.786-17.965 0-11.728-8.467-17.742-24.786-17.742h-22.782v.002Z"/></svg>

Before

Width:  |  Height:  |  Size: 1.1 KiB

View File

@@ -1 +0,0 @@
<svg width="15" height="15" viewBox="0 0 15 15" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M5 1C5 0.447715 5.44772 0 6 0H9C9.55228 0 10 0.447715 10 1V2H14C14.5523 2 15 2.44772 15 3V6C15 6.8888 14.6131 7.68734 14 8.23608V11.5C14 12.3284 13.3284 13 12.5 13H2.5C1.67157 13 1 12.3284 1 11.5V8.2359C0.38697 7.68721 0 6.88883 0 6V3C0 2.44772 0.447716 2 1 2H5V1ZM9 1V2H6V1H9ZM1 3H5H5.5H9.5H10H14V6C14 6.654 13.6866 7.23467 13.1997 7.6004C12.8655 7.85144 12.4508 8 12 8H8V7.5C8 7.22386 7.77614 7 7.5 7C7.22386 7 7 7.22386 7 7.5V8H3C2.5493 8 2.1346 7.85133 1.80029 7.60022C1.31335 7.23446 1 6.65396 1 6V3ZM7 9H3C2.64961 9 2.31292 8.93972 2 8.82905V11.5C2 11.7761 2.22386 12 2.5 12H12.5C12.7761 12 13 11.7761 13 11.5V8.82915C12.6871 8.93978 12.3504 9 12 9H8V9.5C8 9.77614 7.77614 10 7.5 10C7.22386 10 7 9.77614 7 9.5V9Z" fill="currentColor" fill-rule="evenodd" clip-rule="evenodd"></path></svg>

Before

Width:  |  Height:  |  Size: 897 B

View File

@@ -1 +0,0 @@
<svg viewBox="0 0 256 116" xmlns="http://www.w3.org/2000/svg" width="256" height="116" preserveAspectRatio="xMidYMid"><path fill="#FFF" d="m202.357 49.394-5.311-2.124C172.085 103.434 72.786 69.289 66.81 85.997c-.996 11.286 54.227 2.146 93.706 4.059 12.039.583 18.076 9.671 12.964 24.484l10.069.031c11.615-36.209 48.683-17.73 50.232-29.68-2.545-7.857-42.601 0-31.425-35.497Z"/><path fill="#F4811F" d="M176.332 108.348c1.593-5.31 1.062-10.622-1.593-13.809-2.656-3.187-6.374-5.31-11.154-5.842L71.17 87.634c-.531 0-1.062-.53-1.593-.53-.531-.532-.531-1.063 0-1.594.531-1.062 1.062-1.594 2.124-1.594l92.946-1.062c11.154-.53 22.839-9.56 27.087-20.182l5.312-13.809c0-.532.531-1.063 0-1.594C191.203 20.182 166.772 0 138.091 0 111.535 0 88.697 16.995 80.73 40.896c-5.311-3.718-11.684-5.843-19.12-5.31-12.747 1.061-22.838 11.683-24.432 24.43-.531 3.187 0 6.374.532 9.56C16.996 70.107 0 87.103 0 108.348c0 2.124 0 3.718.531 5.842 0 1.063 1.062 1.594 1.594 1.594h170.489c1.062 0 2.125-.53 2.125-1.594l1.593-5.842Z"/><path fill="#FAAD3F" d="M205.544 48.863h-2.656c-.531 0-1.062.53-1.593 1.062l-3.718 12.747c-1.593 5.31-1.062 10.623 1.594 13.809 2.655 3.187 6.373 5.31 11.153 5.843l19.652 1.062c.53 0 1.062.53 1.593.53.53.532.53 1.063 0 1.594-.531 1.063-1.062 1.594-2.125 1.594l-20.182 1.062c-11.154.53-22.838 9.56-27.087 20.182l-1.063 4.78c-.531.532 0 1.594 1.063 1.594h70.108c1.062 0 1.593-.531 1.593-1.593 1.062-4.25 2.124-9.03 2.124-13.81 0-27.618-22.838-50.456-50.456-50.456"/></svg>

Before

Width:  |  Height:  |  Size: 1.4 KiB

View File

@@ -1 +0,0 @@
<svg width="15" height="15" viewBox="0 0 15 15" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M9.96424 2.68571C10.0668 2.42931 9.94209 2.13833 9.6857 2.03577C9.4293 1.93322 9.13832 2.05792 9.03576 2.31432L5.03576 12.3143C4.9332 12.5707 5.05791 12.8617 5.3143 12.9642C5.5707 13.0668 5.86168 12.9421 5.96424 12.6857L9.96424 2.68571ZM3.85355 5.14646C4.04882 5.34172 4.04882 5.6583 3.85355 5.85356L2.20711 7.50001L3.85355 9.14646C4.04882 9.34172 4.04882 9.6583 3.85355 9.85356C3.65829 10.0488 3.34171 10.0488 3.14645 9.85356L1.14645 7.85356C0.951184 7.6583 0.951184 7.34172 1.14645 7.14646L3.14645 5.14646C3.34171 4.9512 3.65829 4.9512 3.85355 5.14646ZM11.1464 5.14646C11.3417 4.9512 11.6583 4.9512 11.8536 5.14646L13.8536 7.14646C14.0488 7.34172 14.0488 7.6583 13.8536 7.85356L11.8536 9.85356C11.6583 10.0488 11.3417 10.0488 11.1464 9.85356C10.9512 9.6583 10.9512 9.34172 11.1464 9.14646L12.7929 7.50001L11.1464 5.85356C10.9512 5.6583 10.9512 5.34172 11.1464 5.14646Z" fill="currentColor" fill-rule="evenodd" clip-rule="evenodd"></path></svg>

Before

Width:  |  Height:  |  Size: 1.0 KiB

View File

@@ -1 +0,0 @@
<svg height="1em" style="flex:none;line-height:1" viewBox="0 0 24 24" width="1em" xmlns="http://www.w3.org/2000/svg"><title>Cursor</title><path d="M11.925 24l10.425-6-10.425-6L1.5 18l10.425 6z" fill="url(#lobe-icons-cursorundefined-fill-0)"></path><path d="M22.35 18V6L11.925 0v12l10.425 6z" fill="url(#lobe-icons-cursorundefined-fill-1)"></path><path d="M11.925 0L1.5 6v12l10.425-6V0z" fill="url(#lobe-icons-cursorundefined-fill-2)"></path><path d="M22.35 6L11.925 24V12L22.35 6z" fill="#555"></path><path d="M22.35 6l-10.425 6L1.5 6h20.85z" fill="#ffff"></path><defs><linearGradient gradientUnits="userSpaceOnUse" id="lobe-icons-cursorundefined-fill-0" x1="11.925" x2="11.925" y1="12" y2="24"><stop offset=".16" stop-color="#ffff" stop-opacity=".39"></stop><stop offset=".658" stop-color="#ffff" stop-opacity=".8"></stop></linearGradient><linearGradient gradientUnits="userSpaceOnUse" id="lobe-icons-cursorundefined-fill-1" x1="22.35" x2="11.925" y1="6.037" y2="12.15"><stop offset=".182" stop-color="#ffff" stop-opacity=".31"></stop><stop offset=".715" stop-color="#ffff" stop-opacity="0"></stop></linearGradient><linearGradient gradientUnits="userSpaceOnUse" id="lobe-icons-cursorundefined-fill-2" x1="11.925" x2="1.5" y1="0" y2="18"><stop stop-color="#ffff" stop-opacity=".6"></stop><stop offset=".667" stop-color="#ffff" stop-opacity=".22"></stop></linearGradient></defs></svg>

Before

Width:  |  Height:  |  Size: 1.4 KiB

View File

@@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="1000" height="1000" aria-labelledby="css-logo-title css-logo-description" viewBox="0 0 1000 1000"><path fill="#639" d="M0 0h840a160 160 0 0 1 160 160v680a160 160 0 0 1-160 160H160A160 160 0 0 1 0 840V0Z"/><path fill="#fff" d="M816.54 919.9c-32.39 0-57.16-9.42-74.5-28.35-17.15-19.03-26.08-46.18-26.88-81.64h69.8c.4 31.36 11.42 47.08 33.08 47.08 11.04 0 18.86-3.5 23.37-10.42 4.41-6.9 6.72-17.93 6.72-33.05 0-12.02-3.01-22.04-8.83-29.95a73.2 73.2 0 0 0-29.48-21.14L783.95 750c-23.06-11.02-39.81-24.04-50.14-39.27-10.03-15.13-15.04-36.36-15.04-63.5 0-30.36 8.83-55 26.37-73.94 18.05-18.93 42.62-28.34 74-28.34 30.3 0 53.76 9.31 70.3 27.84 16.85 18.64 25.67 45.28 26.38 80.14h-67.19c.4-11.4-1.9-22.72-6.72-33.06-3.8-7.6-11.23-11.41-22.26-11.41-19.65 0-29.48 11.71-29.48 35.05 0 11.83 2.4 21.04 7.22 28.05A65.18 65.18 0 0 0 822.76 689l24.77 10.92c25.57 11.72 44.02 26.05 55.35 43.38 11.43 17.23 17.05 40.27 17.05 69.12 0 34.56-9.03 61.1-27.38 79.63-18.25 18.53-43.62 27.85-76 27.85Zm-225.42 0c-32.4 0-57.16-9.42-74.51-28.35-17.15-19.03-26.07-46.18-26.87-81.64h69.79c.4 31.36 11.43 47.08 33.1 47.08 11.02 0 18.84-3.5 23.25-10.42 4.52-6.9 6.72-17.93 6.72-33.05 0-12.02-2.9-22.04-8.72-29.95a73.2 73.2 0 0 0-29.48-21.14L558.53 750c-23.07-11.02-39.81-24.04-50.14-39.27-10.03-15.13-15.04-36.36-15.04-63.5 0-30.36 8.82-55 26.37-73.94 18.05-18.93 42.62-28.34 74-28.34 30.29 0 53.75 9.31 70.2 27.84 17.05 18.64 25.77 45.28 26.47 80.14h-67.18c.4-11.4-1.9-22.72-6.72-33.06-3.81-7.6-11.23-11.41-22.26-11.41-19.66 0-29.49 11.71-29.49 35.05 0 11.83 2.41 21.04 7.22 28.05A65.18 65.18 0 0 0 597.33 689l24.77 10.92c25.57 11.72 44.02 26.05 55.36 43.38 11.33 17.23 17.04 40.27 17.04 69.12 0 34.56-9.12 61.1-27.37 79.63-18.25 18.53-43.62 27.85-76.01 27.85Zm-234.75 0c-31.7 0-56.86-8.62-75.51-25.85-18.65-17.12-27.88-42.87-27.88-76.93V648.83c0-33.85 9.83-59.5 29.48-77.13 19.96-17.43 46.13-26.24 78.52-26.24 31.39 0 56.15 9.01 74.5 26.84 18.56 17.93 27.88 44.58 27.88 80.14v13.32h-73.9v-12.92c0-13.72-3.01-23.84-8.83-30.45a26.46 26.46 0 0 0-21.66-10.32c-12.03 0-20.55 4.1-25.37 12.42a79.04 79.04 0 0 0-6.72 36.66v146.26c0 30.55 10.74 46.08 32.1 46.38 10.02 0 17.54-3.61 22.76-10.82a51.74 51.74 0 0 0 7.72-30.46V801.6h73.9v11.42c0 23.74-4.61 43.57-13.94 59.4a88.8 88.8 0 0 1-38.2 35.66 121.46 121.46 0 0 1-54.85 11.82Z"/></svg>

Before

Width:  |  Height:  |  Size: 2.3 KiB

View File

@@ -1 +0,0 @@
<svg height="1em" style="flex:none;line-height:1" viewBox="0 0 24 24" width="1em" xmlns="http://www.w3.org/2000/svg"><title>Cursor</title><path d="M11.925 24l10.425-6-10.425-6L1.5 18l10.425 6z" fill="url(#lobe-icons-cursorundefined-fill-0)"></path><path d="M22.35 18V6L11.925 0v12l10.425 6z" fill="url(#lobe-icons-cursorundefined-fill-1)"></path><path d="M11.925 0L1.5 6v12l10.425-6V0z" fill="url(#lobe-icons-cursorundefined-fill-2)"></path><path d="M22.35 6L11.925 24V12L22.35 6z" fill="#555"></path><path d="M22.35 6l-10.425 6L1.5 6h20.85z" fill="#ffff"></path><defs><linearGradient gradientUnits="userSpaceOnUse" id="lobe-icons-cursorundefined-fill-0" x1="11.925" x2="11.925" y1="12" y2="24"><stop offset=".16" stop-color="#ffff" stop-opacity=".39"></stop><stop offset=".658" stop-color="#ffff" stop-opacity=".8"></stop></linearGradient><linearGradient gradientUnits="userSpaceOnUse" id="lobe-icons-cursorundefined-fill-1" x1="22.35" x2="11.925" y1="6.037" y2="12.15"><stop offset=".182" stop-color="#ffff" stop-opacity=".31"></stop><stop offset=".715" stop-color="#ffff" stop-opacity="0"></stop></linearGradient><linearGradient gradientUnits="userSpaceOnUse" id="lobe-icons-cursorundefined-fill-2" x1="11.925" x2="1.5" y1="0" y2="18"><stop stop-color="#ffff" stop-opacity=".6"></stop><stop offset=".667" stop-color="#ffff" stop-opacity=".22"></stop></linearGradient></defs></svg>

Before

Width:  |  Height:  |  Size: 1.4 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 4.9 KiB

View File

@@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" style="flex:none;line-height:1" viewBox="0 0 24 24"><path fill="#4D6BFE" d="M23.748 4.482c-.254-.124-.364.113-.512.234-.051.039-.094.09-.137.136-.372.397-.806.657-1.373.626-.829-.046-1.537.214-2.163.848-.133-.782-.575-1.248-1.247-1.548-.352-.156-.708-.311-.955-.65-.172-.241-.219-.51-.305-.774-.055-.16-.11-.323-.293-.35-.2-.031-.278.136-.356.276-.313.572-.434 1.202-.422 1.84.027 1.436.633 2.58 1.838 3.393.137.093.172.187.129.323-.082.28-.18.552-.266.833-.055.179-.137.217-.329.14a5.526 5.526 0 0 1-1.736-1.18c-.857-.828-1.631-1.742-2.597-2.458a11.365 11.365 0 0 0-.689-.471c-.985-.957.13-1.743.388-1.836.27-.098.093-.432-.779-.428-.872.004-1.67.295-2.687.684a3.055 3.055 0 0 1-.465.137 9.597 9.597 0 0 0-2.883-.102c-1.885.21-3.39 1.102-4.497 2.623C.082 8.606-.231 10.684.152 12.85c.403 2.284 1.569 4.175 3.36 5.653 1.858 1.533 3.997 2.284 6.438 2.14 1.482-.085 3.133-.284 4.994-1.86.47.234.962.327 1.78.397.63.059 1.236-.03 1.705-.128.735-.156.684-.837.419-.961-2.155-1.004-1.682-.595-2.113-.926 1.096-1.296 2.746-2.642 3.392-7.003.05-.347.007-.565 0-.845-.004-.17.035-.237.23-.256a4.173 4.173 0 0 0 1.545-.475c1.396-.763 1.96-2.015 2.093-3.517.02-.23-.004-.467-.247-.588zM11.581 18c-2.089-1.642-3.102-2.183-3.52-2.16-.392.024-.321.471-.235.763.09.288.207.486.371.739.114.167.192.416-.113.603-.673.416-1.842-.14-1.897-.167-1.361-.802-2.5-1.86-3.301-3.307-.774-1.393-1.224-2.887-1.298-4.482-.02-.386.093-.522.477-.592a4.696 4.696 0 0 1 1.529-.039c2.132.312 3.946 1.265 5.468 2.774.868.86 1.525 1.887 2.202 2.891.72 1.066 1.494 2.082 2.48 2.914.348.292.625.514.891.677-.802.09-2.14.11-3.054-.614zm1-6.44a.306.306 0 0 1 .415-.287.302.302 0 0 1 .2.288.306.306 0 0 1-.31.307.303.303 0 0 1-.304-.308zm3.11 1.596c-.2.081-.399.151-.59.16a1.245 1.245 0 0 1-.798-.254c-.274-.23-.47-.358-.552-.758a1.73 1.73 0 0 1 .016-.588c.07-.327-.008-.537-.239-.727-.187-.156-.426-.199-.688-.199a.559.559 0 0 1-.254-.078.253.253 0 0 1-.114-.358c.028-.054.16-.186.192-.21.356-.202.767-.136 1.146.016.352.144.618.408 1.001.782.391.451.462.576.685.914.176.265.336.537.445.848.067.195-.019.354-.25.452z"/></svg>

Before

Width:  |  Height:  |  Size: 2.1 KiB

View File

@@ -1 +0,0 @@
<svg width="15" height="15" viewBox="0 0 15 15" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M1 2C0.447715 2 0 2.44772 0 3V12C0 12.5523 0.447715 13 1 13H14C14.5523 13 15 12.5523 15 12V3C15 2.44772 14.5523 2 14 2H1ZM1 3L14 3V3.92494C13.9174 3.92486 13.8338 3.94751 13.7589 3.99505L7.5 7.96703L1.24112 3.99505C1.16621 3.94751 1.0826 3.92486 1 3.92494V3ZM1 4.90797V12H14V4.90797L7.74112 8.87995C7.59394 8.97335 7.40606 8.97335 7.25888 8.87995L1 4.90797Z" fill="currentColor" fill-rule="evenodd" clip-rule="evenodd"></path></svg>

Before

Width:  |  Height:  |  Size: 536 B

View File

@@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 36 36" fill="url(#a)" height="40" width="40"><defs><linearGradient x1="50%" x2="50%" y1="97.078%" y2="0%" id="a"><stop offset="0%" stop-color="#0062E0"/><stop offset="100%" stop-color="#19AFFF"/></linearGradient></defs><path d="M15 35.8C6.5 34.3 0 26.9 0 18 0 8.1 8.1 0 18 0s18 8.1 18 18c0 8.9-6.5 16.3-15 17.8l-1-.8h-4l-1 .8z"/><path fill="#FFF" d="m25 23 .8-5H21v-3.5c0-1.4.5-2.5 2.7-2.5H26V7.4c-1.3-.2-2.7-.4-4-.4-4.1 0-7 2.5-7 7v4h-4.5v5H15v12.7c1 .2 2 .3 3 .3s2-.1 3-.3V23h4z"/></svg>

Before

Width:  |  Height:  |  Size: 542 B

View File

@@ -1,14 +0,0 @@
<svg width="54" height="80" viewBox="0 0 54 80" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_912_3)">
<path d="M13.3333 80.0002C20.6933 80.0002 26.6667 74.0268 26.6667 66.6668V53.3335H13.3333C5.97333 53.3335 0 59.3068 0 66.6668C0 74.0268 5.97333 80.0002 13.3333 80.0002Z" fill="#0ACF83"/>
<path d="M0 39.9998C0 32.6398 5.97333 26.6665 13.3333 26.6665H26.6667V53.3332H13.3333C5.97333 53.3332 0 47.3598 0 39.9998Z" fill="#A259FF"/>
<path d="M0 13.3333C0 5.97333 5.97333 0 13.3333 0H26.6667V26.6667H13.3333C5.97333 26.6667 0 20.6933 0 13.3333Z" fill="#F24E1E"/>
<path d="M26.6667 0H40.0001C47.3601 0 53.3334 5.97333 53.3334 13.3333C53.3334 20.6933 47.3601 26.6667 40.0001 26.6667H26.6667V0Z" fill="#FF7262"/>
<path d="M53.3334 39.9998C53.3334 47.3598 47.3601 53.3332 40.0001 53.3332C32.6401 53.3332 26.6667 47.3598 26.6667 39.9998C26.6667 32.6398 32.6401 26.6665 40.0001 26.6665C47.3601 26.6665 53.3334 32.6398 53.3334 39.9998Z" fill="#1ABCFE"/>
</g>
<defs>
<clipPath id="clip0_912_3">
<rect width="53.3333" height="80" fill="white"/>
</clipPath>
</defs>
</svg>

Before

Width:  |  Height:  |  Size: 1.1 KiB

View File

@@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="600" height="600" fill="none" viewBox="0 0 600 600"><path fill="#FF9100" d="M213.918 560.499c23.248 9.357 48.469 14.909 74.952 15.834 35.84 1.252 69.922-6.158 100.391-20.234-36.537-14.355-69.627-35.348-97.869-61.448-18.306 29.31-45.382 52.462-77.474 65.848Z"/><path fill="#FFC400" d="M291.389 494.66c-64.466-59.622-103.574-145.917-100.269-240.568.108-3.073.27-6.145.46-9.216a166.993 166.993 0 0 0-36.004-5.241 167.001 167.001 0 0 0-51.183 6.153c-17.21 30.145-27.594 64.733-28.888 101.781-3.339 95.611 54.522 179.154 138.409 212.939 32.093-13.387 59.168-36.51 77.475-65.848Z"/><path fill="#FF9100" d="M291.39 494.657c14.988-23.986 24.075-52.106 25.133-82.403 2.783-79.695-50.792-148.251-124.942-167.381-.19 3.071-.352 6.143-.46 9.216-3.305 94.651 35.803 180.946 100.269 240.568Z"/><path fill="#DD2C00" d="M308.231 20.858C266 54.691 232.652 99.302 212.475 150.693c-11.551 29.436-18.81 61.055-20.929 94.2 74.15 19.13 127.726 87.686 124.943 167.38-1.058 30.297-10.172 58.39-25.134 82.404 28.24 26.127 61.331 47.093 97.868 61.447 73.337-33.9 125.37-106.846 128.383-193.127 1.952-55.901-19.526-105.724-49.875-147.778-32.051-44.477-159.5-194.36-159.5-194.36Z"/></svg>

Before

Width:  |  Height:  |  Size: 1.2 KiB

View File

@@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 128 128"><path fill="#64328B" d="M64 0C28.7 0 0 28.7 0 64s28.7 64 64 64 64-28.7 64-64S99.3 0 64 0zM13.2 64 64 114.8c-28.1 0-50.8-22.7-50.8-50.8zm62.2 49.5-60.9-61C19.7 30 39.9 13.2 64 13.2c16.6 0 31.3 7.9 40.5 20.2L97 40.6c-7.3-10.4-19.3-17.1-33-17.1-17.6 0-32.5 11.2-38.1 26.8C33.1 57 75.4 98.8 78.1 102c12.7-4.7 22.3-15.5 25.4-28.9H81.9v-9.4l33 .2c-.1 24.3-16.9 44.5-39.5 49.6z"/></svg>

Before

Width:  |  Height:  |  Size: 441 B

View File

@@ -1,3 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="xMidYMid" viewBox="0 0 256 256">
<path d="M251.17 116.6 139.4 4.82a16.49 16.49 0 0 0-23.31 0l-23.21 23.2 29.44 29.45a19.57 19.57 0 0 1 24.8 24.96l28.37 28.38a19.61 19.61 0 1 1-11.75 11.06L137.28 95.4v69.64a19.62 19.62 0 1 1-16.13-.57V94.2a19.61 19.61 0 0 1-10.65-25.73L81.46 39.44 4.83 116.08a16.49 16.49 0 0 0 0 23.32L116.6 251.17a16.49 16.49 0 0 0 23.32 0l111.25-111.25a16.5 16.5 0 0 0 0-23.33" fill="#DE4C36"/>
</svg>

Before

Width:  |  Height:  |  Size: 484 B

View File

@@ -1,11 +0,0 @@
<svg
viewBox="0 0 256 250"
width="256"
height="250"
fill="#fff"
xmlns="http://www.w3.org/2000/svg"
preserveAspectRatio="xMidYMid"
>
<path
d="M128.001 0C57.317 0 0 57.307 0 128.001c0 56.554 36.676 104.535 87.535 121.46 6.397 1.185 8.746-2.777 8.746-6.158 0-3.052-.12-13.135-.174-23.83-35.61 7.742-43.124-15.103-43.124-15.103-5.823-14.795-14.213-18.73-14.213-18.73-11.613-7.944.876-7.78.876-7.78 12.853.902 19.621 13.19 19.621 13.19 11.417 19.568 29.945 13.911 37.249 10.64 1.149-8.272 4.466-13.92 8.127-17.116-28.431-3.236-58.318-14.212-58.318-63.258 0-13.975 5-25.394 13.188-34.358-1.329-3.224-5.71-16.242 1.24-33.874 0 0 10.749-3.44 35.21 13.121 10.21-2.836 21.16-4.258 32.038-4.307 10.878.049 21.837 1.47 32.066 4.307 24.431-16.56 35.165-13.12 35.165-13.12 6.967 17.63 2.584 30.65 1.255 33.873 8.207 8.964 13.173 20.383 13.173 34.358 0 49.163-29.944 59.988-58.447 63.157 4.591 3.972 8.682 11.762 8.682 23.704 0 17.126-.148 30.91-.148 35.126 0 3.407 2.304 7.398 8.792 6.14C219.37 232.5 256 184.537 256 128.002 256 57.307 198.691 0 128.001 0Zm-80.06 182.34c-.282.636-1.283.827-2.194.39-.929-.417-1.45-1.284-1.15-1.922.276-.655 1.279-.838 2.205-.399.93.418 1.46 1.293 1.139 1.931Zm6.296 5.618c-.61.566-1.804.303-2.614-.591-.837-.892-.994-2.086-.375-2.66.63-.566 1.787-.301 2.626.591.838.903 1 2.088.363 2.66Zm4.32 7.188c-.785.545-2.067.034-2.86-1.104-.784-1.138-.784-2.503.017-3.05.795-.547 2.058-.055 2.861 1.075.782 1.157.782 2.522-.019 3.08Zm7.304 8.325c-.701.774-2.196.566-3.29-.49-1.119-1.032-1.43-2.496-.726-3.27.71-.776 2.213-.558 3.315.49 1.11 1.03 1.45 2.505.701 3.27Zm9.442 2.81c-.31 1.003-1.75 1.459-3.199 1.033-1.448-.439-2.395-1.613-2.103-2.626.301-1.01 1.747-1.484 3.207-1.028 1.446.436 2.396 1.602 2.095 2.622Zm10.744 1.193c.036 1.055-1.193 1.93-2.715 1.95-1.53.034-2.769-.82-2.786-1.86 0-1.065 1.202-1.932 2.733-1.958 1.522-.03 2.768.818 2.768 1.868Zm10.555-.405c.182 1.03-.875 2.088-2.387 2.37-1.485.271-2.861-.365-3.05-1.386-.184-1.056.893-2.114 2.376-2.387 1.514-.263 2.868.356 3.061 1.403Z" />
</svg>

Before

Width:  |  Height:  |  Size: 2.0 KiB

View File

@@ -1 +0,0 @@
<svg width="15" height="15" viewBox="0 0 15 15" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M7.49933 0.25C3.49635 0.25 0.25 3.49593 0.25 7.50024C0.25 10.703 2.32715 13.4206 5.2081 14.3797C5.57084 14.446 5.70302 14.2222 5.70302 14.0299C5.70302 13.8576 5.69679 13.4019 5.69323 12.797C3.67661 13.235 3.25112 11.825 3.25112 11.825C2.92132 10.9874 2.44599 10.7644 2.44599 10.7644C1.78773 10.3149 2.49584 10.3238 2.49584 10.3238C3.22353 10.375 3.60629 11.0711 3.60629 11.0711C4.25298 12.1788 5.30335 11.8588 5.71638 11.6732C5.78225 11.205 5.96962 10.8854 6.17658 10.7043C4.56675 10.5209 2.87415 9.89918 2.87415 7.12104C2.87415 6.32925 3.15677 5.68257 3.62053 5.17563C3.54576 4.99226 3.29697 4.25521 3.69174 3.25691C3.69174 3.25691 4.30015 3.06196 5.68522 3.99973C6.26337 3.83906 6.8838 3.75895 7.50022 3.75583C8.1162 3.75895 8.73619 3.83906 9.31523 3.99973C10.6994 3.06196 11.3069 3.25691 11.3069 3.25691C11.7026 4.25521 11.4538 4.99226 11.3795 5.17563C11.8441 5.68257 12.1245 6.32925 12.1245 7.12104C12.1245 9.9063 10.4292 10.5192 8.81452 10.6985C9.07444 10.9224 9.30633 11.3648 9.30633 12.0413C9.30633 13.0102 9.29742 13.7922 9.29742 14.0299C9.29742 14.2239 9.42828 14.4496 9.79591 14.3788C12.6746 13.4179 14.75 10.7025 14.75 7.50024C14.75 3.49593 11.5036 0.25 7.49933 0.25Z" fill="currentColor" fill-rule="evenodd" clip-rule="evenodd"></path></svg>

Before

Width:  |  Height:  |  Size: 1.3 KiB

View File

@@ -1,18 +0,0 @@
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 452 520"
>
<path
fill="#e34f26"
d="M41 460L0 0h451l-41 460-185 52"></path>
<path fill="#ef652a" d="M226 472l149-41 35-394H226"
></path>
<path
fill="#ecedee"
d="M226 208h-75l-5-58h80V94H84l15 171h127zm0 147l-64-17-4-45h-56l7 89 117 32z"
></path>
<path
fill="#fff"
d="M226 265h69l-7 73-62 17v59l115-32 16-174H226zm0-171v56h136l5-56z"
></path>
</svg>

Before

Width:  |  Height:  |  Size: 893 B

View File

@@ -1 +0,0 @@
<svg width="15" height="15" viewBox="0 0 15 15" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M7.49991 0.876892C3.84222 0.876892 0.877075 3.84204 0.877075 7.49972C0.877075 11.1574 3.84222 14.1226 7.49991 14.1226C11.1576 14.1226 14.1227 11.1574 14.1227 7.49972C14.1227 3.84204 11.1576 0.876892 7.49991 0.876892ZM1.82707 7.49972C1.82707 4.36671 4.36689 1.82689 7.49991 1.82689C10.6329 1.82689 13.1727 4.36671 13.1727 7.49972C13.1727 10.6327 10.6329 13.1726 7.49991 13.1726C4.36689 13.1726 1.82707 10.6327 1.82707 7.49972ZM8.24992 4.49999C8.24992 4.9142 7.91413 5.24999 7.49992 5.24999C7.08571 5.24999 6.74992 4.9142 6.74992 4.49999C6.74992 4.08577 7.08571 3.74999 7.49992 3.74999C7.91413 3.74999 8.24992 4.08577 8.24992 4.49999ZM6.00003 5.99999H6.50003H7.50003C7.77618 5.99999 8.00003 6.22384 8.00003 6.49999V9.99999H8.50003H9.00003V11H8.50003H7.50003H6.50003H6.00003V9.99999H6.50003H7.00003V6.99999H6.50003H6.00003V5.99999Z" fill="currentColor" fill-rule="evenodd" clip-rule="evenodd"></path></svg>

Before

Width:  |  Height:  |  Size: 1007 B

View File

@@ -1 +0,0 @@
<svg width="15" height="15" viewBox="0 0 15 15" fill="none" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M12.9091 12.909C13.2365 12.5817 13.4918 12.1895 13.6588 11.7577C13.8195 11.3443 13.9294 10.8718 13.961 10.1799C13.9926 9.48665 14.0001 9.26529 14.0001 7.50001C14.0001 5.73473 13.9926 5.51328 13.961 4.82008C13.9294 4.12821 13.8195 3.65573 13.6588 3.24228C13.4956 2.80857 13.2398 2.41567 12.9091 2.091C12.5844 1.76028 12.1915 1.50437 11.7578 1.34113C11.3443 1.18056 10.8718 1.0707 10.1799 1.03924C9.48675 1.00748 9.26537 1 7.50006 1C5.73476 1 5.51333 1.00748 4.82014 1.03912C4.12826 1.0707 3.65578 1.18056 3.24233 1.34125C2.80862 1.50447 2.41573 1.76032 2.09105 2.09098C1.76032 2.41563 1.5044 2.80852 1.34113 3.24225C1.18056 3.65573 1.0707 4.12821 1.03924 4.82008C1.00748 5.51328 1 5.73471 1 7.50001C1 9.26532 1.00748 9.48675 1.03924 10.1799C1.07083 10.8718 1.18069 11.3443 1.34138 11.7577C1.5046 12.1915 1.76045 12.5843 2.09111 12.909C2.41578 13.2397 2.80867 13.4955 3.24238 13.6587C3.65586 13.8194 4.12834 13.9293 4.82019 13.9609C5.51348 13.9925 5.73483 14 7.50012 14C9.2654 14 9.48685 13.9925 10.18 13.9609C10.8719 13.9293 11.3444 13.8194 11.7578 13.6587C12.1896 13.4917 12.5818 13.2364 12.9091 12.909ZM1.99949 6.73496C1.99974 6.94524 2.00005 7.19543 2.00005 7.50002C2.00005 7.80461 1.99974 8.0548 1.99949 8.26507C1.99849 9.08596 1.99824 9.29856 2.01963 9.7655C2.04625 10.3509 2.07823 10.7811 2.17588 11.1053C2.26976 11.417 2.37505 11.7342 2.7188 12.1171C3.06255 12.4999 3.39411 12.6733 3.81645 12.8007C4.23879 12.928 4.7696 12.9554 5.23052 12.9764C5.75332 13.0003 5.96052 13.0002 7.05714 12.9999L7.50006 12.9999C7.79304 12.9999 8.03569 13.0001 8.2409 13.0004C9.08195 13.0013 9.29425 13.0015 9.76575 12.9799C10.3512 12.9533 10.7814 12.9213 11.1056 12.8237C11.4173 12.7298 11.7345 12.6245 12.1173 12.2807C12.5001 11.937 12.6735 11.6054 12.8009 11.1831C12.9283 10.7607 12.9557 10.2299 12.9767 9.76902C13.0005 9.24689 13.0004 9.04027 13.0002 7.94749V7.94738L13.0001 7.50039L13.0001 7.05747C13.0004 5.96085 13.0005 5.75365 12.9766 5.23085C12.9556 4.76993 12.9282 4.23912 12.8009 3.81678C12.6735 3.39445 12.5001 3.06288 12.1173 2.71913C11.7345 2.37538 11.4172 2.27009 11.1056 2.17621C10.7813 2.07856 10.3511 2.04658 9.76571 2.01996C9.29421 1.99836 9.08194 1.99859 8.24092 1.99951H8.24092C8.0357 1.99974 7.79305 2.00001 7.50006 2.00001L7.05704 1.99993C5.96051 1.99964 5.75331 1.99958 5.23052 2.02343C4.7696 2.04446 4.23879 2.07183 3.81645 2.19921C3.39411 2.32659 3.06255 2.49999 2.7188 2.88281C2.37505 3.26562 2.26976 3.58286 2.17588 3.89453C2.07823 4.21874 2.04625 4.64894 2.01963 5.23437C1.99824 5.70131 1.99849 5.91401 1.99949 6.73496ZM7.49996 5.25015C6.25741 5.25015 5.25012 6.25744 5.25012 7.49999C5.25012 8.74254 6.25741 9.74983 7.49996 9.74983C8.74251 9.74983 9.7498 8.74254 9.7498 7.49999C9.7498 6.25744 8.74251 5.25015 7.49996 5.25015ZM4.25012 7.49999C4.25012 5.70515 5.70512 4.25015 7.49996 4.25015C9.2948 4.25015 10.7498 5.70515 10.7498 7.49999C10.7498 9.29483 9.2948 10.7498 7.49996 10.7498C5.70512 10.7498 4.25012 9.29483 4.25012 7.49999ZM10.9697 4.7803C11.3839 4.7803 11.7197 4.44452 11.7197 4.0303C11.7197 3.61609 11.3839 3.2803 10.9697 3.2803C10.5555 3.2803 10.2197 3.61609 10.2197 4.0303C10.2197 4.44452 10.5555 4.7803 10.9697 4.7803Z" fill="currentColor"></path></svg>

Before

Width:  |  Height:  |  Size: 3.2 KiB

View File

@@ -1,8 +0,0 @@
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 1052 1052"
><path fill="#f0db4f" d="M0 0h1052v1052H0z"
></path><path
d="M965.9 801.1c-7.7-48-39-88.3-131.7-125.9-32.2-14.8-68.1-25.399-78.8-49.8-3.8-14.2-4.3-22.2-1.9-30.8 6.9-27.9 40.2-36.6 66.6-28.6 17 5.7 33.1 18.801 42.8 39.7 45.4-29.399 45.3-29.2 77-49.399-11.6-18-17.8-26.301-25.4-34-27.3-30.5-64.5-46.2-124-45-10.3 1.3-20.699 2.699-31 4-29.699 7.5-58 23.1-74.6 44-49.8 56.5-35.6 155.399 25 196.1 59.7 44.8 147.4 55 158.6 96.9 10.9 51.3-37.699 67.899-86 62-35.6-7.4-55.399-25.5-76.8-58.4-39.399 22.8-39.399 22.8-79.899 46.1 9.6 21 19.699 30.5 35.8 48.7 76.2 77.3 266.899 73.5 301.1-43.5 1.399-4.001 10.6-30.801 3.199-72.101zm-394-317.6h-98.4c0 85-.399 169.4-.399 254.4 0 54.1 2.8 103.7-6 118.9-14.4 29.899-51.7 26.2-68.7 20.399-17.3-8.5-26.1-20.6-36.3-37.699-2.8-4.9-4.9-8.7-5.601-9-26.699 16.3-53.3 32.699-80 49 13.301 27.3 32.9 51 58 66.399 37.5 22.5 87.9 29.4 140.601 17.3 34.3-10 63.899-30.699 79.399-62.199 22.4-41.3 17.6-91.3 17.4-146.6.5-90.2 0-180.4 0-270.9z"
fill="#323330"></path></svg
>

Before

Width:  |  Height:  |  Size: 1.2 KiB

View File

@@ -1 +0,0 @@
<svg width="15" height="15" viewBox="0 0 15 15" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M2 1C1.44772 1 1 1.44772 1 2V13C1 13.5523 1.44772 14 2 14H13C13.5523 14 14 13.5523 14 13V2C14 1.44772 13.5523 1 13 1H2ZM3.05 6H4.95V12H3.05V6ZM5.075 4.005C5.075 4.59871 4.59371 5.08 4 5.08C3.4063 5.08 2.925 4.59871 2.925 4.005C2.925 3.41129 3.4063 2.93 4 2.93C4.59371 2.93 5.075 3.41129 5.075 4.005ZM12 8.35713C12 6.55208 10.8334 5.85033 9.67449 5.85033C9.29502 5.83163 8.91721 5.91119 8.57874 6.08107C8.32172 6.21007 8.05265 6.50523 7.84516 7.01853H7.79179V6.00044H6V12.0047H7.90616V8.8112C7.8786 8.48413 7.98327 8.06142 8.19741 7.80987C8.41156 7.55832 8.71789 7.49825 8.95015 7.46774H9.02258C9.62874 7.46774 10.0786 7.84301 10.0786 8.78868V12.0047H11.9847L12 8.35713Z" fill="currentColor" fill-rule="evenodd" clip-rule="evenodd"></path></svg>

Before

Width:  |  Height:  |  Size: 848 B

View File

@@ -1,5 +0,0 @@
<svg id="Capa_2" data-name="Capa 2" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 228.06 45">
<g id="Capa_1-2" data-name="Capa 1">
<path d="M225.64,9l2.41-9h-36l-2.41,9h0l-7.23,27h-22.5L169.56,0H12.06L0,45h49.5l4.82-18h15.75l2.41-9h-15.75l2.41-9h22.5l-7.23,27h0l-2.41,9h144l2.41-9h-22.5l2.41-9h15.75l2.41-9h-15.75l2.41-9h22.5ZM43.23,18l-2.41,9h0l-2.41,9H15.91l2.41-9h15.76l2.41-9h-15.76l2.41-9h22.5l-2.41,9h0ZM110.41,36h-22.5l2.41-9h15.75l2.41-9h-15.75l2.41-9h22.5l-7.23,27h0ZM146.41,36h-22.5l2.41-9h15.75l2.41-9h-15.75l2.41-9h22.5l-7.23,27h0Z"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 568 B

View File

@@ -1 +0,0 @@
<svg viewBox="0 0 208 128" xmlns="http://www.w3.org/2000/svg" xml:space="preserve" ><path fill="none" stroke="#FFF" stroke-width="10" d="M15 5h178a10 10 0 0 1 10 10v98a10 10 0 0 1-10 10H15a10 10 0 0 1-10-10V15A10 10 0 0 1 15 5z"/><path fill="#FFF" d="M30 98V30h20l20 25 20-25h20v68H90V59L70 84 50 59v39H30zm125 0-30-33h20V30h20v35h20l-30 33z"/></svg>

Before

Width:  |  Height:  |  Size: 350 B

View File

@@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="1000" height="1000" aria-labelledby="css-logo-title css-logo-description" viewBox="0 0 1000 1000"><path fill="#639" d="M0 0h840a160 160 0 0 1 160 160v680a160 160 0 0 1-160 160H160A160 160 0 0 1 0 840V0Z"/><path fill="#fff" d="M816.54 919.9c-32.39 0-57.16-9.42-74.5-28.35-17.15-19.03-26.08-46.18-26.88-81.64h69.8c.4 31.36 11.42 47.08 33.08 47.08 11.04 0 18.86-3.5 23.37-10.42 4.41-6.9 6.72-17.93 6.72-33.05 0-12.02-3.01-22.04-8.83-29.95a73.2 73.2 0 0 0-29.48-21.14L783.95 750c-23.06-11.02-39.81-24.04-50.14-39.27-10.03-15.13-15.04-36.36-15.04-63.5 0-30.36 8.83-55 26.37-73.94 18.05-18.93 42.62-28.34 74-28.34 30.3 0 53.76 9.31 70.3 27.84 16.85 18.64 25.67 45.28 26.38 80.14h-67.19c.4-11.4-1.9-22.72-6.72-33.06-3.8-7.6-11.23-11.41-22.26-11.41-19.65 0-29.48 11.71-29.48 35.05 0 11.83 2.4 21.04 7.22 28.05A65.18 65.18 0 0 0 822.76 689l24.77 10.92c25.57 11.72 44.02 26.05 55.35 43.38 11.43 17.23 17.05 40.27 17.05 69.12 0 34.56-9.03 61.1-27.38 79.63-18.25 18.53-43.62 27.85-76 27.85Zm-225.42 0c-32.4 0-57.16-9.42-74.51-28.35-17.15-19.03-26.07-46.18-26.87-81.64h69.79c.4 31.36 11.43 47.08 33.1 47.08 11.02 0 18.84-3.5 23.25-10.42 4.52-6.9 6.72-17.93 6.72-33.05 0-12.02-2.9-22.04-8.72-29.95a73.2 73.2 0 0 0-29.48-21.14L558.53 750c-23.07-11.02-39.81-24.04-50.14-39.27-10.03-15.13-15.04-36.36-15.04-63.5 0-30.36 8.82-55 26.37-73.94 18.05-18.93 42.62-28.34 74-28.34 30.29 0 53.75 9.31 70.2 27.84 17.05 18.64 25.77 45.28 26.47 80.14h-67.18c.4-11.4-1.9-22.72-6.72-33.06-3.81-7.6-11.23-11.41-22.26-11.41-19.66 0-29.49 11.71-29.49 35.05 0 11.83 2.41 21.04 7.22 28.05A65.18 65.18 0 0 0 597.33 689l24.77 10.92c25.57 11.72 44.02 26.05 55.36 43.38 11.33 17.23 17.04 40.27 17.04 69.12 0 34.56-9.12 61.1-27.37 79.63-18.25 18.53-43.62 27.85-76.01 27.85Zm-234.75 0c-31.7 0-56.86-8.62-75.51-25.85-18.65-17.12-27.88-42.87-27.88-76.93V648.83c0-33.85 9.83-59.5 29.48-77.13 19.96-17.43 46.13-26.24 78.52-26.24 31.39 0 56.15 9.01 74.5 26.84 18.56 17.93 27.88 44.58 27.88 80.14v13.32h-73.9v-12.92c0-13.72-3.01-23.84-8.83-30.45a26.46 26.46 0 0 0-21.66-10.32c-12.03 0-20.55 4.1-25.37 12.42a79.04 79.04 0 0 0-6.72 36.66v146.26c0 30.55 10.74 46.08 32.1 46.38 10.02 0 17.54-3.61 22.76-10.82a51.74 51.74 0 0 0 7.72-30.46V801.6h73.9v11.42c0 23.74-4.61 43.57-13.94 59.4a88.8 88.8 0 0 1-38.2 35.66 121.46 121.46 0 0 1-54.85 11.82Z"/></svg>

Before

Width:  |  Height:  |  Size: 2.3 KiB

Some files were not shown because too many files have changed in this diff Show More