diff --git a/docs/sprint-artifacts/2-1-create-resume-page-route.context.xml b/docs/sprint-artifacts/2-1-create-resume-page-route.context.xml
new file mode 100644
index 0000000..41cc64a
--- /dev/null
+++ b/docs/sprint-artifacts/2-1-create-resume-page-route.context.xml
@@ -0,0 +1,100 @@
+
+
+ 2
+ 2.1
+ Create Resume Page Route
+ ready-for-dev
+ 2025-11-30
+ BMAD Story Context Workflow
+ docs/sprint-artifacts/2-1-create-resume-page-route.md
+
+
+
+ user
+ to access my resume at `/resume`
+ I can view it before downloading
+
+ - Create resume page route (AC: #1, #2)
+ - Configure page metadata (AC: #4, #5)
+ - Implement print mode detection (AC: #6)
+ - Add placeholder content (AC: #1)
+ - Test page functionality
+
+
+
+
+ Given I navigate to `/resume`, when the page loads, then I see the resume preview
+ The page is standalone (no site header/footer)
+ The page has a white background
+ The page title is "Resume - Ali Arghyani"
+ Meta tags are set for SEO (noindex for privacy)
+ Given I add `?print=true` query parameter, when the page loads, then the download button is hidden (for PDF generation)
+
+
+
+
+
+ docs/architecture.md
+ Resume Export Feature - Architecture Document
+ Novel Pattern: WYSIWYG PDF Export
+ Single component renders both web preview and PDF source. Query Parameter: `?print=true` hides download button in PDF.
+
+
+ docs/architecture.md
+ Resume Export Feature - Architecture Document
+
+ File: `app/pages/resume.vue` - /resume route (standalone page)
+
+
+ docs/sprint-artifacts/tech-spec-epic-2.md
+ Epic Technical Specification: Resume Preview Page
+ AC1: Standalone Resume Route
+ Page is standalone (no site header/footer), page title is "Resume - Ali Arghyani", meta tag `` is present
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ - Use `definePageMeta({ layout: false })` for standalone page
+ - Use `useHead()` or `useSeoMeta()` for metadata
+ - Use `useRoute().query.print` for print mode detection
+ - File location must be `app/pages/resume.vue` (Nuxt file-based routing)
+ - White background: `bg-white` class
+
+
+
+
+ useRoute
+ Nuxt composable
+ const route = useRoute(); const isPrintMode = computed(() => route.query.print === 'true')
+ nuxt/app
+
+
+ useHead
+ Nuxt composable
+ useHead({ title: string, meta: Array<{ name: string, content: string }> })
+ nuxt/app
+
+
+
+
+ Nuxt 4 testing with Vitest. Test page routing, metadata, and print mode detection.
+ tests/, app/**/*.spec.ts
+
+ Navigate to /resume and verify page renders
+ Check that no layout is applied (standalone)
+ Verify page title in document.title
+ Check for noindex meta tag in DOM
+ Test with ?print=true parameter and verify isPrintMode is true
+
+
+
diff --git a/docs/sprint-artifacts/2-1-create-resume-page-route.md b/docs/sprint-artifacts/2-1-create-resume-page-route.md
new file mode 100644
index 0000000..85ac38a
--- /dev/null
+++ b/docs/sprint-artifacts/2-1-create-resume-page-route.md
@@ -0,0 +1,151 @@
+# Story 2.1: Create Resume Page Route
+
+Status: ready-for-dev
+
+## Story
+
+As a user,
+I want to access my resume at `/resume`,
+so that I can view it before downloading.
+
+## Acceptance Criteria
+
+1. **AC1:** Given I navigate to `/resume`, when the page loads, then I see the resume preview
+2. **AC2:** The page is standalone (no site header/footer)
+3. **AC3:** The page has a white background
+4. **AC4:** The page title is "Resume - Ali Arghyani"
+5. **AC5:** Meta tags are set for SEO (noindex for privacy)
+6. **AC6:** Given I add `?print=true` query parameter, when the page loads, then the download button is hidden (for PDF generation)
+
+## Tasks / Subtasks
+
+- [ ] Create resume page route (AC: #1, #2)
+ - [ ] Create `app/pages/resume.vue` file
+ - [ ] Use `definePageMeta({ layout: false })` for standalone page
+ - [ ] Add basic page structure with white background
+
+- [ ] Configure page metadata (AC: #4, #5)
+ - [ ] Set page title using `useHead()` or `useSeoMeta()`
+ - [ ] Add `` for privacy
+ - [ ] Ensure title format: "Resume - Ali Arghyani"
+
+- [ ] Implement print mode detection (AC: #6)
+ - [ ] Use `useRoute().query.print` to detect print parameter
+ - [ ] Pass print mode state to child components
+ - [ ] Verify download button visibility logic
+
+- [ ] Add placeholder content (AC: #1)
+ - [ ] Import `ResumePreview` component (will be created in Story 2.2)
+ - [ ] For now, add placeholder text: "Resume Preview Coming Soon"
+ - [ ] Ensure page renders without errors
+
+- [ ] Test page functionality
+ - [ ] Navigate to `/resume` and verify standalone layout
+ - [ ] Check page title in browser tab
+ - [ ] Inspect meta tags in DOM
+ - [ ] Test `/resume?print=true` parameter handling
+ - [ ] Verify white background styling
+
+## Dev Notes
+
+### Architecture Alignment
+
+**From Architecture Doc:**
+- File location: `app/pages/resume.vue` (confirmed in Project Structure section)
+- Layout: Use `definePageMeta({ layout: false })` for standalone page
+- Query parameter: `?print=true` hides download button for PDF generation
+- SEO: `noindex` meta tag for privacy (resume not indexed by search engines)
+
+**From Tech Spec Epic 2:**
+- AC1-AC6 map directly to this story
+- Page serves dual purposes: (1) user preview, (2) PDF generation source
+- WYSIWYG approach: same page renders for web and PDF
+
+### Project Structure Notes
+
+**File to Create:**
+- `app/pages/resume.vue` - Main resume route
+
+**Dependencies:**
+- Nuxt 4 routing (file-based)
+- `useHead()` or `useSeoMeta()` composable for metadata
+- `useRoute()` composable for query parameter detection
+
+**Future Integration:**
+- Story 2.2 will create `ResumePreview.vue` component to replace placeholder
+- Story 2.5 will create `ResumeDownloadButton.vue` that respects print mode
+
+### Implementation Notes
+
+**Page Structure:**
+```vue
+
+
+
+
+
+
+
Resume Preview Coming Soon
+
+
+
+
+
+
+```
+
+**Testing Checklist:**
+- [ ] Page accessible at `http://localhost:3000/resume`
+- [ ] No site navigation visible (header/footer)
+- [ ] White background applied
+- [ ] Browser tab shows "Resume - Ali Arghyani"
+- [ ] Meta tag `` present in DOM
+- [ ] `?print=true` parameter detected correctly
+
+### References
+
+- [Source: docs/architecture.md#Novel-Pattern-WYSIWYG-PDF-Export]
+- [Source: docs/architecture.md#Project-Structure]
+- [Source: docs/sprint-artifacts/tech-spec-epic-2.md#AC1-Standalone-Resume-Route]
+- [Source: docs/epics.md#Story-2.1-Create-Resume-Page-Route]
+
+## Dev Agent Record
+
+### Context Reference
+
+- docs/sprint-artifacts/2-1-create-resume-page-route.context.xml
+
+### Agent Model Used
+
+
+
+### Debug Log References
+
+
+
+### Completion Notes List
+
+
+
+### File List
+
+
+
+---
+
+**Change Log:**
+- 2025-11-30: Story drafted by SM agent (mahdi)
diff --git a/docs/sprint-artifacts/2-2-create-resume-preview-container-component.context.xml b/docs/sprint-artifacts/2-2-create-resume-preview-container-component.context.xml
new file mode 100644
index 0000000..6c3d95e
--- /dev/null
+++ b/docs/sprint-artifacts/2-2-create-resume-preview-container-component.context.xml
@@ -0,0 +1,147 @@
+
+
+ 2
+ 2.2
+ Create Resume Preview Container Component
+ ready-for-dev
+ 2025-11-30
+ BMAD Story Context Workflow
+ docs/sprint-artifacts/2-2-create-resume-preview-container-component.md
+
+
+
+ developer
+ a container component that renders the full resume
+ I have a single source of truth for web and PDF
+
+ - Create ResumePreview component file
+ - Implement two-column layout
+ - Configure container dimensions
+ - Apply color scheme and typography
+ - Add print styles
+ - Integrate data from composable
+ - Add placeholder sections
+ - Test component rendering
+
+
+
+
+ Two-column layout with left sidebar (35% width) and right main content (65% width)
+ Container has A4 aspect ratio (210mm × 297mm)
+ Page margins are 24px (1.5rem)
+ Background is white
+ Color scheme is blue (#2563eb) and white
+ Typography uses Inter font for English text
+ Proper heading hierarchy (h1 for name, h2 for sections)
+ Body text is 14px (0.875rem)
+ ATS-readable font sizes
+ Layout is responsive - desktop shows two-column side by side, mobile shows single column (sidebar on top)
+ Print styles included - `.no-print` class hides elements in print
+ Page breaks are controlled
+ Colors print correctly (`printBackground: true`)
+
+
+
+
+
+ docs/architecture.md
+ Resume Export Feature - Architecture Document
+ Consistency Rules - Color Scheme
+ Primary (headers, icons): Blue - text-blue-600, bg-blue-600. Background: White - bg-white. Text: Dark gray - text-gray-800.
+
+
+ docs/architecture.md
+ Resume Export Feature - Architecture Document
+ Consistency Rules - Typography
+ Name: Inter, 2rem, Bold. Section Headers: Inter, 1rem, Semibold. Body Text: Inter, 0.875rem, Normal.
+
+
+ docs/architecture.md
+ Resume Export Feature - Architecture Document
+ Consistency Rules - Spacing
+ Page margins: 1.5rem (24px). Section gap: 1.5rem. Sidebar width: 35%. Main content width: 65%.
+
+
+ docs/sprint-artifacts/tech-spec-epic-2.md
+ Epic Technical Specification: Resume Preview Page
+
+ Two-column grid: Left sidebar (35% width): Contact, Skills, Education, Languages. Right main content (65% width): Header, Summary, Experience. Container has A4 aspect ratio (210mm × 297mm).
+
+
+
+
+ app/composables/useResumeData.ts
+ composable
+ useResumeData
+ Provides reactive access to resume data for this component
+
+
+ app/types/resume.ts
+ types
+ Resume, ResumeBasics, WorkExperience, Education, Skill, Language
+ TypeScript interfaces for resume data structure
+
+
+ app/data/resume.en.ts
+ data
+ resumeData
+ Sample resume data to display
+
+
+ app/pages/resume.vue
+ page
+ resume page
+ Will import and render this ResumePreview component
+
+
+
+
+
+
+
+
+
+
+
+
+
+ - Use CSS Grid for two-column layout
+ - Tailwind classes for all styling
+ - A4 dimensions: max-w-[210mm] min-h-[297mm]
+ - Margins: p-6 (1.5rem = 24px)
+ - Responsive breakpoint: md:grid-cols-[35%_65%]
+ - Print styles: @media print with .no-print class
+ - Color palette: Blue #2563eb, White #ffffff, Gray #1f2937
+ - Typography: text-sm (0.875rem) for body, text-base for headers
+ - File location: app/components/resume/ResumePreview.vue
+
+
+
+
+ useResumeData
+ composable
+ const { resume, formatDate, getFullName, getPdfFilename } = useResumeData()
+ app/composables/useResumeData.ts
+
+
+ Resume
+ TypeScript interface
+ interface Resume { basics: ResumeBasics; work: WorkExperience[]; education: Education[]; skills: Skill[]; languages?: Language[] }
+ app/types/resume.ts
+
+
+
+
+ Nuxt 4 component testing with Vitest. Test layout, responsive behavior, and print styles.
+ app/components/**/*.spec.ts
+
+ Mount component and verify two-column grid structure
+ Check container dimensions match A4 (210mm × 297mm)
+ Verify padding is 1.5rem (24px)
+ Check background color is white
+ Verify blue color (#2563eb) is applied
+ Test responsive behavior at mobile breakpoint
+ Verify .no-print class exists in styles
+
+
+
diff --git a/docs/sprint-artifacts/2-2-create-resume-preview-container-component.md b/docs/sprint-artifacts/2-2-create-resume-preview-container-component.md
new file mode 100644
index 0000000..24d745d
--- /dev/null
+++ b/docs/sprint-artifacts/2-2-create-resume-preview-container-component.md
@@ -0,0 +1,232 @@
+# Story 2.2: Create Resume Preview Container Component
+
+Status: ready-for-dev
+
+## Story
+
+As a developer,
+I want a container component that renders the full resume,
+so that I have a single source of truth for web and PDF.
+
+## Acceptance Criteria
+
+1. **AC1:** Given the ResumePreview component is rendered, when it displays, then it shows a two-column layout with left sidebar (35% width) and right main content (65% width)
+2. **AC2:** The container has A4 aspect ratio (210mm × 297mm)
+3. **AC3:** Page margins are 24px (1.5rem)
+4. **AC4:** Background is white
+5. **AC5:** Color scheme is blue (#2563eb) and white
+6. **AC6:** Typography uses Inter font for English text
+7. **AC7:** Proper heading hierarchy (h1 for name, h2 for sections)
+8. **AC8:** Body text is 14px (0.875rem)
+9. **AC9:** ATS-readable font sizes
+10. **AC10:** Layout is responsive - desktop shows two-column side by side, mobile shows single column (sidebar on top)
+11. **AC11:** Print styles included - `.no-print` class hides elements in print
+12. **AC12:** Page breaks are controlled
+13. **AC13:** Colors print correctly (`printBackground: true`)
+
+## Tasks / Subtasks
+
+- [ ] Create ResumePreview component file (AC: #1-#13)
+ - [ ] Create `app/components/resume/ResumePreview.vue`
+ - [ ] Set up component structure with script setup and TypeScript
+
+- [ ] Implement two-column layout (AC: #1, #10)
+ - [ ] Use CSS Grid for two-column layout
+ - [ ] Set sidebar width to 35%, main content to 65%
+ - [ ] Add responsive breakpoint for mobile (single column)
+ - [ ] Ensure sidebar appears above main content on mobile
+
+- [ ] Configure container dimensions (AC: #2, #3)
+ - [ ] Set container to A4 aspect ratio (210mm × 297mm)
+ - [ ] Apply 24px (1.5rem) margins
+ - [ ] Use Tailwind classes: `max-w-[210mm] min-h-[297mm] p-6`
+
+- [ ] Apply color scheme and typography (AC: #4-#9)
+ - [ ] Set white background: `bg-white`
+ - [ ] Define blue primary color: `text-blue-600` (#2563eb)
+ - [ ] Configure Inter font (already available via @nuxt/fonts)
+ - [ ] Set body text size: `text-sm` (0.875rem)
+ - [ ] Ensure proper heading hierarchy (h1, h2)
+
+- [ ] Add print styles (AC: #11-#13)
+ - [ ] Create `.no-print` utility class
+ - [ ] Add `@media print` styles
+ - [ ] Set `printBackground: true` for colors
+ - [ ] Control page breaks with `break-inside-avoid`
+
+- [ ] Integrate data from composable
+ - [ ] Import `useResumeData()` composable
+ - [ ] Access `resume` reactive reference
+ - [ ] Prepare for child component integration (Stories 2.3, 2.4)
+
+- [ ] Add placeholder sections
+ - [ ] Add comment placeholders for child components
+ - [ ] Structure: Sidebar (Contact, Skills, Education, Languages)
+ - [ ] Structure: Main (Header, Summary, Experience)
+
+- [ ] Test component rendering
+ - [ ] Import component in `pages/resume.vue`
+ - [ ] Verify two-column layout on desktop
+ - [ ] Test responsive behavior on mobile
+ - [ ] Check print preview (Ctrl+P)
+ - [ ] Verify A4 dimensions and margins
+
+## Dev Notes
+
+### Architecture Alignment
+
+**From Architecture Doc:**
+- File location: `app/components/resume/ResumePreview.vue`
+- Layout: CSS Grid for two-column design
+- Styling: Tailwind CSS utilities
+- Data source: `useResumeData()` composable from Epic 1
+
+**From Tech Spec Epic 2:**
+- AC1-AC13 map directly to this story
+- Container is the main orchestrator for all resume sections
+- WYSIWYG pattern: same component for web and PDF
+
+### Learnings from Previous Story
+
+**From Story 2.1 (Status: drafted)**
+- Page route created at `app/pages/resume.vue`
+- Standalone layout configured with `definePageMeta({ layout: false })`
+- Print mode detection implemented via `useRoute().query.print`
+- White background and metadata already set
+- **Integration Point**: Import `ResumePreview` component to replace placeholder
+
+[Source: docs/sprint-artifacts/2-1-create-resume-page-route.md]
+
+### Project Structure Notes
+
+**File to Create:**
+- `app/components/resume/ResumePreview.vue` - Main container component
+
+**Dependencies:**
+- `app/composables/useResumeData.ts` (Epic 1 - completed)
+- `app/types/resume.ts` (Epic 1 - completed)
+- `app/data/resume.en.ts` (Epic 1 - completed)
+- Tailwind CSS (existing)
+- @nuxt/fonts with Inter (existing)
+
+**Future Integration:**
+- Story 2.3 will create Header, Summary, Experience components
+- Story 2.4 will create Contact, Skills, Education, Languages components
+- Story 2.5 will create Download Button component
+
+### Implementation Notes
+
+**Component Structure:**
+```vue
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+```
+
+**Responsive Breakpoints:**
+- Desktop (md: 768px+): Two columns side by side
+- Mobile (< 768px): Single column, sidebar stacked on top
+
+**Color Palette:**
+- Primary Blue: `#2563eb` (text-blue-600, bg-blue-600)
+- Background: `#ffffff` (bg-white)
+- Sidebar Background: `#eff6ff` (bg-blue-50)
+- Text: `#1f2937` (text-gray-800)
+- Secondary Text: `#6b7280` (text-gray-600)
+
+**Typography Scale:**
+- Name (h1): 2rem (text-3xl), font-bold
+- Section Headers (h2): 1rem (text-base), font-semibold
+- Body Text: 0.875rem (text-sm), font-normal
+
+**Testing Checklist:**
+- [ ] Component renders without errors
+- [ ] Two-column layout displays correctly on desktop
+- [ ] Single column layout on mobile (< 768px)
+- [ ] A4 dimensions maintained (210mm × 297mm)
+- [ ] Margins are 24px (1.5rem)
+- [ ] White background applied
+- [ ] Blue color scheme visible
+- [ ] Inter font loaded and applied
+- [ ] Print preview shows correct styling
+- [ ] `.no-print` class works in print mode
+
+### References
+
+- [Source: docs/architecture.md#Project-Structure]
+- [Source: docs/architecture.md#Novel-Pattern-WYSIWYG-PDF-Export]
+- [Source: docs/architecture.md#Consistency-Rules]
+- [Source: docs/sprint-artifacts/tech-spec-epic-2.md#AC2-Two-Column-Layout]
+- [Source: docs/sprint-artifacts/tech-spec-epic-2.md#Detailed-Design]
+- [Source: docs/epics.md#Story-2.2-Create-Resume-Preview-Container-Component]
+
+## Dev Agent Record
+
+### Context Reference
+
+- docs/sprint-artifacts/2-2-create-resume-preview-container-component.context.xml
+
+### Agent Model Used
+
+
+
+### Debug Log References
+
+
+
+### Completion Notes List
+
+
+
+### File List
+
+
+
+---
+
+**Change Log:**
+- 2025-11-30: Story drafted by SM agent (mahdi)
diff --git a/docs/sprint-artifacts/2-3-create-resume-header-main-content-components.context.xml b/docs/sprint-artifacts/2-3-create-resume-header-main-content-components.context.xml
new file mode 100644
index 0000000..7d56e17
--- /dev/null
+++ b/docs/sprint-artifacts/2-3-create-resume-header-main-content-components.context.xml
@@ -0,0 +1,131 @@
+
+
+ 2
+ 2.3
+ Create Resume Header & Main Content Components
+ ready-for-dev
+ 2025-11-30
+ BMAD Story Context Workflow
+ docs/sprint-artifacts/2-3-create-resume-header-main-content-components.md
+
+
+
+ user
+ to see my name, title, summary, and work experience prominently
+ recruiters see the most important information first
+
+ - Create ResumeHeader component
+ - Create ResumeSummary component
+ - Create ResumeExperience component
+ - Integrate components into ResumePreview
+ - Test components rendering
+
+
+
+
+ Header shows full name in large bold text (2rem, font-bold)
+ Job title appears below name (1.25rem, text-gray-600)
+ Blue accent line or background element is present
+ Summary shows "Profile" or "Summary" section header
+ Professional summary paragraph is displayed
+ Line height is 1.6 for readability
+ Experience shows for each job: position title (bold), company name, date range (formatted: "Jan 2022 - Present"), bullet points for highlights (• character)
+ Jobs are sorted by date (most recent first)
+ "Present" is shown for current jobs (no endDate)
+
+
+
+
+
+ docs/architecture.md
+ Resume Export Feature - Architecture Document
+
+ WorkExperience interface: company, position, startDate (YYYY-MM), endDate (optional), highlights (string[])
+
+
+ docs/sprint-artifacts/tech-spec-epic-2.md
+ Epic Technical Specification: Resume Preview Page
+ AC5: Header Section, AC10: Summary Section, AC11: Experience Section
+ Header: Name in 2rem bold, job title 1.25rem gray, blue accent line. Summary: Section header, paragraph with line-height 1.6. Experience: Position, company, date range, bullet highlights.
+
+
+
+
+ app/components/resume/ResumePreview.vue
+ component
+ ResumePreview
+ Parent container where these components will be integrated
+
+
+ app/composables/useResumeData.ts
+ composable
+ useResumeData, formatDate
+ Provides data and date formatting helper
+
+
+ app/types/resume.ts
+ types
+ WorkExperience, ResumeBasics
+ TypeScript interfaces for props
+
+
+
+
+
+
+
+
+
+
+
+ - Header: text-3xl font-bold for name, text-xl text-gray-600 for title
+ - Blue accent: border-b-4 border-blue-600
+ - Summary: text-base font-semibold for header, leading-relaxed (1.6) for paragraph
+ - Experience: Sort by startDate descending, format dates with formatDate() helper
+ - Bullet character: • (U+2022)
+ - File locations: app/components/resume/ResumeHeader.vue, ResumeSummary.vue, ResumeExperience.vue
+ - Props pattern: Accept specific data fields, not entire resume object
+
+
+
+
+ ResumeHeader Props
+ Vue component props
+ interface Props { name: string; label: string }
+ app/components/resume/ResumeHeader.vue
+
+
+ ResumeSummary Props
+ Vue component props
+ interface Props { summary: string }
+ app/components/resume/ResumeSummary.vue
+
+
+ ResumeExperience Props
+ Vue component props
+ interface Props { work: WorkExperience[] }
+ app/components/resume/ResumeExperience.vue
+
+
+ formatDate
+ helper function
+ formatDate(date: string, locale?: string): string
+ app/composables/useResumeData.ts
+
+
+
+
+ Vue component testing with Vitest. Test props, rendering, and date formatting.
+ app/components/**/*.spec.ts
+
+ Mount ResumeHeader with sample data, verify name displays with correct styling
+ Verify job title displays below name
+ Check for blue border element
+ Mount ResumeSummary, verify paragraph renders
+ Check computed line-height is 1.6
+ Mount ResumeExperience with multiple jobs, verify all fields display
+ Test job sorting by date
+ Test with job missing endDate, verify "Present" displays
+
+
+
diff --git a/docs/sprint-artifacts/2-3-create-resume-header-main-content-components.md b/docs/sprint-artifacts/2-3-create-resume-header-main-content-components.md
new file mode 100644
index 0000000..14b7e52
--- /dev/null
+++ b/docs/sprint-artifacts/2-3-create-resume-header-main-content-components.md
@@ -0,0 +1,257 @@
+# Story 2.3: Create Resume Header & Main Content Components
+
+Status: ready-for-dev
+
+## Story
+
+As a user,
+I want to see my name, title, summary, and work experience prominently,
+so that recruiters see the most important information first.
+
+## Acceptance Criteria
+
+### ResumeHeader.vue
+1. **AC1:** Given the header component renders, when it displays, then it shows full name in large bold text (2rem, font-bold)
+2. **AC2:** Job title appears below name (1.25rem, text-gray-600)
+3. **AC3:** Blue accent line or background element is present
+
+### ResumeSummary.vue
+4. **AC4:** Given the summary component renders, when it displays, then it shows "Profile" or "Summary" section header
+5. **AC5:** Professional summary paragraph is displayed
+6. **AC6:** Line height is 1.6 for readability
+
+### ResumeExperience.vue
+7. **AC7:** Given the experience component renders, when it displays, then it shows for each job: position title (bold), company name, date range (formatted: "Jan 2022 - Present"), bullet points for highlights (• character)
+8. **AC8:** Jobs are sorted by date (most recent first)
+9. **AC9:** "Present" is shown for current jobs (no endDate)
+
+## Tasks / Subtasks
+
+- [ ] Create ResumeHeader component (AC: #1-#3)
+ - [ ] Create `app/components/resume/ResumeHeader.vue`
+ - [ ] Accept props: `name` (string), `label` (string)
+ - [ ] Display name with `text-3xl font-bold` (2rem)
+ - [ ] Display job title with `text-xl text-gray-600` (1.25rem)
+ - [ ] Add blue accent line: `border-b-4 border-blue-600`
+
+- [ ] Create ResumeSummary component (AC: #4-#6)
+ - [ ] Create `app/components/resume/ResumeSummary.vue`
+ - [ ] Accept props: `summary` (string)
+ - [ ] Add section header "Profile" with `text-base font-semibold`
+ - [ ] Display summary paragraph with `leading-relaxed` (line-height: 1.6)
+ - [ ] Use `text-sm text-gray-800`
+
+- [ ] Create ResumeExperience component (AC: #7-#9)
+ - [ ] Create `app/components/resume/ResumeExperience.vue`
+ - [ ] Accept props: `work` (WorkExperience[])
+ - [ ] Add section header "Experience" with `text-base font-semibold`
+ - [ ] Sort jobs by startDate (most recent first)
+ - [ ] For each job, display:
+ - Position title: `font-semibold text-gray-900`
+ - Company name: `text-gray-700`
+ - Date range: Use `formatDate()` helper from composable
+ - Highlights: `
` with bullet points (• character)
+ - [ ] Handle current jobs: Show "Present" if no endDate
+
+- [ ] Integrate components into ResumePreview (AC: #1-#9)
+ - [ ] Import all three components in `ResumePreview.vue`
+ - [ ] Pass data from `useResumeData()` composable
+ - [ ] Place in right main content column:
+ - ResumeHeader at top
+ - ResumeSummary below header
+ - ResumeExperience below summary
+
+- [ ] Test components rendering
+ - [ ] Verify header displays name and title correctly
+ - [ ] Check blue accent line visibility
+ - [ ] Verify summary section with proper line height
+ - [ ] Test experience section with multiple jobs
+ - [ ] Verify date formatting ("Jan 2022 - Present")
+ - [ ] Check job sorting (most recent first)
+ - [ ] Test with current job (no endDate)
+
+## Dev Notes
+
+### Architecture Alignment
+
+**From Architecture Doc:**
+- File locations: `app/components/resume/ResumeHeader.vue`, `ResumeSummary.vue`, `ResumeExperience.vue`
+- Data source: Props passed from `ResumePreview.vue` (which uses `useResumeData()`)
+- Date formatting: Use `formatDate()` helper from composable
+
+**From Tech Spec Epic 2:**
+- AC5, AC10, AC11, AC15, AC20, AC21 map to this story
+- Main content components for right column (65% width)
+- Professional typography and spacing
+
+### Learnings from Previous Story
+
+**From Story 2.2 (Status: drafted)**
+- `ResumePreview.vue` container created with two-column grid
+- Right main content column ready for child components
+- Data access via `useResumeData()` composable established
+- Tailwind styling patterns defined (text-sm, text-blue-600, etc.)
+- **Integration Point**: Import these components into right column of ResumePreview
+
+[Source: docs/sprint-artifacts/2-2-create-resume-preview-container-component.md]
+
+### Project Structure Notes
+
+**Files to Create:**
+- `app/components/resume/ResumeHeader.vue`
+- `app/components/resume/ResumeSummary.vue`
+- `app/components/resume/ResumeExperience.vue`
+
+**Files to Modify:**
+- `app/components/resume/ResumePreview.vue` - Import and integrate new components
+
+**Dependencies:**
+- `app/composables/useResumeData.ts` - `formatDate()` helper
+- `app/types/resume.ts` - `WorkExperience` interface
+- `app/data/resume.en.ts` - Sample data
+
+### Implementation Notes
+
+**ResumeHeader.vue:**
+```vue
+
+
+
+
+
{{ name }}
+
{{ label }}
+
+
+```
+
+**ResumeSummary.vue:**
+```vue
+
+
+
+
+
Profile
+
{{ summary }}
+
+
+```
+
+**ResumeExperience.vue:**
+```vue
+
+
+
+
+
Experience
+
+
{{ job.position }}
+
{{ job.company }}
+
{{ formatDateRange(job.startDate, job.endDate) }}
+
+ -
+ •
+ {{ highlight }}
+
+
+
+
+
+```
+
+**Integration in ResumePreview.vue:**
+```vue
+
+
+
+
+
+
+```
+
+**Testing Checklist:**
+- [ ] Header displays name "Ali Arghyani" in large bold text
+- [ ] Job title displays below name in gray
+- [ ] Blue accent line visible under header
+- [ ] Summary section has "Profile" header
+- [ ] Summary paragraph has proper line height (1.6)
+- [ ] Experience section has "Experience" header
+- [ ] Jobs sorted by date (most recent first)
+- [ ] Each job shows position, company, date range, highlights
+- [ ] Date formatting works: "Jan 2022 - Present"
+- [ ] Bullet points (•) display correctly
+- [ ] Current job shows "Present" instead of end date
+
+### References
+
+- [Source: docs/architecture.md#Data-Architecture]
+- [Source: docs/architecture.md#Consistency-Rules]
+- [Source: docs/sprint-artifacts/tech-spec-epic-2.md#AC5-Header-Section]
+- [Source: docs/sprint-artifacts/tech-spec-epic-2.md#AC10-Summary-Section]
+- [Source: docs/sprint-artifacts/tech-spec-epic-2.md#AC11-Experience-Section]
+- [Source: docs/epics.md#Story-2.3-Create-Resume-Header-Main-Content-Components]
+
+## Dev Agent Record
+
+### Context Reference
+
+- docs/sprint-artifacts/2-3-create-resume-header-main-content-components.context.xml
+
+### Agent Model Used
+
+
+
+### Debug Log References
+
+
+
+### Completion Notes List
+
+
+
+### File List
+
+
+
+---
+
+**Change Log:**
+- 2025-11-30: Story drafted by SM agent (mahdi)
diff --git a/docs/sprint-artifacts/2-4-create-resume-sidebar-components.context.xml b/docs/sprint-artifacts/2-4-create-resume-sidebar-components.context.xml
new file mode 100644
index 0000000..3241bfe
--- /dev/null
+++ b/docs/sprint-artifacts/2-4-create-resume-sidebar-components.context.xml
@@ -0,0 +1,140 @@
+
diff --git a/docs/sprint-artifacts/2-4-create-resume-sidebar-components.md b/docs/sprint-artifacts/2-4-create-resume-sidebar-components.md
new file mode 100644
index 0000000..ec80e21
--- /dev/null
+++ b/docs/sprint-artifacts/2-4-create-resume-sidebar-components.md
@@ -0,0 +1,324 @@
+# Story 2.4: Create Resume Sidebar Components
+
+Status: ready-for-dev
+
+## Story
+
+As a user,
+I want to see my contact info, skills, education, and languages in the sidebar,
+so that this supporting information is easily scannable.
+
+## Acceptance Criteria
+
+### ResumeContact.vue
+1. **AC1:** Given the contact component renders, when it displays, then it shows email with icon (i-mdi-email)
+2. **AC2:** Phone with icon (i-mdi-phone)
+3. **AC3:** Location with icon (i-mdi-map-marker)
+4. **AC4:** Social profiles with icons (LinkedIn, GitHub, etc.)
+5. **AC5:** Each item is on its own line
+6. **AC6:** Links are clickable (mailto:, tel:, https://)
+
+### ResumeSkills.vue
+7. **AC7:** Given the skills component renders, when it displays, then it shows "Skills" section header
+8. **AC8:** Skill categories as subheaders
+9. **AC9:** Keywords as tags or comma-separated list
+
+### ResumeEducation.vue
+10. **AC10:** Given the education component renders, when it displays, then it shows degree type and field (e.g., "B.Sc. Computer Science")
+11. **AC11:** Institution name
+12. **AC12:** Date range
+
+### ResumeLanguages.vue
+13. **AC13:** Given the languages component renders, when it displays, then it shows "Languages" section header
+14. **AC14:** Each language with fluency level
+
+## Tasks / Subtasks
+
+- [ ] Create ResumeContact component (AC: #1-#6)
+ - [ ] Create `app/components/resume/ResumeContact.vue`
+ - [ ] Accept props: `basics` (ResumeBasics)
+ - [ ] Display email with icon and mailto: link
+ - [ ] Display phone with icon and tel: link
+ - [ ] Display location with icon (city, country)
+ - [ ] Display social profiles with icons and https:// links
+ - [ ] Use Nuxt UI `UIcon` component for icons
+ - [ ] Style each item on separate line
+
+- [ ] Create ResumeSkills component (AC: #7-#9)
+ - [ ] Create `app/components/resume/ResumeSkills.vue`
+ - [ ] Accept props: `skills` (Skill[])
+ - [ ] Add section header "Skills"
+ - [ ] Display each skill category as subheader
+ - [ ] Display keywords as comma-separated list or tags
+ - [ ] Use consistent styling with other sidebar sections
+
+- [ ] Create ResumeEducation component (AC: #10-#12)
+ - [ ] Create `app/components/resume/ResumeEducation.vue`
+ - [ ] Accept props: `education` (Education[])
+ - [ ] Add section header "Education"
+ - [ ] Display degree type and field (e.g., "B.Sc. Computer Science")
+ - [ ] Display institution name
+ - [ ] Display date range using `formatDate()` helper
+
+- [ ] Create ResumeLanguages component (AC: #13-#14)
+ - [ ] Create `app/components/resume/ResumeLanguages.vue`
+ - [ ] Accept props: `languages` (Language[])
+ - [ ] Add section header "Languages"
+ - [ ] Display each language with fluency level
+ - [ ] Format: "English - Fluent"
+
+- [ ] Integrate components into ResumePreview (AC: #1-#14)
+ - [ ] Import all four components in `ResumePreview.vue`
+ - [ ] Pass data from `useResumeData()` composable
+ - [ ] Place in left sidebar column:
+ - ResumeContact at top
+ - ResumeSkills below contact
+ - ResumeEducation below skills
+ - ResumeLanguages at bottom
+
+- [ ] Test components rendering
+ - [ ] Verify contact info displays with icons
+ - [ ] Test clickable links (email, phone, social)
+ - [ ] Check skills section with categories and keywords
+ - [ ] Verify education section with degree and dates
+ - [ ] Test languages section with fluency levels
+ - [ ] Verify all components fit in sidebar layout
+
+## Dev Notes
+
+### Architecture Alignment
+
+**From Architecture Doc:**
+- File locations: `app/components/resume/ResumeContact.vue`, `ResumeSkills.vue`, `ResumeEducation.vue`, `ResumeLanguages.vue`
+- Icons: Use Nuxt UI `UIcon` component with Iconify icons
+- Data source: Props passed from `ResumePreview.vue`
+
+**From Tech Spec Epic 2:**
+- AC6, AC7, AC8, AC9, AC16, AC17, AC18, AC19 map to this story
+- Sidebar components for left column (35% width)
+- Consistent section header styling
+
+### Learnings from Previous Story
+
+**From Story 2.3 (Status: drafted)**
+- Main content components created (Header, Summary, Experience)
+- Component prop patterns established
+- Section header styling: `text-base font-semibold text-gray-900 mb-2`
+- Date formatting via `formatDate()` helper
+- **Integration Point**: Import sidebar components into left column of ResumePreview
+
+[Source: docs/sprint-artifacts/2-3-create-resume-header-main-content-components.md]
+
+### Project Structure Notes
+
+**Files to Create:**
+- `app/components/resume/ResumeContact.vue`
+- `app/components/resume/ResumeSkills.vue`
+- `app/components/resume/ResumeEducation.vue`
+- `app/components/resume/ResumeLanguages.vue`
+
+**Files to Modify:**
+- `app/components/resume/ResumePreview.vue` - Import and integrate sidebar components
+
+**Dependencies:**
+- `@nuxt/ui` - `UIcon` component
+- `app/composables/useResumeData.ts` - `formatDate()` helper
+- `app/types/resume.ts` - Type interfaces
+- `app/data/resume.en.ts` - Sample data
+
+### Implementation Notes
+
+**ResumeContact.vue:**
+```vue
+
+
+
+
+
Contact
+
+
+
+
+
+
+
+
+
+
+
+ {{ basics.location.city }}, {{ basics.location.country }}
+
+
+
+
+
+
+
+```
+
+**ResumeSkills.vue:**
+```vue
+
+
+
+
+
Skills
+
+
+
{{ skill.name }}
+
+ {{ skill.keywords.join(', ') }}
+
+
+
+
+```
+
+**ResumeEducation.vue:**
+```vue
+
+
+
+
+
Education
+
+
+
+ {{ edu.studyType }} {{ edu.area }}
+
+
{{ edu.institution }}
+
{{ formatDateRange(edu.startDate, edu.endDate) }}
+
+
+
+```
+
+**ResumeLanguages.vue:**
+```vue
+
+
+
+
+
Languages
+
+
+ {{ lang.language }} - {{ lang.fluency }}
+
+
+
+```
+
+**Integration in ResumePreview.vue:**
+```vue
+
+
+
+
+
+
+
+```
+
+**Testing Checklist:**
+- [ ] Contact section displays email, phone, location with icons
+- [ ] Email link opens mailto: client
+- [ ] Phone link opens tel: dialer
+- [ ] Social profile links open in new tab
+- [ ] Skills section shows categories and keywords
+- [ ] Keywords displayed as comma-separated list
+- [ ] Education section shows degree, institution, dates
+- [ ] Date formatting works correctly
+- [ ] Languages section shows language and fluency
+- [ ] All components fit properly in sidebar
+- [ ] Icons render correctly (Nuxt UI Icon)
+
+### References
+
+- [Source: docs/architecture.md#Data-Architecture]
+- [Source: docs/architecture.md#Consistency-Rules]
+- [Source: docs/sprint-artifacts/tech-spec-epic-2.md#AC6-Contact-Section]
+- [Source: docs/sprint-artifacts/tech-spec-epic-2.md#AC7-Skills-Section]
+- [Source: docs/sprint-artifacts/tech-spec-epic-2.md#AC8-Education-Section]
+- [Source: docs/sprint-artifacts/tech-spec-epic-2.md#AC9-Languages-Section]
+- [Source: docs/epics.md#Story-2.4-Create-Resume-Sidebar-Components]
+
+## Dev Agent Record
+
+### Context Reference
+
+- docs/sprint-artifacts/2-4-create-resume-sidebar-components.context.xml
+
+### Agent Model Used
+
+
+
+### Debug Log References
+
+
+
+### Completion Notes List
+
+
+
+### File List
+
+
+
+---
+
+**Change Log:**
+- 2025-11-30: Story drafted by SM agent (mahdi)
diff --git a/docs/sprint-artifacts/2-5-create-download-button-component.context.xml b/docs/sprint-artifacts/2-5-create-download-button-component.context.xml
new file mode 100644
index 0000000..5626870
--- /dev/null
+++ b/docs/sprint-artifacts/2-5-create-download-button-component.context.xml
@@ -0,0 +1,108 @@
+
+
+ 2
+ 2.5
+ Create Download Button Component
+ ready-for-dev
+ 2025-11-30
+ BMAD Story Context Workflow
+ docs/sprint-artifacts/2-5-create-download-button-component.md
+
+
+
+ user
+ a prominent download button
+ I can easily download my resume as PDF
+
+ - Create ResumeDownloadButton component
+ - Implement print mode detection
+ - Add placeholder click handler
+ - Integrate into resume page
+ - Test button functionality
+
+
+
+
+ Button is a floating action button (FAB) in bottom-right corner
+ Has download icon (i-heroicons-arrow-down-tray)
+ Has "Download PDF" text (or just icon on mobile)
+ Has blue background color
+ Has fixed position (doesn't scroll)
+ Has shadow for elevation
+ Has the `.no-print` class (hidden in PDF)
+ Button is not visible when `?print=true` parameter is present
+
+
+
+
+
+ docs/architecture.md
+ Resume Export Feature - Architecture Document
+ Novel Pattern: WYSIWYG PDF Export
+ Query Parameter: `?print=true` hides download button for PDF generation.
+
+
+ docs/sprint-artifacts/tech-spec-epic-2.md
+ Epic Technical Specification: Resume Preview Page
+
+ Floating action button in bottom-right corner with download icon, blue background, fixed position, shadow, and .no-print class.
+
+
+
+
+ app/pages/resume.vue
+ page
+ resume page
+ Will import and render this button component, provides isPrintMode prop
+
+
+
+
+
+
+
+
+
+
+ - Use Nuxt UI UButton component
+ - Icon: i-heroicons-arrow-down-tray
+ - Position: fixed bottom-6 right-6
+ - Color: primary (blue)
+ - Size: lg
+ - Shadow: shadow-lg
+ - Z-index: z-50 (above all content)
+ - Responsive: Hide text on mobile with "hidden sm:inline"
+ - Print: .no-print class and v-if="!isPrintMode"
+ - File location: app/components/resume/ResumeDownloadButton.vue
+ - Click handler: Placeholder console.log (Epic 3 will implement actual PDF download)
+
+
+
+
+ ResumeDownloadButton Props
+ Vue component props
+ interface Props { isPrintMode?: boolean }
+ app/components/resume/ResumeDownloadButton.vue
+
+
+ UButton
+ Nuxt UI component
+ <UButton icon="..." size="..." color="..." class="..." @click="..." />
+ @nuxt/ui
+
+
+
+
+ Vue component testing with Vitest. Test visibility, positioning, and click handler.
+ app/components/**/*.spec.ts
+
+ Mount component, verify fixed positioning and bottom-right placement
+ Check icon prop is set correctly
+ Verify blue background color
+ Check fixed position class
+ Verify shadow class applied
+ Check .no-print class exists
+ Mount with isPrintMode=true, verify button not rendered
+
+
+
diff --git a/docs/sprint-artifacts/2-5-create-download-button-component.md b/docs/sprint-artifacts/2-5-create-download-button-component.md
new file mode 100644
index 0000000..fbe351a
--- /dev/null
+++ b/docs/sprint-artifacts/2-5-create-download-button-component.md
@@ -0,0 +1,227 @@
+# Story 2.5: Create Download Button Component
+
+Status: ready-for-dev
+
+## Story
+
+As a user,
+I want a prominent download button,
+so that I can easily download my resume as PDF.
+
+## Acceptance Criteria
+
+1. **AC1:** Given I'm on the resume page, when I see the download button, then it's a floating action button (FAB) in bottom-right corner
+2. **AC2:** It has download icon (i-heroicons-arrow-down-tray)
+3. **AC3:** It has "Download PDF" text (or just icon on mobile)
+4. **AC4:** It has blue background color
+5. **AC5:** It has fixed position (doesn't scroll)
+6. **AC6:** It has shadow for elevation
+7. **AC7:** It has the `.no-print` class (hidden in PDF)
+8. **AC8:** Given I'm on the page with `?print=true`, when the page renders, then the button is not visible
+
+## Tasks / Subtasks
+
+- [ ] Create ResumeDownloadButton component (AC: #1-#7)
+ - [ ] Create `app/components/resume/ResumeDownloadButton.vue`
+ - [ ] Use Nuxt UI `UButton` component
+ - [ ] Set icon to `i-heroicons-arrow-down-tray`
+ - [ ] Add "Download PDF" text
+ - [ ] Apply blue background: `color="primary"` or `bg-blue-600`
+ - [ ] Set fixed position: `fixed bottom-6 right-6`
+ - [ ] Add shadow: `shadow-lg`
+ - [ ] Add `.no-print` class
+
+- [ ] Implement print mode detection (AC: #8)
+ - [ ] Accept prop: `isPrintMode` (boolean)
+ - [ ] Use `v-if="!isPrintMode"` to conditionally render
+ - [ ] Ensure button hidden when `?print=true`
+
+- [ ] Add placeholder click handler
+ - [ ] Add `@click` event handler
+ - [ ] For now, log to console: "Download PDF clicked"
+ - [ ] Note: Actual PDF generation will be implemented in Epic 3
+
+- [ ] Integrate into resume page (AC: #1-#8)
+ - [ ] Import component in `pages/resume.vue`
+ - [ ] Pass `isPrintMode` prop from route query
+ - [ ] Place button outside ResumePreview container
+ - [ ] Verify button appears in bottom-right corner
+
+- [ ] Test button functionality
+ - [ ] Verify button appears in bottom-right corner
+ - [ ] Check fixed position (doesn't scroll with page)
+ - [ ] Verify blue background and shadow
+ - [ ] Test icon displays correctly
+ - [ ] Check "Download PDF" text visibility
+ - [ ] Test click handler (console log)
+ - [ ] Verify button hidden with `?print=true`
+ - [ ] Test print preview (Ctrl+P) - button should be hidden
+
+## Dev Notes
+
+### Architecture Alignment
+
+**From Architecture Doc:**
+- File location: `app/components/resume/ResumeDownloadButton.vue`
+- Component: Use Nuxt UI `UButton` component
+- Icon: Heroicons arrow-down-tray
+- Position: Fixed bottom-right (FAB pattern)
+
+**From Tech Spec Epic 2:**
+- AC12 maps to this story
+- Button hidden in print mode for PDF generation
+- Placeholder for Epic 3 integration
+
+### Learnings from Previous Story
+
+**From Story 2.4 (Status: drafted)**
+- Sidebar components created (Contact, Skills, Education, Languages)
+- All resume sections now complete
+- ResumePreview fully populated with content
+- **Integration Point**: Add download button to resume page, outside ResumePreview container
+
+**From Story 2.1 (Status: drafted)**
+- Print mode detection implemented via `useRoute().query.print`
+- `isPrintMode` computed property available in `pages/resume.vue`
+- **Integration Point**: Pass `isPrintMode` to download button component
+
+[Source: docs/sprint-artifacts/2-4-create-resume-sidebar-components.md]
+[Source: docs/sprint-artifacts/2-1-create-resume-page-route.md]
+
+### Project Structure Notes
+
+**File to Create:**
+- `app/components/resume/ResumeDownloadButton.vue`
+
+**Files to Modify:**
+- `app/pages/resume.vue` - Import and place download button
+
+**Dependencies:**
+- `@nuxt/ui` - `UButton` component
+- Heroicons icon set (via Nuxt UI)
+
+**Future Integration:**
+- Epic 3 Story 3.2 will create `useResumePdf()` composable
+- Epic 3 Story 3.3 will connect this button to PDF generation
+
+### Implementation Notes
+
+**ResumeDownloadButton.vue:**
+```vue
+
+
+
+
+ Download PDF
+
+
+
+
+```
+
+**Integration in pages/resume.vue:**
+```vue
+
+
+
+
+
+
+
+
+```
+
+**Responsive Behavior:**
+- Desktop: Shows "Download PDF" text with icon
+- Mobile: Shows icon only (text hidden with `hidden sm:inline`)
+
+**Z-Index:**
+- Set `z-50` to ensure button appears above all content
+
+**Testing Checklist:**
+- [ ] Button appears in bottom-right corner
+- [ ] Button has fixed position (stays in place when scrolling)
+- [ ] Blue background color applied
+- [ ] Shadow visible for elevation
+- [ ] Download icon displays correctly
+- [ ] "Download PDF" text visible on desktop
+- [ ] Text hidden on mobile (< 640px)
+- [ ] Click handler logs to console
+- [ ] Button hidden with `?print=true` parameter
+- [ ] Button hidden in print preview (Ctrl+P)
+- [ ] Button has proper z-index (appears above content)
+
+### References
+
+- [Source: docs/architecture.md#Implementation-Patterns]
+- [Source: docs/architecture.md#Novel-Pattern-WYSIWYG-PDF-Export]
+- [Source: docs/sprint-artifacts/tech-spec-epic-2.md#AC12-Download-Button]
+- [Source: docs/sprint-artifacts/tech-spec-epic-2.md#AC13-Print-Mode]
+- [Source: docs/epics.md#Story-2.5-Create-Download-Button-Component]
+
+## Dev Agent Record
+
+### Context Reference
+
+- docs/sprint-artifacts/2-5-create-download-button-component.context.xml
+
+### Agent Model Used
+
+
+
+### Debug Log References
+
+
+
+### Completion Notes List
+
+
+
+### File List
+
+
+
+---
+
+**Change Log:**
+- 2025-11-30: Story drafted by SM agent (mahdi)
diff --git a/docs/sprint-artifacts/sprint-status.yaml b/docs/sprint-artifacts/sprint-status.yaml
index 1668502..1f4e811 100644
--- a/docs/sprint-artifacts/sprint-status.yaml
+++ b/docs/sprint-artifacts/sprint-status.yaml
@@ -47,12 +47,12 @@ development_status:
# Goal: Create pixel-perfect resume preview matching PDF output
# FRs: FR5-9, FR15-25
# ═══════════════════════════════════════════════════════════════
- epic-2: backlog
- 2-1-create-resume-page-route: backlog
- 2-2-create-resume-preview-container-component: backlog
- 2-3-create-resume-header-main-content-components: backlog
- 2-4-create-resume-sidebar-components: backlog
- 2-5-create-download-button-component: backlog
+ epic-2: contexted
+ 2-1-create-resume-page-route: ready-for-dev
+ 2-2-create-resume-preview-container-component: ready-for-dev
+ 2-3-create-resume-header-main-content-components: ready-for-dev
+ 2-4-create-resume-sidebar-components: ready-for-dev
+ 2-5-create-download-button-component: ready-for-dev
epic-2-retrospective: optional
# ═══════════════════════════════════════════════════════════════
diff --git a/docs/sprint-artifacts/tech-spec-epic-2.md b/docs/sprint-artifacts/tech-spec-epic-2.md
new file mode 100644
index 0000000..48cb6a7
--- /dev/null
+++ b/docs/sprint-artifacts/tech-spec-epic-2.md
@@ -0,0 +1,380 @@
+# Epic Technical Specification: Resume Preview Page
+
+Date: 2025-11-30
+Author: mahdi
+Epic ID: 2
+Status: Draft
+
+---
+
+## Overview
+
+Epic 2 delivers the Resume Preview Page - a pixel-perfect, standalone web page at `/resume` that renders the resume exactly as it will appear in the PDF export. This epic creates the visual foundation of the Resume Export feature, implementing all UI components with a two-column layout (sidebar + main content) using the Blue & White Clean Professional design template.
+
+The preview page serves dual purposes: (1) user-facing preview for verification before download, and (2) source page for server-side PDF generation via Puppeteer. The WYSIWYG (What You See Is What You Get) approach ensures perfect consistency between web and PDF output.
+
+## Objectives and Scope
+
+**In Scope:**
+- Standalone `/resume` route with no site navigation
+- Two-column responsive layout (35% sidebar, 65% main content)
+- Six modular Vue components for resume sections
+- Blue (#2563eb) and white color scheme with Inter typography
+- Print-optimized CSS for PDF generation compatibility
+- A4 aspect ratio container (210mm × 297mm)
+- Floating download button (hidden in print mode via `?print=true`)
+- ATS-compatible HTML structure (semantic headings, no layout tables)
+
+**Out of Scope:**
+- PDF generation logic (Epic 3)
+- Resume data creation (Epic 1 - already completed)
+- Persian language support (future)
+- Multiple template designs (future)
+- Customization UI (future)
+
+## System Architecture Alignment
+
+**Framework:** Nuxt 4.1.3 with Vue 3 Composition API
+**Styling:** Tailwind CSS 4.1.x with Nuxt UI 4.0.x components
+**Fonts:** Inter (via @nuxt/fonts) for English text
+**Icons:** Nuxt UI Icon component with Iconify icons
+
+**Architecture Decisions Referenced:**
+- ADR-002: Vue Components as Templates - Each resume section is a standalone component
+- Novel Pattern: WYSIWYG PDF Export - Single component source for web and PDF
+- Naming Conventions: PascalCase for components, Tailwind utilities for styling
+
+**Data Source:** `useResumeData()` composable (from Epic 1) provides reactive access to `app/data/resume.en.ts`
+
+## Detailed Design
+
+### Services and Modules
+
+| Component | Responsibility | Inputs | Outputs | Owner |
+|-----------|---------------|--------|---------|-------|
+| `pages/resume.vue` | Route handler, layout wrapper | Query param `?print` | Renders ResumePreview | Story 2.1 |
+| `ResumePreview.vue` | Container, two-column grid | Resume data | Full resume layout | Story 2.2 |
+| `ResumeHeader.vue` | Name and job title display | `basics.name`, `basics.label` | Header section | Story 2.3 |
+| `ResumeSummary.vue` | Professional summary | `basics.summary` | Summary section | Story 2.3 |
+| `ResumeExperience.vue` | Work history with highlights | `work[]` array | Experience section | Story 2.3 |
+| `ResumeContact.vue` | Contact info with icons | `basics` (email, phone, location, profiles) | Contact section | Story 2.4 |
+| `ResumeSkills.vue` | Technical skills by category | `skills[]` array | Skills section | Story 2.4 |
+| `ResumeEducation.vue` | Education history | `education[]` array | Education section | Story 2.4 |
+| `ResumeLanguages.vue` | Language proficiencies | `languages[]` array | Languages section | Story 2.4 |
+| `ResumeDownloadButton.vue` | Floating action button | `?print` query param | Download trigger | Story 2.5 |
+
+### Data Models and Contracts
+
+**Input:** All components consume data from `useResumeData()` composable:
+
+```typescript
+const { resume, formatDate, getFullName, getPdfFilename } = useResumeData()
+```
+
+**Resume Data Structure (from Epic 1):**
+- `resume.basics`: Name, label, email, phone, location, profiles, summary
+- `resume.work[]`: Company, position, startDate, endDate, highlights[]
+- `resume.education[]`: Institution, area, studyType, startDate, endDate
+- `resume.skills[]`: Name (category), keywords[]
+- `resume.languages[]`: Language, fluency
+
+**Date Format:** YYYY-MM strings formatted to "Jan 2023" via `formatDate()` helper
+
+### APIs and Interfaces
+
+**Component Props:**
+
+```typescript
+// ResumePreview.vue - No props (uses composable)
+// All child components receive data via props from parent
+
+// ResumeHeader.vue
+interface Props {
+ name: string
+ label: string // Job title
+}
+
+// ResumeExperience.vue
+interface Props {
+ work: WorkExperience[]
+}
+
+// ResumeContact.vue
+interface Props {
+ basics: ResumeBasics
+}
+
+// Similar pattern for other components
+```
+
+**Query Parameters:**
+- `?print=true`: Hides download button, optimizes for PDF generation
+
+### Workflows and Sequencing
+
+**User Flow:**
+1. User navigates to `/resume`
+2. Page loads with `layout: false` (standalone)
+3. `ResumePreview.vue` fetches data via `useResumeData()`
+4. Two-column grid renders:
+ - Left sidebar: Contact → Skills → Education → Languages
+ - Right main: Header → Summary → Experience
+5. Floating download button appears (bottom-right)
+6. User clicks download → triggers Epic 3 PDF generation
+
+**PDF Generation Flow (Epic 3 integration):**
+1. Puppeteer navigates to `/resume?print=true`
+2. Same components render without download button
+3. Puppeteer captures page as PDF
+4. Result: Pixel-perfect match to web preview
+
+## Non-Functional Requirements
+
+### Performance
+
+- **Page Load:** < 1 second (static data, no API calls)
+- **LCP (Largest Contentful Paint):** < 1.5s
+- **CLS (Cumulative Layout Shift):** 0 (fixed dimensions)
+- **Font Loading:** Inter font preloaded via @nuxt/fonts
+
+**Strategy:** Inline critical CSS, use Tailwind JIT, no external API dependencies
+
+### Security
+
+- **No PII Exposure:** Resume data is static, no user input
+- **SEO:** `noindex` meta tag for privacy (resume not indexed by search engines)
+- **XSS Protection:** Vue's automatic escaping for all text content
+
+### Reliability/Availability
+
+- **Static Rendering:** Page works without JavaScript (SSR)
+- **Graceful Degradation:** Print styles work even if JS fails
+- **Error Handling:** Composable returns empty data if file missing (prevents crashes)
+
+### Observability
+
+- **Console Logging:** Development mode logs component mount/unmount
+- **Error Boundaries:** Vue error handlers catch component failures
+- **Performance Monitoring:** Nuxt DevTools tracks component render times
+
+## Dependencies and Integrations
+
+**External Dependencies:**
+- `@nuxt/fonts` (0.11.x): Inter font loading
+- `@nuxt/ui` (4.0.x): UButton, UIcon components
+- Tailwind CSS (4.1.x): Utility classes
+
+**Internal Dependencies:**
+- `app/types/resume.ts`: TypeScript interfaces (Epic 1)
+- `app/data/resume.en.ts`: Resume data (Epic 1)
+- `app/composables/useResumeData.ts`: Data access composable (Epic 1)
+
+**Integration Points:**
+- Epic 3: `/api/resume/pdf` will navigate to `/resume?print=true`
+- Future: Persian support will use `app/data/resume.fa.ts`
+
+## Acceptance Criteria (Authoritative)
+
+### AC1: Standalone Resume Route
+**Given** I navigate to `/resume`
+**When** the page loads
+**Then** I see the resume preview with no site header/footer
+**And** page title is "Resume - Ali Arghyani"
+**And** meta tag `` is present
+
+### AC2: Two-Column Layout
+**Given** the resume page is rendered on desktop
+**When** I view the layout
+**Then** I see a two-column grid:
+- Left sidebar (35% width): Contact, Skills, Education, Languages
+- Right main content (65% width): Header, Summary, Experience
+**And** container has A4 aspect ratio (210mm × 297mm)
+**And** page margins are 24px (1.5rem)
+
+### AC3: Responsive Behavior
+**Given** the resume page is rendered on mobile
+**When** viewport width < 768px
+**Then** layout switches to single column
+**And** sidebar sections appear above main content
+
+### AC4: Color Scheme and Typography
+**Given** the resume is displayed
+**When** I inspect the styling
+**Then** primary color is blue (#2563eb) for headers and icons
+**And** background is white
+**And** text is dark gray (#1f2937)
+**And** font family is Inter
+**And** body text size is 14px (0.875rem)
+
+### AC5: Header Section
+**Given** the header component renders
+**When** I view the top of the resume
+**Then** I see full name in large bold text (2rem)
+**And** job title below name (1.25rem, gray)
+**And** blue accent line or background element
+
+### AC6: Contact Section
+**Given** the contact component renders
+**When** I view the sidebar
+**Then** I see email with icon (i-mdi-email)
+**And** phone with icon (i-mdi-phone)
+**And** location with icon (i-mdi-map-marker)
+**And** social profiles (LinkedIn, GitHub) with icons
+**And** all links are clickable (mailto:, tel:, https://)
+
+### AC7: Skills Section
+**Given** the skills component renders
+**When** I view the sidebar
+**Then** I see "Skills" section header
+**And** skill categories as subheaders
+**And** keywords displayed as tags or comma-separated list
+
+### AC8: Education Section
+**Given** the education component renders
+**When** I view the sidebar
+**Then** I see degree type and field (e.g., "B.Sc. Computer Science")
+**And** institution name
+**And** date range formatted (e.g., "2018 - 2022")
+
+### AC9: Languages Section
+**Given** the languages component renders
+**When** I view the sidebar
+**Then** I see "Languages" section header
+**And** each language with fluency level (e.g., "English - Fluent")
+
+### AC10: Summary Section
+**Given** the summary component renders
+**When** I view the main content
+**Then** I see "Profile" or "Summary" section header
+**And** professional summary paragraph
+**And** line height is 1.6 for readability
+
+### AC11: Experience Section
+**Given** the experience component renders
+**When** I view the main content
+**Then** I see for each job:
+- Position title (bold)
+- Company name
+- Date range (formatted: "Jan 2022 - Present")
+- Bullet points for highlights (• character)
+**And** jobs are sorted by date (most recent first)
+**And** "Present" is shown for current jobs (no endDate)
+
+### AC12: Download Button
+**Given** I'm on the resume page
+**When** I view the page
+**Then** I see a floating action button in bottom-right corner
+**And** it has download icon (i-heroicons-arrow-down-tray)
+**And** it has "Download PDF" text
+**And** it has blue background color
+**And** it has fixed position (doesn't scroll)
+**And** it has shadow for elevation
+**And** it has `.no-print` class
+
+### AC13: Print Mode
+**Given** I navigate to `/resume?print=true`
+**When** the page loads
+**Then** the download button is not visible
+**And** all other content renders normally
+
+### AC14: Print Styles
+**Given** the page is printed or captured by Puppeteer
+**When** print media query is active
+**Then** `.no-print` elements are hidden
+**And** colors print correctly (printBackground: true)
+**And** page breaks are controlled
+**And** A4 dimensions are maintained
+
+### AC15: ATS Compatibility
+**Given** the HTML structure is inspected
+**When** I check semantic elements
+**Then** name uses `` tag
+**And** section headers use `` tags
+**And** no layout tables are used (CSS Grid/Flexbox only)
+**And** all text is real HTML text (not images)
+
+## Traceability Mapping
+
+| AC | Spec Section | Components | Test Idea |
+|----|--------------|------------|-----------|
+| AC1 | Standalone Route | `pages/resume.vue` | Navigate to /resume, verify no nav, check meta tags |
+| AC2 | Two-Column Layout | `ResumePreview.vue` | Inspect grid, measure column widths, verify A4 ratio |
+| AC3 | Responsive | `ResumePreview.vue` | Resize viewport, verify single column on mobile |
+| AC4 | Color/Typography | All components | Inspect computed styles, verify colors and fonts |
+| AC5 | Header | `ResumeHeader.vue` | Check h1 text, font size, job title styling |
+| AC6 | Contact | `ResumeContact.vue` | Verify icons, links, click mailto/tel links |
+| AC7 | Skills | `ResumeSkills.vue` | Check section header, categories, keywords |
+| AC8 | Education | `ResumeEducation.vue` | Verify degree, institution, date formatting |
+| AC9 | Languages | `ResumeLanguages.vue` | Check language list, fluency levels |
+| AC10 | Summary | `ResumeSummary.vue` | Verify section header, paragraph, line height |
+| AC11 | Experience | `ResumeExperience.vue` | Check job entries, date formatting, bullet points |
+| AC12 | Download Button | `ResumeDownloadButton.vue` | Verify FAB position, icon, styling, shadow |
+| AC13 | Print Mode | `pages/resume.vue` | Add ?print=true, verify button hidden |
+| AC14 | Print Styles | CSS | Trigger print preview, verify styles |
+| AC15 | ATS Compatibility | HTML structure | Inspect DOM, verify semantic tags, no tables |
+
+## Risks, Assumptions, Open Questions
+
+**Risks:**
+- **Risk:** Font loading delay causes layout shift
+ - **Mitigation:** Use @nuxt/fonts with preload, font-display: swap
+- **Risk:** Print styles differ across browsers
+ - **Mitigation:** Test in Chrome, Firefox, Safari; use Puppeteer for PDF (consistent)
+- **Risk:** Long content causes page overflow
+ - **Mitigation:** Test with max content length, add overflow handling
+
+**Assumptions:**
+- **Assumption:** Inter font is ATS-compatible
+ - **Validation:** Inter is a standard web font, widely supported
+- **Assumption:** Two-column layout works for all content lengths
+ - **Validation:** Test with varying experience entries (2-5 jobs)
+- **Assumption:** Blue (#2563eb) has sufficient contrast
+ - **Validation:** WCAG AA contrast ratio verified (4.5:1 minimum)
+
+**Open Questions:**
+- **Question:** Should mobile view show download button?
+ - **Answer:** Yes, but consider smaller size or icon-only
+- **Question:** How to handle very long job titles or company names?
+ - **Answer:** Use text truncation with ellipsis, test with max lengths
+- **Question:** Should we add a "Print" button in addition to "Download PDF"?
+ - **Answer:** No for MVP, browser print (Ctrl+P) is sufficient
+
+## Test Strategy Summary
+
+**Unit Tests:**
+- Each component renders with sample data
+- Date formatting helper works correctly
+- Composable returns expected data structure
+
+**Integration Tests:**
+- Full page renders with all components
+- Print mode hides download button
+- Responsive layout switches at breakpoint
+
+**Visual Regression Tests:**
+- Screenshot comparison: web preview vs expected design
+- Print preview matches web preview
+- Mobile layout matches design
+
+**Manual Tests:**
+- Navigate to /resume, verify all sections
+- Click all links (email, phone, social profiles)
+- Test print preview (Ctrl+P)
+- Test on mobile device
+- Verify ATS compatibility (copy/paste text from PDF)
+
+**Performance Tests:**
+- Measure page load time (< 1s target)
+- Check LCP and CLS metrics
+- Verify font loading doesn't block render
+
+**Acceptance Tests:**
+- Run through all 15 ACs with real data
+- Verify pixel-perfect match to design template
+- Confirm Epic 3 can generate PDF from this page
+
+---
+
+**Epic 2 Tech Spec Complete**
+**Status:** Ready for Story Creation
+**Next Step:** SM creates Story 2.1 draft