diff --git a/.gitea/workflows/build-image.yml b/.gitea/workflows/build-image.yml new file mode 100644 index 0000000..a63fca2 --- /dev/null +++ b/.gitea/workflows/build-image.yml @@ -0,0 +1,48 @@ +name: Build and Push Docker Image + +on: + push: + branches: + - main + - master + +env: + REGISTRY: ${{ gitea.server_url }} + IMAGE_NAME: ${{ gitea.repository }} + +jobs: + build-and-push: + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Log in to Gitea Container Registry + uses: docker/login-action@v3 + with: + registry: ${{ env.REGISTRY }} + username: ${{ gitea.actor }} + password: ${{ secrets.REGISTRY_TOKEN }} + + - name: Extract metadata (tags, labels) + id: meta + uses: docker/metadata-action@v5 + with: + images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} + tags: | + type=ref,event=branch + type=sha,prefix= + type=raw,value=latest,enable=${{ gitea.ref == format('refs/heads/{0}', 'main') || gitea.ref == format('refs/heads/{0}', 'master') }} + + - name: Build and push Docker image + uses: docker/build-push-action@v6 + with: + context: . + push: true + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} + cache-from: type=gha + cache-to: type=gha,mode=max diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..0c0ad08 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,34 @@ +# Stage 1: Build +FROM node:20-alpine AS builder + +WORKDIR /app + +# Install pnpm +RUN corepack enable && corepack prepare pnpm@latest --activate + +# Copy package files +COPY package.json pnpm-lock.yaml ./ + +# Install dependencies +RUN pnpm install --frozen-lockfile + +# Copy source files +COPY . . + +# Build the site +RUN pnpm build + +# Stage 2: Serve with nginx +FROM nginx:alpine AS runner + +# Copy built files +COPY --from=builder /app/dist /usr/share/nginx/html + +# Copy nginx configuration +COPY nginx.conf /etc/nginx/conf.d/default.conf + +# Expose port +EXPOSE 80 + +# Start nginx +CMD ["nginx", "-g", "daemon off;"] diff --git a/assets/homelab.png b/assets/homelab.png new file mode 100644 index 0000000..e9396c7 Binary files /dev/null and b/assets/homelab.png differ diff --git a/assets/lab.png b/assets/lab.png new file mode 100644 index 0000000..5e043dc Binary files /dev/null and b/assets/lab.png differ diff --git a/assets/logo.png b/assets/logo.png new file mode 100644 index 0000000..272792f Binary files /dev/null and b/assets/logo.png differ diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..168cec8 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,6 @@ +services: + portfolio: + build: . + ports: + - "8080:80" + restart: unless-stopped diff --git a/nginx.conf b/nginx.conf new file mode 100644 index 0000000..74781a0 --- /dev/null +++ b/nginx.conf @@ -0,0 +1,55 @@ +server { + listen 80; + listen [::]:80; + server_name _; + + root /usr/share/nginx/html; + index index.html; + + # Security headers + add_header X-Frame-Options "SAMEORIGIN" always; + add_header X-Content-Type-Options "nosniff" always; + add_header X-XSS-Protection "1; mode=block" always; + add_header Referrer-Policy "strict-origin-when-cross-origin" always; + + # Gzip compression + gzip on; + gzip_vary on; + gzip_min_length 1024; + gzip_proxied any; + gzip_types + text/plain + text/css + text/xml + text/javascript + application/javascript + application/json + application/xml + application/rss+xml + application/atom+xml + image/svg+xml; + + # Static file caching + location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ { + expires 1y; + add_header Cache-Control "public, immutable"; + access_log off; + } + + # HTML files - no cache for dynamic updates + location ~* \.html$ { + expires -1; + add_header Cache-Control "no-store, no-cache, must-revalidate"; + } + + # Main location block + location / { + try_files $uri $uri/ $uri.html =404; + } + + # Custom error pages + error_page 404 /404.html; + location = /404.html { + internal; + } +} diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml new file mode 100644 index 0000000..9737f55 --- /dev/null +++ b/pnpm-workspace.yaml @@ -0,0 +1,5 @@ +ignoredBuiltDependencies: + - '@biomejs/biome' + - '@tailwindcss/oxide' + - esbuild + - sharp diff --git a/public/fonts/InstrumentSerif-Italic.woff2 b/public/fonts/InstrumentSerif-Italic.woff2 new file mode 100644 index 0000000..197abca Binary files /dev/null and b/public/fonts/InstrumentSerif-Italic.woff2 differ diff --git a/public/fonts/InstrumentSerif-Regular.woff2 b/public/fonts/InstrumentSerif-Regular.woff2 new file mode 100644 index 0000000..0ad6971 Binary files /dev/null and b/public/fonts/InstrumentSerif-Regular.woff2 differ diff --git a/public/fonts/Inter-Variable.woff2 b/public/fonts/Inter-Variable.woff2 new file mode 100644 index 0000000..5a8d3e7 Binary files /dev/null and b/public/fonts/Inter-Variable.woff2 differ diff --git a/src/assets/work/free-3d-valentines-assets/01.jpg b/src/assets/work/free-3d-valentines-assets/01.jpg deleted file mode 100644 index 0fa57f1..0000000 Binary files a/src/assets/work/free-3d-valentines-assets/01.jpg and /dev/null differ diff --git a/src/assets/work/free-3d-valentines-assets/02.jpg b/src/assets/work/free-3d-valentines-assets/02.jpg deleted file mode 100644 index e3cc070..0000000 Binary files a/src/assets/work/free-3d-valentines-assets/02.jpg and /dev/null differ diff --git a/src/assets/work/free-3d-valentines-assets/03.jpg b/src/assets/work/free-3d-valentines-assets/03.jpg deleted file mode 100644 index 2500280..0000000 Binary files a/src/assets/work/free-3d-valentines-assets/03.jpg and /dev/null differ diff --git a/src/assets/work/free-3d-valentines-assets/04.jpg b/src/assets/work/free-3d-valentines-assets/04.jpg deleted file mode 100644 index 30ac522..0000000 Binary files a/src/assets/work/free-3d-valentines-assets/04.jpg and /dev/null differ diff --git a/src/assets/work/free-3d-valentines-assets/05.jpg b/src/assets/work/free-3d-valentines-assets/05.jpg deleted file mode 100644 index 6d29e0e..0000000 Binary files a/src/assets/work/free-3d-valentines-assets/05.jpg and /dev/null differ diff --git a/src/assets/work/free-3d-valentines-assets/logo.png b/src/assets/work/free-3d-valentines-assets/logo.png deleted file mode 100644 index 98af311..0000000 Binary files a/src/assets/work/free-3d-valentines-assets/logo.png and /dev/null differ diff --git a/src/assets/work/luonmodels/001.jpg b/src/assets/work/luonmodels/001.jpg deleted file mode 100644 index 721e270..0000000 Binary files a/src/assets/work/luonmodels/001.jpg and /dev/null differ diff --git a/src/assets/work/luonmodels/002.jpg b/src/assets/work/luonmodels/002.jpg deleted file mode 100644 index 9aa3a9e..0000000 Binary files a/src/assets/work/luonmodels/002.jpg and /dev/null differ diff --git a/src/assets/work/luonmodels/003.jpg b/src/assets/work/luonmodels/003.jpg deleted file mode 100644 index 67deeb9..0000000 Binary files a/src/assets/work/luonmodels/003.jpg and /dev/null differ diff --git a/src/assets/work/luonmodels/004.jpg b/src/assets/work/luonmodels/004.jpg deleted file mode 100644 index 00eb689..0000000 Binary files a/src/assets/work/luonmodels/004.jpg and /dev/null differ diff --git a/src/assets/work/luonmodels/005.jpg b/src/assets/work/luonmodels/005.jpg deleted file mode 100644 index 8c603cb..0000000 Binary files a/src/assets/work/luonmodels/005.jpg and /dev/null differ diff --git a/src/assets/work/luonmodels/006.jpg b/src/assets/work/luonmodels/006.jpg deleted file mode 100644 index 43fdc2b..0000000 Binary files a/src/assets/work/luonmodels/006.jpg and /dev/null differ diff --git a/src/assets/work/luonmodels/007.jpg b/src/assets/work/luonmodels/007.jpg deleted file mode 100644 index b34848e..0000000 Binary files a/src/assets/work/luonmodels/007.jpg and /dev/null differ diff --git a/src/assets/work/luonmodels/008.jpg b/src/assets/work/luonmodels/008.jpg deleted file mode 100644 index 5789a9e..0000000 Binary files a/src/assets/work/luonmodels/008.jpg and /dev/null differ diff --git a/src/assets/work/luonmodels/009.jpg b/src/assets/work/luonmodels/009.jpg deleted file mode 100644 index 96cb936..0000000 Binary files a/src/assets/work/luonmodels/009.jpg and /dev/null differ diff --git a/src/assets/work/luonmodels/010.jpg b/src/assets/work/luonmodels/010.jpg deleted file mode 100644 index 3dc5c1c..0000000 Binary files a/src/assets/work/luonmodels/010.jpg and /dev/null differ diff --git a/src/assets/work/luonmodels/011.jpg b/src/assets/work/luonmodels/011.jpg deleted file mode 100644 index 305f11d..0000000 Binary files a/src/assets/work/luonmodels/011.jpg and /dev/null differ diff --git a/src/assets/work/luonmodels/012.jpg b/src/assets/work/luonmodels/012.jpg deleted file mode 100644 index acd119a..0000000 Binary files a/src/assets/work/luonmodels/012.jpg and /dev/null differ diff --git a/src/assets/work/luonmodels/013.jpg b/src/assets/work/luonmodels/013.jpg deleted file mode 100644 index 59addbb..0000000 Binary files a/src/assets/work/luonmodels/013.jpg and /dev/null differ diff --git a/src/assets/work/luonmodels/014.jpg b/src/assets/work/luonmodels/014.jpg deleted file mode 100644 index fae5fa2..0000000 Binary files a/src/assets/work/luonmodels/014.jpg and /dev/null differ diff --git a/src/assets/work/ricoblog2024/P_01.jpg b/src/assets/work/ricoblog2024/P_01.jpg deleted file mode 100644 index b830dab..0000000 Binary files a/src/assets/work/ricoblog2024/P_01.jpg and /dev/null differ diff --git a/src/assets/work/ricoblog2024/P_02.jpg b/src/assets/work/ricoblog2024/P_02.jpg deleted file mode 100644 index dd45679..0000000 Binary files a/src/assets/work/ricoblog2024/P_02.jpg and /dev/null differ diff --git a/src/assets/work/ricoblog2024/P_03.jpg b/src/assets/work/ricoblog2024/P_03.jpg deleted file mode 100644 index 559bed7..0000000 Binary files a/src/assets/work/ricoblog2024/P_03.jpg and /dev/null differ diff --git a/src/assets/work/ricoblog2024/P_04.jpg b/src/assets/work/ricoblog2024/P_04.jpg deleted file mode 100644 index f145260..0000000 Binary files a/src/assets/work/ricoblog2024/P_04.jpg and /dev/null differ diff --git a/src/assets/work/ricoblog2024/P_05.jpg b/src/assets/work/ricoblog2024/P_05.jpg deleted file mode 100644 index 4eb23f5..0000000 Binary files a/src/assets/work/ricoblog2024/P_05.jpg and /dev/null differ diff --git a/src/assets/work/ricoblog2024/P_06.jpg b/src/assets/work/ricoblog2024/P_06.jpg deleted file mode 100644 index 057bda8..0000000 Binary files a/src/assets/work/ricoblog2024/P_06.jpg and /dev/null differ diff --git a/src/assets/work/ricoblog2024/P_07.jpg b/src/assets/work/ricoblog2024/P_07.jpg deleted file mode 100644 index bb8995c..0000000 Binary files a/src/assets/work/ricoblog2024/P_07.jpg and /dev/null differ diff --git a/src/assets/work/ricoblog2024/logo.png b/src/assets/work/ricoblog2024/logo.png deleted file mode 100644 index 84dc3b5..0000000 Binary files a/src/assets/work/ricoblog2024/logo.png and /dev/null differ diff --git a/src/collections/experiences.json b/src/collections/experiences.json index c8ea945..c5f23ab 100644 --- a/src/collections/experiences.json +++ b/src/collections/experiences.json @@ -1,17 +1,16 @@ [ { - "dates": "June 2018 · Present", - "role": "Web & Product Designer", - "company": "Company Name", - "description": "Leading the design of user-centric web applications and dating platforms.", - "logo": "/assets/experiences/company.jpg" + "dates": "2024 - Present", + "role": "President", + "company": "HEC IA", + "description": "Technical workshops on AI tools for business students.", + "logo": "/assets/experiences/hec-ia.png" }, { - "dates": "July 2016 · June 2017", - "role": "Web & Product Designer", - "company": "Company Name", - "description": "Spearheaded the design and development of e-commerce websites and online marketplaces.", - "logo": "/assets/experiences/company.jpg" + "dates": "2023 - Present", + "role": "Freelance Developer", + "company": "Self-employed", + "description": "Fullstack development. Python, Golang, automation.", + "logo": "/assets/experiences/freelance.png" } - ] diff --git a/src/collections/featuredwork.json b/src/collections/featuredwork.json index 59cd977..e3bde3e 100644 --- a/src/collections/featuredwork.json +++ b/src/collections/featuredwork.json @@ -1,58 +1,26 @@ [ { - "name": "RicoOG", - "description": "OG Inspiration Library", - "tags": ["Open Graph", "Design", "Library"], - "image": "/assets/works/ricoog.jpg", - "video": "/assets/works/ricoog.mp4", - "url": "https://ricoog.com/", + "name": "Homelab Infrastructure", + "description": "Self-hosted production infrastructure", + "tags": ["Kubernetes", "Proxmox", "Docker", "Monitoring"], + "image": "/assets/works/homelab.jpg", + "url": "/work/homelab", "isShow": true }, { - "name": "GradientsHub", - "description": "Gradient Resources & Tools", - "tags": ["Gradient","Resources","Tools"], - "image": "/assets/works/gradientshub.jpg", - "video": "/assets/works/gradientshub.mp4", - "url": "https://gradientshub.com" + "name": "HEC IA", + "description": "AI workshops for business students", + "tags": ["Education", "AI", "Workshops"], + "image": "/assets/works/hec-ia.jpg", + "url": "/work/hec-ia", + "isShow": true }, { - "name": "Luon Models", - "description": "Company Website", - "tags": ["Company","Website","Branding"], - "image": "/assets/works/luonmodels.jpg", - "video": "/assets/works/luonmodels.mp4", - "url": "https://luonmodels.netlify.app/" - }, - { - "name": "Ricoui", - "description": "Designer Portfolio", - "tags": ["Designer","Portfolio","Open Source"], - "image": "/assets/works/ricoui.jpg", - "video": "/assets/works/ricoui.mp4", - "url": "/work/ricoblog2024" - - }, - { - "name": "3D Valentines Assets", - "description": "Blender Design Resources & Assets", - "tags": ["3D","Resources","Assets"], - "image": "/assets/works/3d-valentines.jpg", - "video": "/assets/works/3d-valentines.mp4", - "url": "/work/3dvalentine" - }, - { - "name": "UIUXDECK", - "description": "Design Resources & Tools", - "tags": ["Design","Resources","Tools"], - "image": "/assets/works/uiuxdeck.jpg", - "url": "http://uiuxdeck.com/" - }, - { - "name": "Inspoweb", - "description": "Web Inspiration Library", - "tags": ["Inspiration","Web Collection"], - "image": "/assets/works/inspoweb.jpg", - "url": "https://inspoweb.com/" + "name": "Freelance Development", + "description": "Fullstack development and automation", + "tags": ["Python", "Golang", "Automation"], + "image": "/assets/works/freelance.jpg", + "url": "/work/freelance", + "isShow": true } ] diff --git a/src/collections/menu.json b/src/collections/menu.json index 19af874..a7bf79c 100644 --- a/src/collections/menu.json +++ b/src/collections/menu.json @@ -4,11 +4,7 @@ "url": "/" }, { - "name": "Writing", - "url": "/blog" - }, - { - "name": "Works", + "name": "Projects", "url": "/works" }, { diff --git a/src/collections/social.json b/src/collections/social.json index f107313..8972c4b 100644 --- a/src/collections/social.json +++ b/src/collections/social.json @@ -1,68 +1,18 @@ [ { - "id": 1, + "id": 1, "name": "Github", - "username": "ricocc", + "username": "vorpax", "image": "/assets/social/social-github.jpg", - "url": "https://github.com/ricocc/" + "url": "https://github.com/vorpax", + "isShow": true }, - { - "id": 2, - "name": "Xiaohongshu", - "username": "ricouii", - "image": "/assets/social/social-xiaohongshu.jpg", - "url": "https://www.xiaohongshu.com/user/profile/5f2b6903000000000101f51f" - }, - - { - "id": 3, - "name": "Twitter", - "username": "ricouii", - "image": "/assets/social/social-twitter.jpg", - "url": "https://x.com/ricouii" - }, - - { - "id": 4, - "name": "Gumroad", - "username": "ricoui", - "image": "/assets/social/social-gumroad.jpg", - "url": "https://ricoui.gumroad.com/" - }, - - { - "id": 5, - "name": "Behance", - "username": "ricoui", - "image": "/assets/social/social-behance.jpg", - "url": "https://www.behance.net/ricoui" - }, - - { - "id": 6, - "name": "figma", - "username": "ricocc", - "image": "/assets/social/social-figma.jpg", - "url": "https://www.figma.com/@ricocc", - "isShow": false - }, - - { - "id": 7, - "name": "Dribbble", - "username": "ricoui", - "image": "/assets/social/social-dribbble.jpg", - "url": "https://dribbble.com/ricoui" - }, - - { - "id": 8, - "name": "Email", - "username": "ricocc", - "image": "/assets/social/social-email.jpg", - "url": "mailto:ricocc@qq.com" + "id": 2, + "name": "LinkedIn", + "username": "alexandre-houard", + "image": "/assets/social/social-linkedin.jpg", + "url": "https://www.linkedin.com/in/alexandre-houard-686960279/", + "isShow": true } - - ] diff --git a/src/collections/works.json b/src/collections/works.json index 6ce4931..e3bde3e 100644 --- a/src/collections/works.json +++ b/src/collections/works.json @@ -1,58 +1,26 @@ [ { - "name": "RicoOG", - "description": "OG Inspiration Library", - "tags": ["Open Graph", "Design", "Library"], - "image": "/assets/works/ricoog.jpg", - "video": "/assets/works/ricoog.mp4", - "url": "https://ricoog.com/", + "name": "Homelab Infrastructure", + "description": "Self-hosted production infrastructure", + "tags": ["Kubernetes", "Proxmox", "Docker", "Monitoring"], + "image": "/assets/works/homelab.jpg", + "url": "/work/homelab", "isShow": true }, { - "name": "GradientsHub", - "description": "Gradient Resources & Tools", - "tags": ["Gradient","Resources","Tools"], - "image": "/assets/works/gradientshub.jpg", - "video": "/assets/works/gradientshub.mp4", - "url": "https://gradientshub.com" + "name": "HEC IA", + "description": "AI workshops for business students", + "tags": ["Education", "AI", "Workshops"], + "image": "/assets/works/hec-ia.jpg", + "url": "/work/hec-ia", + "isShow": true }, { - "name": "Luon Models", - "description": "Agency Company Website", - "tags": ["Agency","Website"], - "image": "/assets/works/luonmodels.jpg", - "video": "/assets/works/luonmodels.mp4", - "url": "/work/luonmodels" - }, - { - "name": "Ricoui", - "description": "Designer Portfolio", - "tags": ["Designer","Portfolio","Open Source"], - "image": "/assets/works/ricoui.jpg", - "video": "/assets/works/ricoui.mp4", - "url": "/work/ricoblog2024" - - }, - { - "name": "3D Valentines Assets", - "description": "Blender Design Resources & Assets", - "tags": ["3D","Resources","Assets"], - "image": "/assets/works/3d-valentines.jpg", - "video": "/assets/works/3d-valentines.mp4", - "url": "/work/3dvalentine" - }, - { - "name": "UIUXDECK", - "description": "Design Resources & Tools", - "tags": ["Design","Resources","Tools"], - "image": "/assets/works/uiuxdeck.jpg", - "url": "http://uiuxdeck.com/" - }, - { - "name": "Inspoweb", - "description": "Web Inspiration Library", - "tags": ["Inspiration","Web Collection"], - "image": "/assets/works/inspoweb.jpg", - "url": "https://inspoweb.com/" + "name": "Freelance Development", + "description": "Fullstack development and automation", + "tags": ["Python", "Golang", "Automation"], + "image": "/assets/works/freelance.jpg", + "url": "/work/freelance", + "isShow": true } ] diff --git a/src/components/sections/Explore.astro b/src/components/sections/Explore.astro index 46d2a0a..4880380 100644 --- a/src/components/sections/Explore.astro +++ b/src/components/sections/Explore.astro @@ -1,15 +1,12 @@ --- import SectionHeader from "@/components/elements/SectionHeader.astro"; -import Matter from "@/components/ui/Matter.astro"; -import Button from "@/components/ui/Button.astro"; -import Tools from "../ui/Tools.astro"; +import { Server, Code, GraduationCap } from "@lucide/astro"; + interface Props { title?: string; description?: string; } -const {title, description -} = Astro.props; - +const { title, description } = Astro.props; ---
@@ -19,141 +16,67 @@ const {title, description
- - \ No newline at end of file diff --git a/src/components/sections/Header.astro b/src/components/sections/Header.astro index 9abdd2f..aac5f63 100644 --- a/src/components/sections/Header.astro +++ b/src/components/sections/Header.astro @@ -1,5 +1,6 @@ --- -import { Mail, Moon, SunMedium,Download } from "@lucide/astro"; +import { Moon, SunMedium } from "@lucide/astro"; +import { siteConfig } from "@/config/site.js"; import menus from "@/collections/menu.json"; import Button from "@/components/ui/Button.astro"; import Logo from "@/components/ui/Logo.astro"; @@ -109,19 +110,19 @@ import Logo from "@/components/ui/Logo.astro"; } - +
-
-
+

