mirror of
https://github.com/mmahdium/portfolio.git
synced 2026-08-17 05:24:30 +03:30
feat(resume): enhance styling and improve visual hierarchy across components
- Update section spacing from mb-6 to mb-8 for better visual separation - Enhance heading styles with text-blue-700, increased padding (pb-1.5), and letter-spacing - Improve typography hierarchy by changing font-semibold to font-bold for titles - Increase spacing between list items and skill categories for better readability - Add font-medium styling to dates and institution names for improved emphasis - Enhance bullet point styling with explicit color and font-weight in experience highlights - Reorganize ResumeHeader contact section with improved link styling and layout - Promote Portfolio website link with bold styling and blue color for better visibility - Adjust print-specific spacing to maintain consistency across screen and print layouts - Update resume data with refined content structure - Archive outdated resume content technical specification document
This commit is contained in:
@@ -9,17 +9,18 @@ const props = defineProps<Props>()
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<section class="mb-6 print:mb-4">
|
<section class="mb-8 print:mb-5">
|
||||||
<h2 class="text-base font-bold text-blue-600 uppercase border-b-2 border-blue-600 pb-1 mb-3">
|
<h2
|
||||||
|
class="text-base font-bold text-blue-700 uppercase border-b-2 border-blue-600 pb-1.5 mb-4 print:mb-2.5 tracking-wide">
|
||||||
Skills & Qualifications
|
Skills & Qualifications
|
||||||
</h2>
|
</h2>
|
||||||
|
|
||||||
<!-- Technical Skills (categorized) -->
|
<!-- Technical Skills (categorized) -->
|
||||||
<div v-if="skills?.length">
|
<div v-if="skills?.length">
|
||||||
<div class="space-y-0.5">
|
<div class="space-y-2">
|
||||||
<div v-for="skill in skills" :key="skill.name" class="text-sm">
|
<div v-for="skill in skills" :key="skill.name" class="text-sm">
|
||||||
<span class="font-medium text-gray-800">{{ skill.name }}:</span>
|
<span class="font-bold text-gray-900">{{ skill.name }}: </span><span class="text-gray-700">{{
|
||||||
<span class="text-gray-700"> {{ skill.keywords.join(', ') }}</span>
|
skill.keywords.join(', ') }}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -16,18 +16,19 @@ function formatDateRange(start: string, end?: string): string {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<section class="mb-6 print:mb-4">
|
<section class="mb-8 print:mb-5">
|
||||||
<h2 class="text-base font-bold text-blue-600 uppercase border-b-2 border-blue-600 pb-1 mb-3">
|
<h2
|
||||||
|
class="text-base font-bold text-blue-700 uppercase border-b-2 border-blue-600 pb-1.5 mb-4 print:mb-2.5 tracking-wide">
|
||||||
Education
|
Education
|
||||||
</h2>
|
</h2>
|
||||||
|
|
||||||
<div v-for="edu in education" :key="edu.institution + edu.startDate" class="mb-3 last:mb-0">
|
<div v-for="edu in education" :key="edu.institution + edu.startDate" class="mb-4 last:mb-0">
|
||||||
<div class="flex justify-between items-start">
|
<div class="flex justify-between items-start">
|
||||||
<div>
|
<div>
|
||||||
<h3 class="text-sm font-semibold text-gray-800">{{ edu.studyType }} in {{ edu.area }}</h3>
|
<h3 class="text-sm font-bold text-gray-900">{{ edu.studyType }} in {{ edu.area }}</h3>
|
||||||
<p class="text-sm text-gray-600">{{ edu.institution }}</p>
|
<p class="text-sm font-medium text-gray-600">{{ edu.institution }}</p>
|
||||||
</div>
|
</div>
|
||||||
<span class="text-sm text-gray-500 whitespace-nowrap">
|
<span class="text-sm text-gray-500 whitespace-nowrap font-medium">
|
||||||
{{ formatDateRange(edu.startDate, edu.endDate) }}
|
{{ formatDateRange(edu.startDate, edu.endDate) }}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -24,24 +24,25 @@ function formatDateRange(start: string, end?: string): string {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<section class="mb-6 print:mb-3">
|
<section class="mb-8 print:mb-5">
|
||||||
<h2 class="text-base font-bold text-blue-600 uppercase border-b-2 border-blue-600 pb-1 mb-2 print:mb-1.5">
|
<h2
|
||||||
|
class="text-base font-bold text-blue-700 uppercase border-b-2 border-blue-600 pb-1.5 mb-4 print:mb-2.5 tracking-wide">
|
||||||
Work Experience
|
Work Experience
|
||||||
</h2>
|
</h2>
|
||||||
|
|
||||||
<div v-for="job in sortedWork" :key="job.company + job.startDate" class="mb-4 last:mb-0 print:mb-3">
|
<div v-for="job in sortedWork" :key="job.company + job.startDate" class="mb-5 last:mb-0 print:mb-4">
|
||||||
<div class="flex justify-between items-start gap-4">
|
<div class="flex justify-between items-start gap-4">
|
||||||
<div class="flex-1 min-w-0">
|
<div class="flex-1 min-w-0">
|
||||||
<h3 class="text-sm font-semibold text-gray-800 break-words hyphens-none">{{ job.position }}</h3>
|
<h3 class="text-sm font-bold text-gray-900 break-words hyphens-none">{{ job.position }}</h3>
|
||||||
<p class="text-sm text-gray-600">{{ job.company }}</p>
|
<p class="text-sm font-medium text-gray-600">{{ job.company }}</p>
|
||||||
</div>
|
</div>
|
||||||
<span class="text-sm text-gray-500 whitespace-nowrap flex-shrink-0">
|
<span class="text-sm text-gray-500 whitespace-nowrap flex-shrink-0 font-medium">
|
||||||
{{ formatDateRange(job.startDate, job.endDate) }}
|
{{ formatDateRange(job.startDate, job.endDate) }}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<ul class="mt-2 space-y-1 print:mt-1 print:space-y-0.5">
|
<ul class="mt-2.5 space-y-1.5 print:mt-1.5 print:space-y-1">
|
||||||
<li v-for="(highlight, idx) in job.highlights" :key="idx"
|
<li v-for="(highlight, idx) in job.highlights" :key="idx"
|
||||||
class="text-sm text-gray-700 pl-4 relative before:content-['•'] before:absolute before:left-0 break-words hyphens-none">
|
class="text-sm text-gray-700 pl-4 relative before:content-['•'] before:absolute before:left-0 before:text-gray-500 before:font-bold print:before:text-gray-500 break-words hyphens-none">
|
||||||
{{ highlight }}
|
{{ highlight }}
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ defineProps<Props>()
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="flex gap-6 mb-6 print:mb-2 print:pb-0">
|
<div class="flex gap-6 mb-8 print:mb-4 print:pb-1">
|
||||||
<!-- Profile Photo (if provided) -->
|
<!-- Profile Photo (if provided) -->
|
||||||
<div v-if="basics.image" class="flex-shrink-0">
|
<div v-if="basics.image" class="flex-shrink-0">
|
||||||
<img :src="basics.image" :alt="basics.name" class="w-32 h-32 object-cover rounded-full print:w-24 print:h-24" />
|
<img :src="basics.image" :alt="basics.name" class="w-32 h-32 object-cover rounded-full print:w-24 print:h-24" />
|
||||||
@@ -20,7 +20,7 @@ defineProps<Props>()
|
|||||||
<h1 class="text-3xl font-bold text-gray-900 print:text-xl print:mb-0.5">{{ basics.name }}</h1>
|
<h1 class="text-3xl font-bold text-gray-900 print:text-xl print:mb-0.5">{{ basics.name }}</h1>
|
||||||
<p class="text-xl text-gray-600 mt-1 print:text-base print:mt-0">{{ basics.label }}</p>
|
<p class="text-xl text-gray-600 mt-1 print:text-base print:mt-0">{{ basics.label }}</p>
|
||||||
|
|
||||||
<div class="mt-3 flex flex-wrap gap-x-4 gap-y-1.5 text-sm text-gray-700 print:mt-1.5 print:text-xs print:gap-x-3">
|
<div class="mt-3 flex flex-wrap gap-x-5 gap-y-2 text-sm text-gray-700 print:mt-2 print:text-xs print:gap-x-4">
|
||||||
<!-- Location -->
|
<!-- Location -->
|
||||||
<span class="inline-flex items-center gap-1.5">
|
<span class="inline-flex items-center gap-1.5">
|
||||||
<UIcon name="i-heroicons-map-pin" class="text-gray-500 flex-shrink-0" />
|
<UIcon name="i-heroicons-map-pin" class="text-gray-500 flex-shrink-0" />
|
||||||
@@ -34,12 +34,19 @@ defineProps<Props>()
|
|||||||
</a>
|
</a>
|
||||||
|
|
||||||
<!-- Email -->
|
<!-- Email -->
|
||||||
<span class="inline-flex items-center gap-1.5">
|
<a :href="`mailto:${basics.email}`"
|
||||||
|
class="inline-flex items-center gap-1.5 hover:text-blue-600 transition-colors">
|
||||||
<UIcon name="i-heroicons-envelope" class="text-gray-500 flex-shrink-0" />
|
<UIcon name="i-heroicons-envelope" class="text-gray-500 flex-shrink-0" />
|
||||||
<a :href="`mailto:${basics.email}`" class="hover:text-blue-600 transition-colors">
|
|
||||||
{{ basics.email }}
|
{{ basics.email }}
|
||||||
</a>
|
</a>
|
||||||
</span>
|
|
||||||
|
<!-- Website (Portfolio) - Bold & Colored -->
|
||||||
|
<a v-if="basics.profiles?.find(p => p.network === 'Portfolio')"
|
||||||
|
:href="basics.profiles.find(p => p.network === 'Portfolio')!.url" target="_blank"
|
||||||
|
class="inline-flex items-center gap-1.5 font-semibold text-blue-600 hover:text-blue-700 transition-colors print:text-blue-600">
|
||||||
|
<UIcon name="i-heroicons-globe-alt" class="text-blue-600 flex-shrink-0" />
|
||||||
|
Website
|
||||||
|
</a>
|
||||||
|
|
||||||
<!-- LinkedIn -->
|
<!-- LinkedIn -->
|
||||||
<a v-if="basics.profiles?.find(p => p.network === 'LinkedIn')"
|
<a v-if="basics.profiles?.find(p => p.network === 'LinkedIn')"
|
||||||
@@ -49,14 +56,6 @@ defineProps<Props>()
|
|||||||
LinkedIn
|
LinkedIn
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
<!-- Website (Portfolio) -->
|
|
||||||
<a v-if="basics.profiles?.find(p => p.network === 'Portfolio')"
|
|
||||||
:href="basics.profiles.find(p => p.network === 'Portfolio')!.url" target="_blank"
|
|
||||||
class="inline-flex items-center gap-1.5 hover:text-blue-600 transition-colors">
|
|
||||||
<UIcon name="i-heroicons-globe-alt" class="text-gray-500 flex-shrink-0" />
|
|
||||||
Website
|
|
||||||
</a>
|
|
||||||
|
|
||||||
<!-- GitHub -->
|
<!-- GitHub -->
|
||||||
<a v-if="basics.profiles?.find(p => p.network === 'GitHub')"
|
<a v-if="basics.profiles?.find(p => p.network === 'GitHub')"
|
||||||
:href="basics.profiles.find(p => p.network === 'GitHub')!.url" target="_blank"
|
:href="basics.profiles.find(p => p.network === 'GitHub')!.url" target="_blank"
|
||||||
|
|||||||
@@ -10,14 +10,15 @@ const props = defineProps<Props>()
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<section class="mb-6 print:mb-4">
|
<section class="mb-8 print:mb-5">
|
||||||
<h2 class="text-base font-bold text-blue-600 uppercase border-b-2 border-blue-600 pb-1 mb-3">
|
<h2
|
||||||
|
class="text-base font-bold text-blue-700 uppercase border-b-2 border-blue-600 pb-1.5 mb-4 print:mb-2.5 tracking-wide">
|
||||||
Languages & Certifications
|
Languages & Certifications
|
||||||
</h2>
|
</h2>
|
||||||
|
|
||||||
<!-- Languages -->
|
<!-- Languages -->
|
||||||
<div v-if="languages?.length" class="mb-2">
|
<div v-if="languages?.length" class="mb-3">
|
||||||
<span class="text-sm font-semibold text-gray-800">Languages: </span>
|
<span class="text-sm font-bold text-gray-900">Languages: </span>
|
||||||
<span class="text-sm text-gray-700">
|
<span class="text-sm text-gray-700">
|
||||||
<template v-for="(lang, idx) in languages" :key="lang.language">
|
<template v-for="(lang, idx) in languages" :key="lang.language">
|
||||||
{{ lang.language }} ({{ lang.fluency }})<template v-if="idx < languages.length - 1">, </template>
|
{{ lang.language }} ({{ lang.fluency }})<template v-if="idx < languages.length - 1">, </template>
|
||||||
@@ -27,7 +28,7 @@ const props = defineProps<Props>()
|
|||||||
|
|
||||||
<!-- Certifications -->
|
<!-- Certifications -->
|
||||||
<div v-if="certifications?.length">
|
<div v-if="certifications?.length">
|
||||||
<span class="text-sm font-semibold text-gray-800">Certifications: </span>
|
<span class="text-sm font-bold text-gray-900">Certifications: </span>
|
||||||
<span class="text-sm text-gray-700">
|
<span class="text-sm text-gray-700">
|
||||||
<template v-for="(cert, idx) in certifications" :key="cert.name">
|
<template v-for="(cert, idx) in certifications" :key="cert.name">
|
||||||
{{ cert.issuer }} - {{ cert.summary }}<template v-if="idx < certifications.length - 1">, </template>
|
{{ cert.issuer }} - {{ cert.summary }}<template v-if="idx < certifications.length - 1">, </template>
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ const { resume } = useResumeData()
|
|||||||
.resume-content {
|
.resume-content {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
padding: 1.5rem !important;
|
padding: 2rem !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
@media print {
|
@media print {
|
||||||
@@ -68,7 +68,7 @@ const { resume } = useResumeData()
|
|||||||
}
|
}
|
||||||
|
|
||||||
.resume-content {
|
.resume-content {
|
||||||
padding: 0.75rem !important;
|
padding: 1rem !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
* {
|
* {
|
||||||
|
|||||||
@@ -7,8 +7,9 @@ defineProps<Props>()
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<section class="mb-6 print:mb-3">
|
<section class="mb-8 print:mb-5">
|
||||||
<h2 class="text-base font-bold text-blue-600 uppercase border-b-2 border-blue-600 pb-1 mb-2 print:mb-1.5">
|
<h2
|
||||||
|
class="text-base font-bold text-blue-700 uppercase border-b-2 border-blue-600 pb-1.5 mb-3 print:mb-2 tracking-wide">
|
||||||
Summary
|
Summary
|
||||||
</h2>
|
</h2>
|
||||||
<p class="text-sm text-gray-800 leading-relaxed print:leading-normal">{{ summary }}</p>
|
<p class="text-sm text-gray-800 leading-relaxed print:leading-normal">{{ summary }}</p>
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ export const resumeData: Resume = {
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
summary:
|
summary:
|
||||||
'Frontend Developer with 3+ years building high-performance Vue.js/Nuxt applications for international clients. AI-first engineer leveraging Cursor, GitHub Copilot, and AI-powered tools & methodologies to accelerate development by up to 50% while maintaining code quality. Specialized in performance optimization, scalable architecture (SSR, PWA, RBAC), and accessibility. Delivered 6+ production applications with focus on maintainability and distributed team collaboration. Fluent in English (6+ years in fully English-speaking environment at Huawei).',
|
'Frontend Developer with 3+ years building high-performance Vue.js/Nuxt applications for international clients. AI-first engineer leveraging Cursor, GitHub Copilot, and AI-powered tools & methodologies to accelerate development by up to 50% while maintaining code quality. Specialized in performance optimization, scalable architecture (SSR, PWA, RBAC), and accessibility. Delivered 4+ production applications with focus on maintainability and distributed team collaboration. Fluent in English (6+ years in fully English-speaking environment at Huawei).',
|
||||||
},
|
},
|
||||||
|
|
||||||
work: [
|
work: [
|
||||||
@@ -67,7 +67,7 @@ export const resumeData: Resume = {
|
|||||||
startDate: '2023-09',
|
startDate: '2023-09',
|
||||||
endDate: '2024-12',
|
endDate: '2024-12',
|
||||||
highlights: [
|
highlights: [
|
||||||
'Delivered 6+ production-grade web applications for international clients using Vue.js/Nuxt.js, consistently achieving strong performance metrics and high client satisfaction',
|
'Delivered 4+ production-grade web applications for international clients using Vue.js/Nuxt.js, consistently achieving strong performance metrics and high client satisfaction',
|
||||||
'Leveraged AI development tools (Cursor and Github Copilot) to reduce development time by at least 40% across 6 projects, enabling faster client delivery and 100% on-time project completion rate',
|
'Leveraged AI development tools (Cursor and Github Copilot) to reduce development time by at least 40% across 6 projects, enabling faster client delivery and 100% on-time project completion rate',
|
||||||
'Elara Medical - Medical tourism platform with RBAC system, i18n for 3 languages, PWA features, and optimized performance through code splitting and lazy loading',
|
'Elara Medical - Medical tourism platform with RBAC system, i18n for 3 languages, PWA features, and optimized performance through code splitting and lazy loading',
|
||||||
'Ideh - Idea evaluation platform with reusable component library reducing development time by 30% and scalable Vue.js architecture',
|
'Ideh - Idea evaluation platform with reusable component library reducing development time by 30% and scalable Vue.js architecture',
|
||||||
|
|||||||
@@ -258,7 +258,7 @@ Frontend Developer | Freelance (Remote) | Sep 2023 – Dec 2024
|
|||||||
|
|
||||||
**Introduction Paragraph:**
|
**Introduction Paragraph:**
|
||||||
```
|
```
|
||||||
Delivered 6+ production-grade web applications for international clients, achieving
|
Delivered 4+ production-grade web applications for international clients, achieving
|
||||||
90+ Lighthouse performance scores and 99%+ uptime across all projects.
|
90+ Lighthouse performance scores and 99%+ uptime across all projects.
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -545,7 +545,7 @@ Spearheaded 40% performance improvement...
|
|||||||
**Summary Adjustment:**
|
**Summary Adjustment:**
|
||||||
```
|
```
|
||||||
Versatile Senior Frontend Developer with 5+ years delivering production-grade
|
Versatile Senior Frontend Developer with 5+ years delivering production-grade
|
||||||
applications for international clients. Delivered 6+ projects as freelancer with
|
applications for international clients. Delivered 4+ projects as freelancer with
|
||||||
100% on-time delivery and 90+ Lighthouse scores. Architected reusable component
|
100% on-time delivery and 90+ Lighthouse scores. Architected reusable component
|
||||||
library reducing development time by 30%...
|
library reducing development time by 30%...
|
||||||
```
|
```
|
||||||
|
|||||||
Reference in New Issue
Block a user