Add build instructions; update README to match spec
This commit is contained in:
424
INSTRUCTIONS.md
Normal file
424
INSTRUCTIONS.md
Normal file
@@ -0,0 +1,424 @@
|
|||||||
|
# Portfolio Website — Build Instructions
|
||||||
|
|
||||||
|
Build a complete, production-ready personal portfolio website for me.
|
||||||
|
|
||||||
|
## Source of truth
|
||||||
|
|
||||||
|
First inspect ALL files available in the project/workspace, especially CV/resume files and documents containing personal, professional, project, education, skill, certification, or contact information.
|
||||||
|
|
||||||
|
Use those files as the source of truth.
|
||||||
|
|
||||||
|
Do not invent experience, achievements, dates, employers, technologies, metrics, education, certifications, projects, or personal details.
|
||||||
|
|
||||||
|
If multiple CVs contain conflicting information:
|
||||||
|
|
||||||
|
1. Prefer the newest clearly dated version.
|
||||||
|
2. Cross-check other available documents where useful.
|
||||||
|
3. If the correct information cannot be determined, flag the conflict instead of guessing.
|
||||||
|
|
||||||
|
## Goal
|
||||||
|
|
||||||
|
Create a modern, fast, professional portfolio presenting:
|
||||||
|
|
||||||
|
- Who I am
|
||||||
|
- Professional summary
|
||||||
|
- Work history / Experience
|
||||||
|
- Projects
|
||||||
|
- Technical skills
|
||||||
|
- Education
|
||||||
|
- Certifications, if present
|
||||||
|
- Contact information
|
||||||
|
- Relevant external profiles and links found in the supplied files
|
||||||
|
|
||||||
|
Prioritize real information, readability, and clarity over decorative UI.
|
||||||
|
|
||||||
|
The overall tone should be simple, informative, confident, and professional. Avoid filler language and unnecessary marketing copy.
|
||||||
|
|
||||||
|
## Information architecture and section navigation
|
||||||
|
|
||||||
|
My Skills, Work History, Projects, Education, Certifications, About information, and other major portfolio content must each have a clearly defined UI and navigation state.
|
||||||
|
|
||||||
|
Do not present the portfolio as an undifferentiated long page where users must continuously scroll to discover everything.
|
||||||
|
|
||||||
|
Visitors should immediately understand:
|
||||||
|
|
||||||
|
- What sections are available
|
||||||
|
- Which section they are currently viewing
|
||||||
|
- How to move to another section
|
||||||
|
- How to return to previous content
|
||||||
|
- Which items are interactive
|
||||||
|
- Where more detailed information is available
|
||||||
|
|
||||||
|
Create a clear navigation model appropriate for the final design. This may use a persistent navigation bar, section switcher, tabs, sidebar, command-style navigation, or another well-designed approach.
|
||||||
|
|
||||||
|
The navigation itself should feel like part of the portfolio's identity rather than a generic website menu.
|
||||||
|
|
||||||
|
Important sections such as:
|
||||||
|
|
||||||
|
"About → Experience → Projects → Skills → Education / Certifications → Contact"
|
||||||
|
|
||||||
|
must be directly selectable.
|
||||||
|
|
||||||
|
On mobile, adapt this interaction appropriately rather than simply shrinking the desktop navigation.
|
||||||
|
|
||||||
|
## Work history
|
||||||
|
|
||||||
|
Give work history a dedicated, recognizable UI.
|
||||||
|
|
||||||
|
Users should be able to move between employers/roles easily and understand:
|
||||||
|
|
||||||
|
- Company
|
||||||
|
- Position
|
||||||
|
- Time period
|
||||||
|
- Responsibilities
|
||||||
|
- Relevant technologies
|
||||||
|
- Significant work or achievements, only when supported by source files
|
||||||
|
|
||||||
|
Consider timelines, selectable role entries, expandable details, or another compact interaction when appropriate.
|
||||||
|
|
||||||
|
Do not bury work experience inside generic cards.
|
||||||
|
|
||||||
|
## Projects
|
||||||
|
|
||||||
|
Projects should have their own distinct interface.
|
||||||
|
|
||||||
|
Make individual projects easy to browse and switch between.
|
||||||
|
|
||||||
|
Where supported by source material, show:
|
||||||
|
|
||||||
|
- Project name
|
||||||
|
- Purpose/problem
|
||||||
|
- My role
|
||||||
|
- What I worked on
|
||||||
|
- Technologies
|
||||||
|
- Relevant outcomes
|
||||||
|
- Links
|
||||||
|
|
||||||
|
Allow users to select a project and explore its details without losing their place in the overall portfolio.
|
||||||
|
|
||||||
|
## Skills
|
||||||
|
|
||||||
|
Skills should also be a clearly identifiable section rather than a large unordered list of technology badges.
|
||||||
|
|
||||||
|
Organize skills into meaningful categories derived from my actual experience and source documents.
|
||||||
|
|
||||||
|
For example, only when supported by the files:
|
||||||
|
|
||||||
|
"Infrastructure"
|
||||||
|
"Networking"
|
||||||
|
"Cloud"
|
||||||
|
"DevOps"
|
||||||
|
"Development"
|
||||||
|
"Operating Systems"
|
||||||
|
"Virtualization"
|
||||||
|
"Automation"
|
||||||
|
"Databases"
|
||||||
|
"Tools"
|
||||||
|
|
||||||
|
Do not invent categories or skills merely to fill the interface.
|
||||||
|
|
||||||
|
Where useful, make categories selectable so visitors can quickly explore different areas of expertise.
|
||||||
|
|
||||||
|
Do not assign arbitrary percentage bars such as "Linux 95%" or "Docker 90%" unless such measurements genuinely exist in the source material.
|
||||||
|
|
||||||
|
## Section switching and animation
|
||||||
|
|
||||||
|
Switching between major sections should be a deliberate visual interaction.
|
||||||
|
|
||||||
|
When a visitor chooses:
|
||||||
|
|
||||||
|
"Experience → Projects"
|
||||||
|
|
||||||
|
or:
|
||||||
|
|
||||||
|
"Projects → Skills"
|
||||||
|
|
||||||
|
the change should have a polished animated transition rather than an abrupt content replacement.
|
||||||
|
|
||||||
|
Use transitions such as:
|
||||||
|
|
||||||
|
- Directional slide + fade
|
||||||
|
- Content crossfade
|
||||||
|
- Subtle depth transition
|
||||||
|
- Animated navigation indicator
|
||||||
|
- Shared-element movement where appropriate
|
||||||
|
- Staggered entrance of important content
|
||||||
|
- Smooth timeline/project transitions
|
||||||
|
- Micro-interactions on selected navigation items
|
||||||
|
|
||||||
|
The active section must always be visually obvious.
|
||||||
|
|
||||||
|
Animation should communicate where the user moved, not merely decorate the screen.
|
||||||
|
|
||||||
|
For example, the navigation indicator can move toward the newly selected section while the previous content exits and the new content enters with coordinated motion.
|
||||||
|
|
||||||
|
Maintain spatial consistency so users do not become disoriented.
|
||||||
|
|
||||||
|
Animations should generally be short, responsive, and interruptible. Never make visitors wait for an animation before they can continue navigating.
|
||||||
|
|
||||||
|
Support browser Back/Forward behavior where section navigation changes the URL.
|
||||||
|
|
||||||
|
Where appropriate, major sections should have addressable URLs, for example:
|
||||||
|
|
||||||
|
"/en/experience"
|
||||||
|
"/en/projects"
|
||||||
|
"/en/skills"
|
||||||
|
|
||||||
|
This allows a visitor to link directly to a particular part of the portfolio.
|
||||||
|
|
||||||
|
## Internationalization
|
||||||
|
|
||||||
|
Design the website as multilingual/i18n-first from the beginning.
|
||||||
|
|
||||||
|
Do NOT hard-code user-facing text throughout components. Store translations in structured locale resources.
|
||||||
|
|
||||||
|
Adding another language should not require modifying page components or duplicating pages.
|
||||||
|
|
||||||
|
On the visitor's first visit, determine the initial language using this priority:
|
||||||
|
|
||||||
|
1. Previously saved explicit language choice
|
||||||
|
2. Browser language/preferences ("navigator.languages" / "Accept-Language")
|
||||||
|
3. Privacy-preserving location/region signal when reliably available
|
||||||
|
4. Default fallback language
|
||||||
|
|
||||||
|
Do not request precise geolocation or location permission merely to select a language.
|
||||||
|
|
||||||
|
Never assume that a country uniquely determines language. Region should only help choose a sensible initial locale.
|
||||||
|
|
||||||
|
Always provide a clearly visible language selector.
|
||||||
|
|
||||||
|
Persist explicit language choices locally and respect them on future visits.
|
||||||
|
|
||||||
|
Implement graceful fallback:
|
||||||
|
|
||||||
|
"requested locale → base language → default language"
|
||||||
|
|
||||||
|
Use locale-aware formatting for dates, numbers, and regional data where appropriate.
|
||||||
|
|
||||||
|
Update the HTML "lang" attribute whenever the active language changes.
|
||||||
|
|
||||||
|
Use multilingual URL structures such as:
|
||||||
|
|
||||||
|
"/en/..."
|
||||||
|
"/vi/..."
|
||||||
|
"/ja/..."
|
||||||
|
|
||||||
|
Add appropriate canonical and "hreflang" metadata for multilingual SEO.
|
||||||
|
|
||||||
|
## Content architecture and translation
|
||||||
|
|
||||||
|
Create a canonical portfolio content/data layer separate from presentation and translations.
|
||||||
|
|
||||||
|
Professional facts must remain identical across languages. Only their presentation should be translated.
|
||||||
|
|
||||||
|
Translate naturally rather than word-for-word.
|
||||||
|
|
||||||
|
Preserve where appropriate:
|
||||||
|
|
||||||
|
- Company names
|
||||||
|
- Product names
|
||||||
|
- Project names
|
||||||
|
- Technical terminology
|
||||||
|
- Technology names
|
||||||
|
- URLs
|
||||||
|
- Proper nouns
|
||||||
|
|
||||||
|
Never translate content in a way that changes its meaning or exaggerates my experience.
|
||||||
|
|
||||||
|
If source documents contain multiple languages, reconcile them into one canonical representation before generating locale-specific presentation content.
|
||||||
|
|
||||||
|
## Visual design
|
||||||
|
|
||||||
|
Use a clean, modern, technical aesthetic appropriate for an experienced technology professional.
|
||||||
|
|
||||||
|
The site must be:
|
||||||
|
|
||||||
|
- Responsive
|
||||||
|
- Mobile-first
|
||||||
|
- Accessible
|
||||||
|
- Keyboard navigable
|
||||||
|
- Fast
|
||||||
|
- SEO-friendly
|
||||||
|
- Dark/light-mode friendly
|
||||||
|
- Visually polished
|
||||||
|
- Easy to scan
|
||||||
|
- Informative without feeling dense
|
||||||
|
|
||||||
|
Avoid a generic AI-generated portfolio appearance.
|
||||||
|
|
||||||
|
Specifically avoid excessive gradients, oversized hero typography, excessive rounded cards, meaningless statistics, buzzwords, filler copy, and visual clutter.
|
||||||
|
|
||||||
|
Use my actual career, projects, technologies, and professional information to establish the site's identity.
|
||||||
|
|
||||||
|
The visual philosophy should be:
|
||||||
|
Simple at first glance, detailed when explored.
|
||||||
|
|
||||||
|
## Animation and interaction
|
||||||
|
|
||||||
|
Include eye-catching but tasteful animations throughout the experience.
|
||||||
|
|
||||||
|
Prioritize animation for meaningful interactions:
|
||||||
|
|
||||||
|
- Entering the portfolio
|
||||||
|
- Changing major sections
|
||||||
|
- Selecting a work experience
|
||||||
|
- Selecting a project
|
||||||
|
- Switching skill categories
|
||||||
|
- Opening additional details
|
||||||
|
- Changing language
|
||||||
|
- Changing theme
|
||||||
|
- Navigation hover/focus
|
||||||
|
- Returning to previous content
|
||||||
|
|
||||||
|
Animations should make the interface feel responsive and alive while preserving the simplicity of the content.
|
||||||
|
|
||||||
|
Do not animate everything.
|
||||||
|
|
||||||
|
Avoid distracting particle effects, excessive parallax, constant background movement, long intro sequences, or animation that interferes with reading.
|
||||||
|
|
||||||
|
Animations must:
|
||||||
|
|
||||||
|
- Remain smooth on normal hardware
|
||||||
|
- Prefer GPU-friendly transforms and opacity
|
||||||
|
- Avoid unnecessary JavaScript
|
||||||
|
- Respect "prefers-reduced-motion"
|
||||||
|
- Degrade gracefully when animation is disabled
|
||||||
|
- Never block navigation
|
||||||
|
- Work correctly on touch devices
|
||||||
|
- Work correctly with keyboard navigation
|
||||||
|
- Remain usable on lower-powered mobile devices
|
||||||
|
|
||||||
|
The desired balance is:
|
||||||
|
|
||||||
|
Simplicity + information + technical identity + fluid navigation + memorable interaction.
|
||||||
|
|
||||||
|
## Engineering
|
||||||
|
|
||||||
|
Before implementation:
|
||||||
|
|
||||||
|
1. Inspect the entire repository and available files.
|
||||||
|
2. Understand the existing stack and conventions.
|
||||||
|
3. Find and inspect relevant CV/resume/document files.
|
||||||
|
4. Extract and normalize factual portfolio information.
|
||||||
|
5. Resolve conflicts using the source-of-truth rules.
|
||||||
|
6. Determine supported languages.
|
||||||
|
7. Design the canonical content model.
|
||||||
|
8. Design the i18n, locale detection, fallback, and routing architecture.
|
||||||
|
9. Design the section/navigation architecture.
|
||||||
|
10. Design the animation and transition system.
|
||||||
|
11. Then implement.
|
||||||
|
|
||||||
|
If this is an existing project, preserve its stack and conventions unless there is a strong technical reason to change them.
|
||||||
|
|
||||||
|
Maintain clear separation between:
|
||||||
|
|
||||||
|
- UI components
|
||||||
|
- Canonical portfolio data
|
||||||
|
- Translation resources
|
||||||
|
- Locale detection/routing
|
||||||
|
- Section navigation
|
||||||
|
- Animation/transition behavior
|
||||||
|
- SEO/metadata
|
||||||
|
- Configuration
|
||||||
|
|
||||||
|
Do not duplicate entire pages for different languages.
|
||||||
|
|
||||||
|
Avoid unnecessary dependencies.
|
||||||
|
|
||||||
|
Never expose missing translation keys such as "hero.title" to visitors.
|
||||||
|
|
||||||
|
## Docker and deployment
|
||||||
|
|
||||||
|
The final website must be built and deployed using a Docker image.
|
||||||
|
|
||||||
|
Provide a production-ready Docker setup.
|
||||||
|
|
||||||
|
Include:
|
||||||
|
|
||||||
|
- "Dockerfile"
|
||||||
|
- ".dockerignore"
|
||||||
|
- Multi-stage build where appropriate
|
||||||
|
- Production-mode runtime
|
||||||
|
- Small runtime image where practical
|
||||||
|
- Non-root runtime user where practical
|
||||||
|
- Correct exposed/configurable port
|
||||||
|
- Environment-variable configuration
|
||||||
|
- Correct inclusion of static assets and locales
|
||||||
|
- Health check where appropriate
|
||||||
|
- No embedded secrets or credentials
|
||||||
|
|
||||||
|
The project should support approximately:
|
||||||
|
|
||||||
|
"docker build -t portfolio ."
|
||||||
|
|
||||||
|
and an appropriate documented "docker run" command.
|
||||||
|
|
||||||
|
Document in the README:
|
||||||
|
|
||||||
|
- Local development
|
||||||
|
- Production build
|
||||||
|
- Docker build
|
||||||
|
- Docker run
|
||||||
|
- Ports
|
||||||
|
- Environment variables
|
||||||
|
- How portfolio content is structured
|
||||||
|
- How to add/update projects
|
||||||
|
- How to add/update work history
|
||||||
|
- How to add skills
|
||||||
|
- How to add another language
|
||||||
|
|
||||||
|
## Performance
|
||||||
|
|
||||||
|
Treat performance as a feature.
|
||||||
|
|
||||||
|
Optimize:
|
||||||
|
|
||||||
|
- Initial bundle size
|
||||||
|
- Images
|
||||||
|
- Fonts
|
||||||
|
- JavaScript
|
||||||
|
- Animations
|
||||||
|
- Loading behavior
|
||||||
|
- Caching
|
||||||
|
- Core Web Vitals
|
||||||
|
|
||||||
|
Do not introduce a large animation/UI library for effects that can reasonably be implemented using CSS or dependencies already present in the project.
|
||||||
|
|
||||||
|
## Quality and verification
|
||||||
|
|
||||||
|
Before considering the task complete:
|
||||||
|
|
||||||
|
- Run the project.
|
||||||
|
- Run lint checks.
|
||||||
|
- Run type checks.
|
||||||
|
- Run available tests.
|
||||||
|
- Build the production version.
|
||||||
|
- Build and run the Docker image.
|
||||||
|
- Test responsive layouts.
|
||||||
|
- Test desktop and mobile navigation.
|
||||||
|
- Test direct URLs to major sections.
|
||||||
|
- Test browser Back/Forward navigation.
|
||||||
|
- Test every supported locale.
|
||||||
|
- Test automatic language detection.
|
||||||
|
- Test manual language switching.
|
||||||
|
- Test persistence across reloads.
|
||||||
|
- Test locale fallback.
|
||||||
|
- Check for untranslated strings.
|
||||||
|
- Check broken links.
|
||||||
|
- Check keyboard navigation.
|
||||||
|
- Check accessibility basics.
|
||||||
|
- Test dark/light mode.
|
||||||
|
- Test "prefers-reduced-motion".
|
||||||
|
- Test section transitions.
|
||||||
|
- Test Experience/Project/Skill switching.
|
||||||
|
- Verify animations remain usable on mobile.
|
||||||
|
- Check metadata, canonical URLs, and multilingual SEO.
|
||||||
|
- Verify every professional claim against the supplied files.
|
||||||
|
|
||||||
|
Fix issues encountered rather than merely reporting them.
|
||||||
|
|
||||||
|
Do not stop at a scaffold, wireframe, mockup, or generic portfolio template.
|
||||||
|
|
||||||
|
Deliver a complete, polished, interactive, multilingual, Docker-deployable portfolio website based entirely on my actual professional information.
|
||||||
|
|
||||||
|
The final experience should feel like an interactive professional profile rather than a CV pasted onto a webpage.
|
||||||
35
README.md
35
README.md
@@ -1,3 +1,36 @@
|
|||||||
# Portfolio
|
# Portfolio
|
||||||
|
|
||||||
Personal project portfolio.
|
Personal portfolio website — interactive professional profile, not a CV pasted onto a webpage.
|
||||||
|
|
||||||
|
Built per [INSTRUCTIONS.md](./INSTRUCTIONS.md), which is the full build specification: source-of-truth rules (CV/resume files in this workspace are canonical; no invented facts), section architecture, i18n-first design, animation requirements, Docker deployment, and verification checklist.
|
||||||
|
|
||||||
|
## What it presents
|
||||||
|
|
||||||
|
- About — who I am, professional summary
|
||||||
|
- Experience — work history with dedicated timeline/role UI
|
||||||
|
- Projects — browsable project details (purpose, role, tech, outcomes, links)
|
||||||
|
- Skills — categorized by actual experience, no invented percentages
|
||||||
|
- Education / Certifications
|
||||||
|
- Contact + external profiles
|
||||||
|
|
||||||
|
## Key properties
|
||||||
|
|
||||||
|
- **Section navigation** — persistent nav with addressable URLs (`/en/experience`, `/en/projects`, ...), browser Back/Forward support, animated section transitions that are interruptible and respect `prefers-reduced-motion`
|
||||||
|
- **i18n-first** — canonical content layer separate from translations; locale detection (saved choice → browser languages → region hint → default); visible language selector with persistence; `/en/...`, `/vi/...` style URLs with hreflang/canonical metadata
|
||||||
|
- **Design** — clean, technical aesthetic; mobile-first, responsive, accessible, keyboard navigable; dark/light mode; simple at first glance, detailed when explored
|
||||||
|
- **Performance** — small initial bundle, no heavy animation/UI libraries for effects CSS can do
|
||||||
|
|
||||||
|
## Deployment
|
||||||
|
|
||||||
|
Docker-based: multi-stage build, non-root runtime user, health check.
|
||||||
|
|
||||||
|
```sh
|
||||||
|
docker build -t portfolio .
|
||||||
|
docker run --rm -p 8080:8080 portfolio
|
||||||
|
```
|
||||||
|
|
||||||
|
See INSTRUCTIONS.md → "Docker and deployment" for ports, environment variables, and content-editing guides (adding projects, work history, skills, languages).
|
||||||
|
|
||||||
|
## Status
|
||||||
|
|
||||||
|
Scaffold — repo initialized. Implementation follows the engineering steps in [INSTRUCTIONS.md](./INSTRUCTIONS.md) (inspect workspace sources → canonical content model → i18n/routing/section architecture → animation system → implement → verify).
|
||||||
|
|||||||
Reference in New Issue
Block a user