"Beautiful design. Clean code. That's the goal."

- + >"Bridging business strategy with technical implementation."

- {/* Hover overlay */} - {/*
*/}
)) } @@ -137,55 +130,32 @@ const filtered = headings.filter(h => h.depth <= 3);
-

- I'm Rico, a Senior Web & Product Designer. + Started in business prep school, now at HEC Paris. Self-taught in infrastructure and development. I bridge business strategy with technical implementation.

-

- With 8+ years of experience in UX/UI, I not only enjoy creative design and content creation, but coding is also one of my great interests. I often transform my rich and quirky ideas and creativity into design outcomes and tangible projects. - -

-

- Great design isn't just a pretty interface—it helps people reach their goals naturally, fuels sustainable growth, and keeps systems solid as you scale. I connect design and development, bringing strategy, usability, and execution together to turn visuals into real, measurable results. -

- - -
- - + +
- -

h.depth <= 3); data-aos-duration="600" data-aos-once="true" > - -
+ +
- +
- Product Design + Infrastructure
- -
-
- -
- Website Design -
-
-
- -
-
- -
- Brand Design -
-
-
- -
-
- -
- Prototyping -
-
-
- -
+ +
- Development + Fullstack Development
- -
+ +
- +
- UI/UX Design + Business Strategy +
+
+
+ +
+
+ +
+ DevOps
@@ -256,33 +208,10 @@ const filtered = headings.filter(h => h.depth <= 3);
-
-

