From b7723b11d93d14d912243f2178462969cdb6cb97 Mon Sep 17 00:00:00 2001 From: ssbg04 Date: Fri, 23 Oct 2026 00:50:38 +0800 Subject: [PATCH] feat: redesign portfolio to bryl-minimal aesthetic and refine mobile/desktop UX - Default theme to system mode with live OS color-scheme detection - Fix custom dot-matrix sprite cursor for light/dark modes - Preserve natural color portraits across all views - Improve mobile hero layout with responsive portrait and Geist Pixel typography - Add subtle color tint to perimeter background dots while keeping reading content clear - Center certificate modal via createPortal and make verify button theme-responsive - Make settings controls (magnifier toggle, lens button, zoom levels) theme-responsive - Remove flagship badge and deep-dive technical sections from TIS-RMS case study --- package-lock.json | 293 ++++++ package.json | 4 + public/fonts/GeistPixel-Square.woff2 | Bin 0 -> 28540 bytes src/components/About.tsx | 551 ++++------- src/components/Certifications.tsx | 100 +- src/components/ContactForm.tsx | 446 ++++----- src/components/ControlsDropdown.tsx | 56 +- src/components/DotMatrixCursor.tsx | 44 +- src/components/Footer.tsx | 211 ++-- src/components/Hero.tsx | 267 ++---- src/components/Navbar.tsx | 256 ++--- src/components/NetworkStatus.tsx | 11 +- src/components/PhotoGallery.tsx | 35 +- src/components/PortfolioAssistantFAB.tsx | 8 +- src/components/Projects.tsx | 556 +++-------- src/components/Skills.tsx | 153 ++- src/components/SpotifyWidget.tsx | 21 +- src/components/Testimonials.tsx | 93 +- src/layouts/Layout.astro | 29 +- src/lib/theme.ts | 4 +- src/pages/404.astro | 41 +- src/pages/about.astro | 6 +- src/pages/contact.astro | 50 +- src/pages/gallery.astro | 4 +- src/pages/links.astro | 51 +- src/pages/maintenance.astro | 63 +- src/pages/projects.astro | 17 +- src/pages/projects/[slug].astro | 308 ++---- src/styles/global.css | 1119 ++++++++-------------- 29 files changed, 1906 insertions(+), 2891 deletions(-) create mode 100644 public/fonts/GeistPixel-Square.woff2 diff --git a/package-lock.json b/package-lock.json index 77164c2..17312b9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15,8 +15,11 @@ "@emnapi/core": "^1.11.3", "@emnapi/runtime": "^1.11.3", "@emnapi/wasi-threads": "^2.2.0", + "@fontsource-variable/geist": "^5.3.0", + "@fontsource-variable/geist-mono": "^5.3.0", "@fontsource-variable/inter": "^5.3.0", "@fontsource-variable/jetbrains-mono": "^5.3.0", + "@fontsource-variable/source-serif-4": "^5.3.1", "@fontsource/dotgothic16": "^5.3.1", "@fortawesome/fontawesome-free": "^7.3.1", "@fortawesome/fontawesome-svg-core": "^7.3.1", @@ -30,6 +33,7 @@ "@types/react-dom": "^19.2.3", "astro": "^7.0.6", "framer-motion": "^12.42.2", + "geist": "^1.8.2", "ogl": "^1.0.11", "react": "^19.2.7", "react-dom": "^19.2.7", @@ -1515,6 +1519,24 @@ "node": ">=18" } }, + "node_modules/@fontsource-variable/geist": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/@fontsource-variable/geist/-/geist-5.3.0.tgz", + "integrity": "sha512-j0m+vLQuG5XAYoHtGCVu0spvlGreR3EzpECUVzkFmI1mTVnAO38l/NEPDCFgZ177JxzYJCLSmTQibIiYPilGrA==", + "license": "OFL-1.1", + "funding": { + "url": "https://github.com/sponsors/ayuhito" + } + }, + "node_modules/@fontsource-variable/geist-mono": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/@fontsource-variable/geist-mono/-/geist-mono-5.3.0.tgz", + "integrity": "sha512-vBbuwDEo9AkrqADMXOrlAR3DFcJi4/JxeuU43FoiQERnNwsfXNnvxvReZG02cQKmyk4DZkZdBZX3oTDvy2zBAw==", + "license": "OFL-1.1", + "funding": { + "url": "https://github.com/sponsors/ayuhito" + } + }, "node_modules/@fontsource-variable/inter": { "version": "5.3.0", "resolved": "https://registry.npmjs.org/@fontsource-variable/inter/-/inter-5.3.0.tgz", @@ -1533,6 +1555,15 @@ "url": "https://github.com/sponsors/ayuhito" } }, + "node_modules/@fontsource-variable/source-serif-4": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/@fontsource-variable/source-serif-4/-/source-serif-4-5.3.1.tgz", + "integrity": "sha512-4Rtay22SC4lMvw11r/+9kxANB6P3M0X8s1NudBC2v0J1KU2y3DcMoNcT3lBoZ/CqLirzf+StlO6UlJilyrvaUg==", + "license": "OFL-1.1", + "funding": { + "url": "https://github.com/sponsors/ayuhito" + } + }, "node_modules/@fontsource/dotgothic16": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/@fontsource/dotgothic16/-/dotgothic16-5.3.1.tgz", @@ -2176,6 +2207,140 @@ "@emnapi/runtime": "^1.7.1 || ^2.0.0-alpha.4" } }, + "node_modules/@next/env": { + "version": "16.4.2", + "resolved": "https://registry.npmjs.org/@next/env/-/env-16.4.2.tgz", + "integrity": "sha512-nTUTFH7G5/J/fmpkjVLegOkqyKOP0CEsJcMsyO4UCYeN1su+YMW/MfaSErnJskL7XM+UDK6aTvslxsRCyya/sA==", + "license": "MIT" + }, + "node_modules/@next/swc-darwin-arm64": { + "version": "16.4.2", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-16.4.2.tgz", + "integrity": "sha512-ONkhFvZNFWlsEHOM/81AtxdyuJP2KRYKYR0JxPwvcu1AuPMMMgcL+wW2luldJvMtZwKtUxoSkCychW5wIeoYSw==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-darwin-x64": { + "version": "16.4.2", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-16.4.2.tgz", + "integrity": "sha512-luPCMbOsCoaF+kXJEUjmjmOZg1lC3BflhmUu+ZmW4tBu2vW/4AXak8JBFvePizGkxVmNiAw/r9ra+6UviCWtWQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-arm64-gnu": { + "version": "16.4.2", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-16.4.2.tgz", + "integrity": "sha512-xhwFTAncJyaCNy5KqKKuKaIIdCy1/1ZV1s5S1G0hhT7wGMkDTlfJ6aQbfRFnIG/s3/kDrxQ8aycVe+c5QnP8ow==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-arm64-musl": { + "version": "16.4.2", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-16.4.2.tgz", + "integrity": "sha512-T1PNmfbPcxr5ndtWUL/3wQtLXsz808lq6sc2GrNT5k2oquF7UyqZddHSuAewHVsWsGXe6nsl9HoN1YNriVjuSg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-x64-gnu": { + "version": "16.4.2", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-16.4.2.tgz", + "integrity": "sha512-N9cDUOCGtkJG5PNKDFZUF3xXndrJJcpLp121uAGjIGvO/U2p9tfdNOM9htj7+5f72l0m8rMw/cvYacUJBQoudg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-x64-musl": { + "version": "16.4.2", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-16.4.2.tgz", + "integrity": "sha512-yY2uh1YhX6ufuYy2FCbw1dqblbhI57GLYAJfCkqD9auTv6pLrH67Uccjc3QMKBeCYAG6lkgu08ExmX1bbjejjQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-win32-arm64-msvc": { + "version": "16.4.2", + "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-16.4.2.tgz", + "integrity": "sha512-j/ArWRIHpMMB6wYLMhr2puTguBt70lNU/Cmjl9p6dTDE8DGknYJMP9PdwPk2dqpCNL/KIX9yfngDvIesxJPmsg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-win32-x64-msvc": { + "version": "16.4.2", + "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-16.4.2.tgz", + "integrity": "sha512-AA4edyWHDko3NCSo0x6GomsdgFb0oR1J3MXU1b5xt6FRFg4AucrMPW3S0hCe/9onU0O1BbpGQBsqo1r0Gneu1g==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, "node_modules/@noble/ed25519": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/@noble/ed25519/-/ed25519-3.1.0.tgz", @@ -2657,6 +2822,15 @@ "integrity": "sha512-1bnPQqSxSuc3Ii6MhBysoWCg58j97aUjuCSZrGSmDxNqtytIi0k8utUenAwTZN4V5mXXYGsVUI9zeBqy+jBOSQ==", "license": "MIT" }, + "node_modules/@swc/helpers": { + "version": "0.5.23", + "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.23.tgz", + "integrity": "sha512-5lSsMOTXURePglDfvuAQUqkGek9Hg2kksOYay2m0+XR++b2NWYL/4sWyuvVBIs8oKnJaxkdi9whaL/sqN13afw==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.8.0" + } + }, "node_modules/@tailwindcss/node": { "version": "4.3.2", "resolved": "https://registry.npmjs.org/@tailwindcss/node/-/node-4.3.2.tgz", @@ -3482,6 +3656,12 @@ "node": ">=8" } }, + "node_modules/client-only": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz", + "integrity": "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==", + "license": "MIT" + }, "node_modules/clsx": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", @@ -4082,6 +4262,15 @@ "node": "^8.16.0 || ^10.6.0 || >=11.0.0" } }, + "node_modules/geist": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/geist/-/geist-1.8.2.tgz", + "integrity": "sha512-fRF4sbJ9qcCxPb35cVtKBAwYlTt1IbU9nkbPi0a+xyZqPIjCJ2BY8ekGhx6/SGSZKrR7/UuL57r/eeDQ1Xy11g==", + "license": "SIL OPEN FONT LICENSE", + "peerDependencies": { + "next": ">=13.2.0" + } + }, "node_modules/gensync": { "version": "1.0.0-beta.2", "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", @@ -4863,6 +5052,87 @@ "node": ">= 10" } }, + "node_modules/next": { + "version": "16.4.2", + "resolved": "https://registry.npmjs.org/next/-/next-16.4.2.tgz", + "integrity": "sha512-r+oBJojfefUjOiWkBhXgLS+igxX/7BWyK59uHnyOyplMSLtBZ+QLP3okrdYTbrfrbrmNTVWLBPaHDX9KRaIt3w==", + "license": "MIT", + "dependencies": { + "@next/env": "16.4.2", + "@swc/helpers": "0.5.23", + "baseline-browser-mapping": "^2.9.19", + "caniuse-lite": "^1.0.30001579", + "postcss": "8.5.23", + "styled-jsx": "5.1.6" + }, + "bin": { + "next": "dist/bin/next" + }, + "engines": { + "node": ">=20.9.0" + }, + "optionalDependencies": { + "@next/swc-darwin-arm64": "16.4.2", + "@next/swc-darwin-x64": "16.4.2", + "@next/swc-linux-arm64-gnu": "16.4.2", + "@next/swc-linux-arm64-musl": "16.4.2", + "@next/swc-linux-x64-gnu": "16.4.2", + "@next/swc-linux-x64-musl": "16.4.2", + "@next/swc-win32-arm64-msvc": "16.4.2", + "@next/swc-win32-x64-msvc": "16.4.2", + "sharp": "^0.35.5" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.1.0", + "@playwright/test": "^1.51.1", + "babel-plugin-react-compiler": "*", + "react": "^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0", + "react-dom": "^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0", + "sass": "^1.3.0" + }, + "peerDependenciesMeta": { + "@opentelemetry/api": { + "optional": true + }, + "@playwright/test": { + "optional": true + }, + "babel-plugin-react-compiler": { + "optional": true + }, + "sass": { + "optional": true + } + } + }, + "node_modules/next/node_modules/postcss": { + "version": "8.5.23", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.23.tgz", + "integrity": "sha512-g50586zr4bZmwFiTlflMu8E0bDTb5I5gertgwAKmsdUlTQIhZtunzUlD1WSzwcVWPoAVpsrA6vlfCD7oXvRwgg==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.16", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, "node_modules/nlcst-to-string": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/nlcst-to-string/-/nlcst-to-string-4.0.0.tgz", @@ -5593,6 +5863,29 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/styled-jsx": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/styled-jsx/-/styled-jsx-5.1.6.tgz", + "integrity": "sha512-qSVyDTeMotdvQYoHWLNGwRFJHC+i+ZvdBRYosOFgC+Wg1vx4frN2/RG/NA7SYqqvKNLf39P2LSRA2pu6n0XYZA==", + "license": "MIT", + "dependencies": { + "client-only": "0.0.1" + }, + "engines": { + "node": ">= 12.0.0" + }, + "peerDependencies": { + "react": ">= 16.8.0 || 17.x.x || ^18.0.0-0 || ^19.0.0-0" + }, + "peerDependenciesMeta": { + "@babel/core": { + "optional": true + }, + "babel-plugin-macros": { + "optional": true + } + } + }, "node_modules/supports-color": { "version": "10.2.2", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-10.2.2.tgz", diff --git a/package.json b/package.json index 8c6d966..5f40d94 100644 --- a/package.json +++ b/package.json @@ -19,8 +19,11 @@ "@emnapi/core": "^1.11.3", "@emnapi/runtime": "^1.11.3", "@emnapi/wasi-threads": "^2.2.0", + "@fontsource-variable/geist": "^5.3.0", + "@fontsource-variable/geist-mono": "^5.3.0", "@fontsource-variable/inter": "^5.3.0", "@fontsource-variable/jetbrains-mono": "^5.3.0", + "@fontsource-variable/source-serif-4": "^5.3.1", "@fontsource/dotgothic16": "^5.3.1", "@fortawesome/fontawesome-free": "^7.3.1", "@fortawesome/fontawesome-svg-core": "^7.3.1", @@ -34,6 +37,7 @@ "@types/react-dom": "^19.2.3", "astro": "^7.0.6", "framer-motion": "^12.42.2", + "geist": "^1.8.2", "ogl": "^1.0.11", "react": "^19.2.7", "react-dom": "^19.2.7", diff --git a/public/fonts/GeistPixel-Square.woff2 b/public/fonts/GeistPixel-Square.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..02cd121c51af45ed4873e6996477a9b25a46f0cc GIT binary patch literal 28540 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 H-$JbhyR_Y( literal 0 HcmV?d00001 diff --git a/src/components/About.tsx b/src/components/About.tsx index 4567d77..68c0284 100644 --- a/src/components/About.tsx +++ b/src/components/About.tsx @@ -1,10 +1,8 @@ import React, { useState, useEffect } from 'react'; import { createPortal } from 'react-dom'; import type { Education, Experience, SiteSettings } from '../lib/data'; -import ScrollReveal from './ScrollReveal'; import GithubContributions from './GithubContributions'; import LocalTimeWeather from './LocalTimeWeather'; -import SectionBackground from './SectionBackground'; interface AboutProps { settings: SiteSettings; @@ -20,7 +18,7 @@ export default function About({ settings, experience, education = [], - sectionTag = 'Profile & Background', + sectionTag = '04 — background', githubUsername = 'ssbg04', isPage = false, isCompact = false @@ -63,7 +61,6 @@ export default function About({ }; }, [isPreviewOpen]); - // Robust File Download (supports Sanity CDN ?dl= attachment and local files) const handleDownload = async (e?: React.MouseEvent) => { if (e) { e.preventDefault(); @@ -92,7 +89,6 @@ export default function About({ document.body.removeChild(link); setTimeout(() => window.URL.revokeObjectURL(blobUrl), 2000); } catch (err) { - console.warn('Direct blob download failed, falling back to direct anchor:', err); let fallbackUrl = resumeUrl; if (fallbackUrl.includes('cdn.sanity.io')) { const sep = fallbackUrl.includes('?') ? '&' : '?'; @@ -112,411 +108,260 @@ export default function About({ }; return ( -
- -
+
+
{/* Section Header */} - -
-
- {isPage ? ( -

- About & Background -

- ) : ( -

- About & Background -

- )} -
-
-
+
+ + {sectionTag.toLowerCase()} + +