Tool Stack

-
- - -
-
-
-
- -

h.depth <= 3); }

+
+ +
+

+ Education +

+
+
+ +
+

HEC Paris

+

M1 - Master in Management

+
+
+
+ +
+

Sorbonne University

+

Bachelor's in Mathematics

+
+
+
+
+ +
+

h.depth <= 3); data-aos-duration="500" data-aos-once="true" > - If you want to stay up to date with my work be sure to follow me on twitter, or you can send me an email and I'll be sure to get back to you. + class="text-primary underline dark:text-primary-light">LinkedIn or check out my work on GitHub. +

+

+ Email: {siteConfig.mail}

diff --git a/src/pages/index.astro b/src/pages/index.astro index a6bf802..749db98 100644 --- a/src/pages/index.astro +++ b/src/pages/index.astro @@ -1,29 +1,27 @@ --- import Button from "../components/ui/Button.astro"; import { siteConfig } from "@/config/site"; -import HeroCard from "@/components/home/HeroCard.astro"; import Layout from "@/layouts/Layout.astro"; import FeaturedWork from "../components/sections/FeaturedWork.astro"; -import BlogSection from "@/components/sections/BlogSection.astro"; import SocialCard from "@/components/cards/SocialCard.astro"; import AnimatedText from "@/components/ui/AnimatedText.astro"; import Explore from "@/components/sections/Explore.astro"; ---
-
+

+ +
- +
-
@@ -74,11 +72,11 @@ keywords="Rico, Portfolio, Web Design, UI Design, Frontend Development, Creative data-aos-duration="600" data-aos-once="true" > - +

- +
-
@@ -102,7 +95,7 @@ keywords="Rico, Portfolio, Web Design, UI Design, Frontend Development, Creative data-aos-duration="600" data-aos-once="true" > - +
- -
- -
- +
diff --git a/src/pages/infrastructure.astro b/src/pages/infrastructure.astro new file mode 100644 index 0000000..8798ded --- /dev/null +++ b/src/pages/infrastructure.astro @@ -0,0 +1,111 @@ +--- +import Layout from "@/layouts/Layout.astro"; +import { Server, Database, Shield, Globe, Activity, Lock } from "@lucide/astro"; +--- + + +
+
+

Infrastructure

+

Technical overview of my homelab stack.

+
+ +
+ +
+
+ +

Virtualization

+
+
    +
  • Proxmox VE - Hypervisor
  • +
  • Multiple VMs and LXC containers
  • +
  • ZFS storage pools
  • +
+
+ + +
+
+ +

Orchestration

+
+
    +
  • Kubernetes - Container orchestration
  • +
  • Docker - Containerization
  • +
  • GitOps deployment workflow
  • +