+ experience & background +

+
- {/* Bento Grid: Only Sanity Studio managed content */} -
+ {/* Narrative & Detail Cards */} +
- {/* Bento Cell 1: Biography & Narrative (8 cols) */} -
- -
-
-
-
- - Biography - -
- {settings.isAvailable !== false && ( - - - {settings.availabilityStatus || 'Open to Opportunities'} - - )} -
- -

- {settings.fullName} -

- - {paragraphs.length > 0 && ( -
- {paragraphs.map((p, i) => ( -

{p}

- ))} -
+ {/* Biography Block */} +
+
+
+
+ + engineering biography + + {settings.isAvailable !== false && ( + + ● active + )}
- {/* Footer Metadata */} -
- - Role: {settings.title} - - - {settings.location} - +
+ {paragraphs.map((p, i) => ( +

{p}

+ ))}
- + +
+ {settings.title} + {settings.location} +
+
- {/* Bento Cell 2: Identity & Verified Documents Hub (4 cols) */} -
- -
-
-
-
- {settings.fullName} -
-
-

- {settings.fullName} -

-

- {settings.title} -

-
+ {/* Quick Info & Document Card */} +
+
+
+
+
+ {settings.fullName}
- - {/* Fact Matrix */} -
-
- Location - {settings.location} -
- - - - - - {settings.availabilityStatus && ( -
- Status - - {settings.availabilityStatus} - -
- )} +
+

+ {settings.fullName.toLowerCase()} +

+

+ laguna, ph +

- {/* CV Action Buttons */} -
- - Curriculum Vitae - -
- +
+
+ Location + {settings.location} +
- + + +
- + + {/* CV Action */} +
+ + curriculum vitae + +
+ + +
+
+
- {/* Bento Cell 3: Experience (dynamically spans depending on presence of Education) */} + {/* Work Experience Timeline */} {!isCompact && hasExperience && ( -
- -
-
-
-
- - - - - -

- Work Experience -

-
- - {experience.length} {experience.length === 1 ? 'Role' : 'Roles'} - -
+
+
+
+ + professional experience + + + {experience.length} roles + +
- {experience.map((exp, idx) => ( -
0 ? "pt-5 mt-5 border-t border-border-custom" : ""}> -
-
-
- {exp.role} -
-

- {exp.company} {exp.employmentType ? `• ${exp.employmentType}` : ''} {exp.location ? `(${exp.location})` : ''} -

-
- - - {exp.startDate} — {exp.endDate} - +
+ {experience.map((exp, idx) => ( +
0 ? "pt-6 border-t border-border-custom" : ""}> +
+
+

+ {exp.role} +

+

+ {exp.company} {exp.employmentType ? `· ${exp.employmentType}` : ''} {exp.location ? `· ${exp.location}` : ''} +

- {exp.description && exp.description.length > 0 && ( -
    - {exp.description.map((bullet, bIdx) => ( -
  • {bullet}
  • - ))} -
- )} - - {exp.technologies && exp.technologies.length > 0 && ( -
- {exp.technologies.map((t) => ( - - {t} - - ))} -
- )} + + {exp.startDate} — {exp.endDate} +
- ))} -
+ + {exp.description && exp.description.length > 0 && ( +
    + {exp.description.map((bullet, bIdx) => ( +
  • {bullet}
  • + ))} +
+ )} + + {exp.technologies && exp.technologies.length > 0 && ( +
+ {exp.technologies.map((t) => ( + + {t} + + ))} +
+ )} +
+ ))}
- +
)} - {/* Bento Cell 4: Education (dynamically spans depending on presence of Experience) */} + {/* Education Block */} {!isCompact && hasEducation && ( -
- -
-
-
-
- - - - - -

- Education & Academics -

-
- - {education.length} {education.length === 1 ? 'Degree' : 'Degrees'} - -
+
+
+
+ + education & academic history + + + {education.length} credentials + +
- {education.map((edu, idx) => ( -
0 ? "pt-5 mt-5 border-t border-border-custom" : ""}> -
-
-
- {edu.degree} -
-

- {edu.fieldOfStudy ? `${edu.fieldOfStudy} • ` : ''}{edu.institution} -

-
- - - {edu.startDate} — {edu.endDate} - +
+ {education.map((edu, idx) => ( +
0 ? "pt-6 border-t border-border-custom" : ""}> +
+
+

+ {edu.degree} +

+

+ {edu.fieldOfStudy ? `${edu.fieldOfStudy} · ` : ''}{edu.institution} +

- {edu.achievements && edu.achievements.length > 0 && ( -
    - {edu.achievements.map((item, aIdx) => ( -
  • {item}
  • - ))} -
- )} - - {edu.location && ( -
- - - - - {edu.location} -
- )} + + {edu.startDate} — {edu.endDate} +
- ))} -
+ + {edu.achievements && edu.achievements.length > 0 && ( +
    + {edu.achievements.map((item, aIdx) => ( +
  • {item}
  • + ))} +
+ )} +
+ ))}
- +
)} - {/* Bento Cell 5: GitHub Contributions Activity Graph (12 cols) */} -
- + {/* GitHub Contributions Graph */} + {githubUsername && ( +
- -
- - {/* Compact Dashboard Action to Explore Full Timeline */} - {isCompact && ( - )}
-
- {/* Simple CV Preview Modal */} + {/* CV Preview Modal (bryl-minimal spec: 16px radius, hairline border, escape closes) */} {mounted && isPreviewOpen && createPortal(
setIsPreviewOpen(false)} role="dialog" aria-modal="true" - aria-label="Curriculum Vitae Preview" + aria-label="CV Preview" + className="fixed inset-0 z-50 flex items-center justify-center p-4 bg-black/40 backdrop-blur-sm" + onClick={() => setIsPreviewOpen(false)} >
e.stopPropagation()} > - {/* Modal Header */} -
-
- - - - - -
-

- Curriculum Vitae -

-

- {settings.fullName} -

-
-
- - {/* Actions: Download & Close */} -
- - - -
+
+ + curriculum vitae preview + +
- {/* Modal Body: PDF Preview */} -
+