+
+ + +
+
+ +

PKI & Security

+
+
    +
  • step-ca - Internal Certificate Authority
  • +
  • Automated certificate provisioning
  • +
  • mTLS for service communication
  • +
+
+ + +
+
+ +

DNS

+
+
    +
  • Technitium - DNS Server
  • +
  • Split-horizon DNS
  • +
  • Internal service discovery
  • +
+
+ + +
+
+ +

Monitoring

+
+
    +
  • Grafana - Visualization
  • +
  • Prometheus - Metrics
  • +
  • InfluxDB - Time-series data
  • +
+
+ + +
+
+ +

Access & Auth

+
+
    +
  • Authentik - Identity Provider
  • +
  • OIDC/SAML SSO
  • +
  • Caddy - Reverse proxy
  • +
  • FRP - Tunnel access
  • +
+
+
+ +
+

Architecture Notes

+

+ Everything runs on-premise. Services communicate over an internal network with mTLS. External access goes through authenticated reverse proxy. Monitoring covers infrastructure and application metrics. +

+
+ + +
+
diff --git a/src/pages/work/3dvalentine.astro b/src/pages/work/3dvalentine.astro deleted file mode 100644 index bba54c5..0000000 --- a/src/pages/work/3dvalentine.astro +++ /dev/null @@ -1,64 +0,0 @@ ---- -import { Image } from "astro:assets"; -import PostLayout from "@/layouts/PostLayout.astro"; -import PageHeader from "@/components/elements/PageHeader.astro"; -import ActionBar from "@/components/widgets/ActionBar.astro"; -import SeparatorLine from "@/components/elements/SeparatorLine.astro"; - -const workTitle = "3D Valentines Assets"; -const workDescription = "Design Resources & Tools"; -const workTags = ["3D", "Resources", "Tools"]; - -// 手动导入图片 -import Img01 from "../../assets/work/free-3d-valentines-assets/01.jpg"; -import Img02 from "../../assets/work/free-3d-valentines-assets/02.jpg"; -import Img03 from "../../assets/work/free-3d-valentines-assets/03.jpg"; -import Img04 from "../../assets/work/free-3d-valentines-assets/04.jpg"; -const images = [Img01, Img02, Img03, Img04]; - -import logoUrl from "../../assets/work/free-3d-valentines-assets/logo.png"; ---- - -
-
- - - -
- -
-
-
-
-

- An exquisite collection of 3D Valentine's Day materials, providing creative inspiration for designers and developers. This free 3D resource pack includes various high-quality models and designs that can be used for your Valentine's Day themed projects. -

-

These 3D resources feature modern design styles with rich details and textures. Whether used for website design, application interfaces, social media content, or other creative projects, these resources can help you create unique Valentine's Day experiences.

-

All resources are free to use and suitable for both personal and commercial projects. Feel free to download and use these beautiful 3D Valentine's Day materials in your designs.

-
- - {images.map((img, index) => ( - - {`3D - - ))} -
-
-
-
- -
\ No newline at end of file diff --git a/src/pages/work/freelance.astro b/src/pages/work/freelance.astro new file mode 100644 index 0000000..921ef0d --- /dev/null +++ b/src/pages/work/freelance.astro @@ -0,0 +1,50 @@ +--- +import PostLayout from "@/layouts/PostLayout.astro"; +import PageHeader from "@/components/elements/PageHeader.astro"; +import SeparatorLine from "@/components/elements/SeparatorLine.astro"; +import { siteConfig } from "@/config/site.js"; +--- + +
+
+ + +
+ +
+
+
+
+

Stack

+
    +
  • Backend: Python, Golang
  • +
  • Automation: Bash, scripting
  • +
  • Infrastructure: Docker, Linux
  • +
+ +

Services

+
    +
  • Web application development
  • +
  • Automation and scripting
  • +
  • API development
  • +
  • DevOps and deployment
  • +
+ +

Contact

+

+ Interested in working together? Reach out at {siteConfig.mail} +

+
+
+
+
+
+
diff --git a/src/pages/work/hec-ia.astro b/src/pages/work/hec-ia.astro new file mode 100644 index 0000000..29255be --- /dev/null +++ b/src/pages/work/hec-ia.astro @@ -0,0 +1,46 @@ +--- +import PostLayout from "@/layouts/PostLayout.astro"; +import PageHeader from "@/components/elements/PageHeader.astro"; +import SeparatorLine from "@/components/elements/SeparatorLine.astro"; +--- + +
+
+ + +
+ +
+
+
+
+

Mission

+

+ Making AI accessible to business students. Technical workshops designed for non-technical profiles. +

+ +

What We Do

+
    +
  • Hands-on workshops on AI tools
  • +
  • Introduction to agentic AI
  • +
  • Practical ML workflows
  • +
+ +

Impact

+

+ Bridging the gap between business and tech. Helping future managers understand what's possible with AI. +

+
+
+
+
+
+
diff --git a/src/pages/work/homelab.astro b/src/pages/work/homelab.astro new file mode 100644 index 0000000..f1730e5 --- /dev/null +++ b/src/pages/work/homelab.astro @@ -0,0 +1,57 @@ +--- +import PostLayout from "@/layouts/PostLayout.astro"; +import PageHeader from "@/components/elements/PageHeader.astro"; +import SeparatorLine from "@/components/elements/SeparatorLine.astro"; +import Button from "@/components/ui/Button.astro"; +import { ArrowRight } from "@lucide/astro"; +--- + +
+
+ + +
+ +
+
+
+
+

The Story

+

+ What started as a simple Raspberry Pi running Pi-hole evolved into a full production-grade infrastructure. The goal was to learn by doing: understanding how enterprise systems work by building them myself. +

+ +

Current Stack

+
    +
  • Virtualization: Proxmox VE
  • +
  • Orchestration: Kubernetes
  • +
  • Containers: Docker
  • +
  • Monitoring: Grafana, Prometheus, InfluxDB
  • +
  • Reverse Proxy: Caddy, FRP
  • +
  • Auth: Authentik (OIDC)
  • +
+ +

What I Learned

+

+ Building infrastructure from scratch taught me more than any course could. Debugging network issues at 2am, recovering from failed upgrades, designing for redundancy - these experiences shaped how I approach technical problems. +

+ +
+ +
+
+
+
+
+
+
diff --git a/src/pages/work/luonmodels.astro b/src/pages/work/luonmodels.astro deleted file mode 100644 index b7c8b3f..0000000 --- a/src/pages/work/luonmodels.astro +++ /dev/null @@ -1,59 +0,0 @@ ---- -import { Image } from "astro:assets"; -import PostLayout from "@/layouts/PostLayout.astro"; -import PageHeader from "@/components/elements/PageHeader.astro"; -import ActionBar from "@/components/widgets/ActionBar.astro"; -import SeparatorLine from "@/components/elements/SeparatorLine.astro"; - -//自动导入 Image 组件和图像 -const allImagesModules = import.meta.glob('../../assets/work/luonmodels/*.{jpg,png,webp}', { eager: true }); -const allImages = Object.values(allImagesModules) as Array<{ default: any }>; -const logoUrl = "https://luonmodels.vercel.app/favicon.png"; ---- - -
-
- - - -
- -
-
-
-
-

- LUONModels is a sleek and fluid Astro enterprise template specifically designed for modeling agencies, photographers, and studios. It aims to showcase people, photography, and information clearly and effectively, while also making it convenient to build event pages, content blogs, and various other specialized pages. -

-

Features

-
    -
  • ✅ Responsive Design: Fully optimized for mobile and desktop viewing, ensuring a consistent experience across devices.
  • -
  • ✅ Built with Astro.js: Leverages the powerful features of Astro.js for optimized performance and easy customize.
  • -
  • ✅ Intuitive User Interface: Minimalist layout promotes ease of use, allowing users to find what they need without confusion.
  • -
  • ✅ Speed Optimization: Engineered for exceptional loading times, ensuring that users don’t have to wait on page loads.
  • -
  • ✅ Customizable Components: Flexibility to customize elements easily, aligning with your brand’s identity and needs.
  • -
  • ✅ SEO Friendly: Built with search engine optimization in mind, helping improve visibility and rankings.
  • -
-

🔗🔗 Live Demo

-
- {allImages.map((img, index) => ( - - {`Image - - ))} -
-
-
-
- -
- - diff --git a/src/pages/work/ricoblog2024.astro b/src/pages/work/ricoblog2024.astro deleted file mode 100644 index cd557b7..0000000 --- a/src/pages/work/ricoblog2024.astro +++ /dev/null @@ -1,61 +0,0 @@ ---- -import { Image } from "astro:assets"; -import PostLayout from "@/layouts/PostLayout.astro"; -import PageHeader from "@/components/elements/PageHeader.astro"; -import ActionBar from "@/components/widgets/ActionBar.astro"; -import SeparatorLine from "@/components/elements/SeparatorLine.astro"; - - -// 手动导入图片 -import P_01 from "../../assets/work/ricoblog2024/P_01.jpg"; -import P_02 from "../../assets/work/ricoblog2024/P_02.jpg"; -import P_03 from "../../assets/work/ricoblog2024/P_03.jpg"; -import P_04 from "../../assets/work/ricoblog2024/P_04.jpg"; -import P_05 from "../../assets/work/ricoblog2024/P_05.jpg"; -import P_06 from "../../assets/work/ricoblog2024/P_06.jpg"; -import P_07 from "../../assets/work/ricoblog2024/P_07.jpg"; -const images = [P_01, P_02, P_03, P_04, P_05, P_06, P_07]; - -import logoUrl from "../../assets/work/ricoblog2024/logo.png"; ---- - -
-
- - - -
- -
-
-
-
-

- 我每一年都会计划制作一个人网站,在其中运用自己当时喜欢的技术、热爱的风格和即时的想法。从设计细节中去看到我的审美、思想、设计的看法等一切的动态变化。 这真的十分有趣。 -

-

本次的网站开发,从突然有了想法,确定设计风格、选择技术栈,到整个网站框架大概制作完毕,其实只花了大约一周时间。会不会有人好奇我思考原型和设计稿、开发的过程呢?

-

实际上设计的部分,一页都没有画,想法已经在脑海里了,只是用了 Figma 直接制作需要的元素素材。然后在开发的时候,一边写代码一边调整设计。

-

技术栈选择: Figma + Astro (💡Astro.js 推荐! 设计师也可以很快学会的前端框架!)

-
- {images.map((img, index) => ( - - {`Rico - - ))} - -
-
-
-
- -
- - diff --git a/src/styles/global.css b/src/styles/global.css index b54b4ee..92ff234 100644 --- a/src/styles/global.css +++ b/src/styles/global.css @@ -1,7 +1,27 @@ -/* Import Google Fonts */ -@import url("https://fonts.googleapis.com/css2?family=Instrument+Serif:ital@0;1&display=swap"); -@import url("https://fonts.googleapis.com/css2?family=Inter:ital,opsz,wght@0,14..32,100..900;1,14..32,100..900&display=swap"); +/* Self-hosted fonts */ +@font-face { + font-family: 'Inter'; + font-style: normal; + font-weight: 100 900; + font-display: swap; + src: url('/fonts/Inter-Variable.woff2') format('woff2'); +} +@font-face { + font-family: 'Instrument Serif'; + font-style: normal; + font-weight: 400; + font-display: swap; + src: url('/fonts/InstrumentSerif-Regular.woff2') format('woff2'); +} + +@font-face { + font-family: 'Instrument Serif'; + font-style: italic; + font-weight: 400; + font-display: swap; + src: url('/fonts/InstrumentSerif-Italic.woff2') format('woff2'); +} @import "tailwindcss"; @@ -11,73 +31,73 @@ /* Define theme font mappings */ @theme { - --font-brand: "Instrument Serif", ui-sans-serif, system-ui, Noto Sans SC, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; - --font-sans: "Inter", ui-sans-serif, system-ui, Noto Sans SC, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; - --font-body: "Inter", ui-sans-serif, system-ui, Noto Sans SC, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; + --font-brand: "Instrument Serif", ui-serif, Georgia, serif; + --font-sans: "Inter", ui-sans-serif, system-ui, sans-serif; + --font-body: "Inter", ui-sans-serif, system-ui, sans-serif; --max-screen: 1200px; --inner-screen: 800px; - --color-neutral-50: #f7f9fc; - --color-neutral-100: #edf1f8; - --color-neutral-200: #dfe4ed; - --color-neutral-300: #c5cedb; - --color-neutral-400: #92a1b7; - --color-neutral-500: #677487; - --color-neutral-600: #4f5a6d; - --color-neutral-700: #3f4a5a; - --color-neutral-800: #2c3542; - --color-neutral-900: #19222f; - --color-neutral-950: #10161f; + --color-neutral-50: #f8fafc; + --color-neutral-100: #f1f5f9; + --color-neutral-200: #e2e8f0; + --color-neutral-300: #cbd5e1; + --color-neutral-400: #94a3b8; + --color-neutral-500: #64748b; + --color-neutral-600: #475569; + --color-neutral-700: #334155; + --color-neutral-800: #1e293b; + --color-neutral-900: #0f172a; + --color-neutral-950: #020617; - --color-primary: #2d6dc3; - --color-primary-rgb: 45, 109, 195; - --color-primary-strong: #0066ff; - --color-primary-dark: #2d6dc3; - --color-primary-light: #8fb9ff; - --color-primary-light-dark: #bcd8ff; - --color-primary-lighter: #6da7ff; + /* Violet theme #707BC2 */ + --color-primary: #707BC2; + --color-primary-rgb: 112, 123, 194; + --color-primary-strong: #5B67B3; + --color-primary-dark: #8B94D4; + --color-primary-light: #A5ADE0; + --color-primary-light-dark: #9BA3D8; + --color-primary-lighter: #B8BEE8; /* Article-specific variables */ --color-primary-bg: var(--color-bg-primary-light); --color-primary-bg-light: var(--color-bg-secondary); - --color-btn-primary: #2d6dc3; - --color-btn-primary-hover: #0066ff; - --color-btn-primary-dark: #2871e9; - --color-btn-primary-dark-hover: #2d6dc3; + --color-btn-primary: #707BC2; + --color-btn-primary-hover: #5B67B3; + --color-btn-primary-dark: #8B94D4; + --color-btn-primary-dark-hover: #707BC2; /* Accent colors */ - --color-accent: #fad13b; - --color-accent-light: #faeb75; + --color-accent: #707BC2; + --color-accent-light: #A5ADE0; /* Background colors */ - - --color-bg-primary: #fdfaf5; + --color-bg-primary: #f8fafc; --color-bg-secondary: #fff; - --color-bg-primary-light: #faf9f5; - --color-bg-primary-deep: #fefcf4; + --color-bg-primary-light: #f1f5f9; + --color-bg-primary-deep: #f8fafc; - --color-bg-primary-dark: #0b1220; - --color-bg-secondary-dark: #0f1b2d; + --color-bg-primary-dark: #0f172a; + --color-bg-secondary-dark: #1e293b; /* Text colors */ - --color-text-primary: #2d6dc3; - --color-text-secondary: #3f4a5a; - --color-text-tertiary: #7a6550; + --color-text-primary: #5B67B3; + --color-text-secondary: #475569; + --color-text-tertiary: #64748b; - --color-text-primary-dark: #3884eb; - --color-text-secondary-dark: #c5cedb; - --color-text-tertiary-dark: #9bb3d7; + --color-text-primary-dark: #A5ADE0; + --color-text-secondary-dark: #cbd5e1; + --color-text-tertiary-dark: #94a3b8; } /* Dark mode variable overrides */ html.dark { - --color-primary-rgb: 56, 132, 235; - --color-primary-light-dark: #3884eb; - --color-primary-lighter: #8fb9ff; - --color-primary-bg: rgba(56, 132, 235, 0.15); - --color-primary-bg-light: rgba(56, 132, 235, 0.05); + --color-primary-rgb: 139, 148, 212; + --color-primary-light-dark: #8B94D4; + --color-primary-lighter: #A5ADE0; + --color-primary-bg: rgba(112, 123, 194, 0.15); + --color-primary-bg-light: rgba(112, 123, 194, 0.05); } /* Add typography styles */ @@ -113,13 +133,13 @@ html.dark { padding-right: 1rem; } .gradient-title { - background: linear-gradient(to right, #746aff, #0b046d); + background: linear-gradient(to right, #707BC2, #3d4785); -webkit-background-clip: text; background-clip: text; color: transparent; } .gradient-title-light{ - background: linear-gradient(to right, #bcb7ff, #746aff); + background: linear-gradient(to right, #A5ADE0, #707BC2); -webkit-background-clip: text; background-clip: text; color: transparent;