diff --git a/src/app/pages/experience/operative-history/column-education-info/column-education-info.component.css b/src/app/pages/experience/operative-history/column-education-info/column-education-info.component.css index e69de29..684c18a 100644 --- a/src/app/pages/experience/operative-history/column-education-info/column-education-info.component.css +++ b/src/app/pages/experience/operative-history/column-education-info/column-education-info.component.css @@ -0,0 +1,562 @@ +/* Education Column Container */ +.education-column { + display: flex; + flex-direction: column; + gap: var(--card-gap); + min-height: 0; + padding-right: 0.5rem; + + /* Hide overflow initially */ + overflow: hidden; + animation: enableColumnScrollAfterAnimation 0s ease-out 3s forwards; + + /* Initial state for animation */ + opacity: 0; + transform: translateY(20px); + animation: fadeInUp var(--animation-duration) ease-out calc(var(--animation-delay-base) * 4) forwards, enableColumnScrollAfterAnimation 0s ease-out 3s forwards; +} + +/* Column Title */ +.column-title { + font-family: var(--font-terminal); + font-size: 1rem; + color: var(--color-nier-accent); + letter-spacing: 0.1em; + text-align: center; + margin-bottom: var(--card-gap); + padding: 0.5rem; + border-bottom: 1px solid var(--color-nier-border); + flex-shrink: 0; + position: sticky; + top: 0; + background: var(--color-nier-bg); + z-index: 10; + + /* Title animation */ + opacity: 0; + transform: translateX(-10px); + animation: slideInLeft 0.4s ease-out calc(var(--animation-delay-base) * 7) forwards; +} + +/* Experience Card Styles */ +.experience-card { + border: 2px solid var(--color-nier-border); + background: var(--color-nier-bg); + position: relative; + transition: var(--transition-smooth); + margin-bottom: var(--card-gap); + flex-shrink: 0; + border-radius: var(--border-radius); + + /* Card initial state */ + opacity: 0; + transform: translateY(30px) scale(0.95); + will-change: transform, opacity; + animation: cardFadeIn var(--animation-duration) ease-out calc(var(--animation-delay-base) * 9) forwards; +} + +.experience-card:hover { + transform: translateY(-2px) scale(1.02); + box-shadow: var(--shadow-hover); + border-color: var(--color-nier-accent); +} + +/* Active Training Highlight */ +.active-training { + border-color: var(--color-nier-accent); + animation: cardFadeIn var(--animation-duration) ease-out calc(var(--animation-delay-base) * 9) forwards; +} + +/* Card Overlay Effect */ +.experience-card::before { + content: ''; + position: absolute; + inset: 0; + background: linear-gradient(135deg, transparent 0%, rgba(41, 41, 37, 0.05) 100%); + opacity: 0; + transition: opacity 0.3s ease; + pointer-events: none; +} + +.experience-card:hover::before { + opacity: 1; +} + +/* Experience Header */ +.experience-header { + background: linear-gradient(135deg, var(--color-nier-dark) 0%, var(--color-nier-highlight) 100%); + color: var(--color-nier-text-light); + padding: var(--card-padding); + border-bottom: 2px solid var(--color-nier-border); + position: relative; + overflow: hidden; +} + +/* Shimmer Effect */ +.experience-header::after { + content: ''; + position: absolute; + top: 0; + left: -100%; + width: 100%; + height: 100%; + background: linear-gradient(90deg, transparent, rgba(255,255,255,0.1), transparent); + transition: left 0.5s cubic-bezier(0.4, 0, 0.2, 1); +} + +.experience-card:hover .experience-header::after { + left: 100%; +} + +/* Experience Body */ +.experience-body { + padding: var(--card-padding); + background: var(--color-nier-bg); +} + +/* Experience Title */ +.experience-title { + font-family: var(--font-noto-jp); + font-size: 0.95rem; + font-weight: 400; + letter-spacing: 0.02em; + line-height: 1.2; + margin: 0; + text-shadow: 0 1px 2px rgba(0,0,0,0.1); +} + +/* Detail Blocks */ +.detail-block { + margin-bottom: var(--card-gap); + padding: 0.25rem; + border-left: 2px solid transparent; + transition: border-color 0.3s ease, padding-left 0.3s ease; +} + +.detail-block:hover { + border-left-color: var(--color-nier-accent); + padding-left: 0.5rem; +} + +.detail-label { + font-family: var(--font-terminal); + font-size: 0.75rem; + color: var(--color-nier-text-dark); + font-weight: 500; + text-transform: uppercase; + letter-spacing: 0.05em; + display: block; + margin-bottom: 0.25rem; + opacity: 0.8; + transition: opacity 0.3s ease; +} + +.detail-block:hover .detail-label { + opacity: 1; +} + +.detail-value { + font-family: var(--font-noto-jp); + color: var(--color-nier-text-dark); + font-size: 0.85rem; + line-height: 1.4; + display: block; +} + +/* Tech Stack Section */ +.tech-section { + margin-top: var(--card-gap); + padding-top: var(--card-gap); + border-top: 1px solid var(--color-nier-border); + position: relative; +} + +.tech-section::before { + content: ''; + position: absolute; + top: 0; + left: 0; + width: 0; + height: 1px; + background: var(--color-nier-accent); + animation: expandLine 0.6s ease-out calc(var(--animation-delay-base) * 12) forwards; +} + +.tech-grid { + display: flex; + flex-wrap: wrap; + gap: 0.25rem; + margin-top: 0.5rem; +} + +/* Tech Items */ +.tech-item { + background: linear-gradient(135deg, var(--color-nier-accent) 0%, var(--color-nier-highlight) 100%); + color: var(--color-nier-text-light); + padding: 0.25rem 0.5rem; + font-size: 0.7rem; + font-family: var(--font-terminal); + text-transform: uppercase; + letter-spacing: 0.05em; + border-radius: 3px; + white-space: nowrap; + transition: var(--transition-smooth); + box-shadow: 0 2px 4px rgba(0,0,0,0.1); + + /* Initial state for staggered animation */ + opacity: 0; + transform: scale(0.8) translateY(10px); + animation: techItemFadeIn 0.4s ease-out forwards; +} + +/* Staggered animation delays for tech items */ +.tech-item:nth-child(1) { animation-delay: calc(var(--animation-delay-base) * 13); } +.tech-item:nth-child(2) { animation-delay: calc(var(--animation-delay-base) * 14); } +.tech-item:nth-child(3) { animation-delay: calc(var(--animation-delay-base) * 15); } +.tech-item:nth-child(4) { animation-delay: calc(var(--animation-delay-base) * 16); } +.tech-item:nth-child(5) { animation-delay: calc(var(--animation-delay-base) * 17); } +.tech-item:nth-child(n+6) { animation-delay: calc(var(--animation-delay-base) * 18); } + +.tech-item:hover { + transform: translateY(-2px) scale(1.05); + box-shadow: 0 6px 12px rgba(0,0,0,0.2); +} + +/* Status Badges */ +.current-status { + padding: 0.375rem 0.75rem; + font-size: 0.7rem; + font-family: var(--font-terminal-retro); + text-transform: uppercase; + letter-spacing: 0.1em; + border-radius: 20px; + margin-bottom: 0.5rem; + display: inline-block; + box-shadow: 0 2px 4px rgba(0,0,0,0.1); + transition: var(--transition-smooth); + background: linear-gradient(135deg, #4ade80 0%, #22c55e 100%); + color: white; +} + +/* Info Card Styles */ +.info-card { + border: 2px solid var(--color-nier-border); + background: var(--color-nier-bg); + position: relative; + transition: var(--transition-smooth); + margin-bottom: var(--card-gap); + flex-shrink: 0; + border-radius: var(--border-radius); + + /* Card initial state */ + opacity: 0; + transform: translateY(30px) scale(0.95); + animation: cardFadeIn var(--animation-duration) ease-out calc(var(--animation-delay-base) * 10) forwards; +} + +.info-card:hover { + transform: translateY(-1px) scale(1.01); + box-shadow: var(--shadow-subtle); +} + +.info-header { + background: linear-gradient(135deg, var(--color-nier-dark) 0%, var(--color-nier-highlight) 100%); + color: var(--color-nier-text-light); + padding: 0.5rem; + font-family: var(--font-terminal); + font-size: 0.8rem; + text-transform: uppercase; + letter-spacing: 0.05em; + border-bottom: 2px solid var(--color-nier-border); + position: relative; + overflow: hidden; +} + +.info-content { + padding: var(--card-padding); + background: var(--color-nier-bg); + font-size: 0.85rem; + line-height: 1.4; +} + +/* Visual Effects */ +.corner-accent { + position: absolute; + top: 0; + right: 0; + width: 0; + height: 0; + border-left: 10px solid transparent; + border-top: 10px solid var(--color-nier-accent); + opacity: 0; + transition: opacity 0.3s ease; + animation: fadeIn 0.3s ease-out calc(var(--animation-delay-base) * 11) forwards; +} + +.experience-card:hover .corner-accent { + opacity: 1; + animation: none; +} + +.scan-line { + position: absolute; + top: 0; + left: 0; + right: 0; + height: 2px; + background: linear-gradient(90deg, transparent, var(--color-nier-accent), transparent); + will-change: transform; + opacity: 0; + animation: scanFadeIn 0.4s ease-out calc(var(--animation-delay-base) * 12) forwards, scan 4s ease-in-out calc(var(--animation-delay-base) * 15) infinite; +} + +/* Keyframe animations */ +@keyframes fadeInUp { + from { + opacity: 0; + transform: translateY(20px); + } + to { + opacity: 1; + transform: translateY(0); + } +} + +@keyframes enableColumnScrollAfterAnimation { + to { + overflow-y: auto; + } +} + +@keyframes slideInLeft { + from { + opacity: 0; + transform: translateX(-10px); + } + to { + opacity: 1; + transform: translateX(0); + } +} + +@keyframes cardFadeIn { + from { + opacity: 0; + transform: translateY(30px) scale(0.95); + } + to { + opacity: 1; + transform: translateY(0) scale(1); + } +} + +@keyframes techItemFadeIn { + from { + opacity: 0; + transform: scale(0.8) translateY(10px); + } + to { + opacity: 1; + transform: scale(1) translateY(0); + } +} + +@keyframes expandLine { + from { + width: 0; + } + to { + width: 30%; + } +} + +@keyframes fadeIn { + from { + opacity: 0; + } + to { + opacity: 1; + } +} + +@keyframes scanFadeIn { + from { + opacity: 0; + } + to { + opacity: 1; + } +} + +@keyframes scan { + 0% { + transform: translateX(-100%); + } + 100% { + transform: translateX(100%); + } +} + +/* Performance Optimizations */ +.experience-card, +.info-card, +.tech-item { + backface-visibility: hidden; + -webkit-backface-visibility: hidden; +} + +/* Responsive Design - Education Column Specific */ +@media (max-width: 480px) { + .education-column { + gap: 0.5rem; + padding-right: 0.25rem; + + /* Ensure columns are visible on mobile */ + min-height: auto; + + /* Simplified mobile column animations */ + animation-name: fadeInUp, enableColumnScrollAfterAnimation; + animation-duration: 0.3s, 0s; + animation-timing-function: ease-out, ease-out; + animation-delay: 0.2s, 1.5s; + animation-fill-mode: forwards, forwards; + } + + .column-title { + font-size: 0.9rem; + padding: 0.375rem; + margin-bottom: 0.5rem; + + /* Simplified title animation */ + animation-name: slideInLeft; + animation-duration: 0.3s; + animation-timing-function: ease-out; + animation-delay: 0.3s; + animation-fill-mode: forwards; + } + + .experience-card, + .info-card { + margin-bottom: 0.5rem; + border-radius: 6px; + + /* Simplified card animations */ + animation-name: cardFadeIn; + animation-duration: 0.3s; + animation-timing-function: ease-out; + animation-fill-mode: forwards; + } + + .experience-card { + animation-delay: 0.4s; + } + + .info-card { + animation-delay: 0.5s; + } + + .experience-header, + .info-header { + padding: 0.75rem 0.5rem 0.5rem 0.5rem; + } + + .experience-body, + .info-content { + padding: 0.75rem 0.5rem; + } + + .experience-title { + font-size: 0.9rem; + line-height: 1.3; + margin-bottom: 0.25rem; + } + + .detail-block { + margin-bottom: 1rem; + padding: 0.5rem 0.25rem; + } + + .detail-label { + font-size: 0.7rem; + margin-bottom: 0.375rem; + } + + .detail-value { + font-size: 0.8rem; + line-height: 1.4; + } + + .tech-section { + margin-top: 1.25rem; + padding-top: 1rem; + } + + .tech-item { + padding: 0.25rem 0.5rem; + font-size: 0.7rem; + margin-bottom: 0.25rem; + + /* Simplified tech item animation */ + animation-name: techItemFadeIn; + animation-duration: 0.2s; + animation-timing-function: ease-out; + animation-delay: 0.6s; + animation-fill-mode: forwards; + } + + .current-status { + padding: 0.375rem 0.75rem; + font-size: 0.7rem; + margin-bottom: 0.75rem; + } + + .info-content { + font-size: 0.85rem; + line-height: 1.4; + } + + /* Remove complex animations on very small screens */ + @media (max-width: 360px) { + .experience-card, + .info-card, + .tech-item, + .corner-accent, + .scan-line { + animation: none !important; + opacity: 1 !important; + transform: none !important; + } + } +} + +@media (max-width: 768px) and (min-width: 481px) { + .column-title { + font-size: 0.95rem; + } + + .experience-title { + font-size: 0.9rem; + } + + .detail-value, + .info-content { + font-size: 0.8rem; + } +} + +/* Reduced Motion Support - Education Column */ +@media (prefers-reduced-motion: reduce) { + .education-column, + .column-title, + .experience-card, + .info-card, + .tech-item, + .corner-accent, + .scan-line, + .tech-section::before { + animation: none !important; + transition: none !important; + opacity: 1 !important; + transform: none !important; + } +} diff --git a/src/app/pages/experience/operative-history/column-education-info/column-education-info.component.html b/src/app/pages/experience/operative-history/column-education-info/column-education-info.component.html index e69de29..78977c2 100644 --- a/src/app/pages/experience/operative-history/column-education-info/column-education-info.component.html +++ b/src/app/pages/experience/operative-history/column-education-info/column-education-info.component.html @@ -0,0 +1,45 @@ + +
+

[EDUCATION_PROTOCOL]

+ + @if (currentTraining(); as training) { +
+
+
+ +
+
{{ training.statusLabel }}
+

{{ training.title }}

+
+ +
+
+ PROGRAM: + {{ training.classification }} +
+ +
+ INSTITUTION: + {{ training.timeline }} +
+ +
+
CURRICULUM:
+
+ @for (tech of training.techStack; track tech) { + {{ tech }} + } +
+
+
+
+ } + + +
+
ACADEMIC_FOCUS
+
+

Full-stack development specialization with emphasis on modern web technologies and enterprise-grade solutions.

+
+
+
diff --git a/src/app/pages/experience/operative-history/column-education-info/column-education-info.component.ts b/src/app/pages/experience/operative-history/column-education-info/column-education-info.component.ts index 4fe5600..ba9649e 100644 --- a/src/app/pages/experience/operative-history/column-education-info/column-education-info.component.ts +++ b/src/app/pages/experience/operative-history/column-education-info/column-education-info.component.ts @@ -1,4 +1,5 @@ import { Component, signal } from '@angular/core'; +import { type Experience } from '../../../../shared/models/experience.model'; @Component({ selector: 'app-column-education-info', @@ -6,4 +7,24 @@ import { Component, signal } from '@angular/core'; templateUrl: './column-education-info.component.html', styleUrl: './column-education-info.component.css', }) -export class ColumnEducationInfoComponent {} +export class ColumnEducationInfoComponent { + private readonly _currentTraining = signal({ + id: 'developer-training', + title: 'DEVELOPER_TRAINING.EXE', + classification: "Concepteur Développeur d'Applications (RNCP Level BAC+4)", + objective: + 'Intensive full-stack development program focusing on modern web technologies including TypeScript, Node.js, and contemporary development frameworks. Building comprehensive skills in both frontend and backend development.', + timeline: "École O'clock | January 2025 - October 2025", + techStack: [ + 'TYPESCRIPT', + 'NODE.JS', + 'FULL_STACK', + 'WEB_FRAMEWORKS', + ] as const, + status: 'current', + statusLabel: 'ACTIVE | IN_PROGRESS', + isCurrent: true, + } as const); + + readonly currentTraining = this._currentTraining.asReadonly(); +} diff --git a/src/app/pages/experience/operative-history/column-personal-info/column-personal-info.component.html b/src/app/pages/experience/operative-history/column-personal-info/column-personal-info.component.html index f3a9e87..6978243 100644 --- a/src/app/pages/experience/operative-history/column-personal-info/column-personal-info.component.html +++ b/src/app/pages/experience/operative-history/column-personal-info/column-personal-info.component.html @@ -1,4 +1,3 @@ -

[PERSONAL_DATA]

diff --git a/src/app/pages/experience/operative-history/column-professional-info/column-professional-info.component.css b/src/app/pages/experience/operative-history/column-professional-info/column-professional-info.component.css index e69de29..829e0e7 100644 --- a/src/app/pages/experience/operative-history/column-professional-info/column-professional-info.component.css +++ b/src/app/pages/experience/operative-history/column-professional-info/column-professional-info.component.css @@ -0,0 +1,515 @@ +/* Professional Column Container */ +.professional-column { + display: flex; + flex-direction: column; + gap: var(--card-gap); + min-height: 0; + padding-right: 0.5rem; + + /* Hide overflow initially */ + overflow: hidden; + animation: enableColumnScrollAfterAnimation 0s ease-out 3s forwards; + + /* Initial state for animation */ + opacity: 0; + transform: translateY(20px); + animation: fadeInUp var(--animation-duration) ease-out calc(var(--animation-delay-base) * 3) forwards, enableColumnScrollAfterAnimation 0s ease-out 3s forwards; +} + +/* Column Title */ +.column-title { + font-family: var(--font-terminal); + font-size: 1rem; + color: var(--color-nier-accent); + letter-spacing: 0.1em; + text-align: center; + margin-bottom: var(--card-gap); + padding: 0.5rem; + border-bottom: 1px solid var(--color-nier-border); + flex-shrink: 0; + position: sticky; + top: 0; + background: var(--color-nier-bg); + z-index: 10; + + /* Title animation */ + opacity: 0; + transform: translateX(-10px); + animation: slideInLeft 0.4s ease-out calc(var(--animation-delay-base) * 7) forwards; +} + +/* Experience List Container */ +.experience-list { + display: flex; + flex-direction: column; + gap: var(--card-gap); +} + +/* Experience Card Styles */ +.experience-card { + border: 2px solid var(--color-nier-border); + background: var(--color-nier-bg); + position: relative; + transition: var(--transition-smooth); + margin-bottom: var(--card-gap); + flex-shrink: 0; + border-radius: var(--border-radius); + + /* Card initial state */ + opacity: 0; + transform: translateY(30px) scale(0.95); + will-change: transform, opacity; + animation: cardFadeIn var(--animation-duration) ease-out calc(var(--animation-delay-base) * 9) forwards; +} + +.experience-card:hover { + transform: translateY(-2px) scale(1.02); + box-shadow: var(--shadow-hover); + border-color: var(--color-nier-accent); +} + +/* Card Overlay Effect */ +.experience-card::before { + content: ''; + position: absolute; + inset: 0; + background: linear-gradient(135deg, transparent 0%, rgba(41, 41, 37, 0.05) 100%); + opacity: 0; + transition: opacity 0.3s ease; + pointer-events: none; +} + +.experience-card:hover::before { + opacity: 1; +} + +/* Experience Header */ +.experience-header { + background: linear-gradient(135deg, var(--color-nier-dark) 0%, var(--color-nier-highlight) 100%); + color: var(--color-nier-text-light); + padding: var(--card-padding); + border-bottom: 2px solid var(--color-nier-border); + position: relative; + overflow: hidden; +} + +/* Shimmer Effect */ +.experience-header::after { + content: ''; + position: absolute; + top: 0; + left: -100%; + width: 100%; + height: 100%; + background: linear-gradient(90deg, transparent, rgba(255,255,255,0.1), transparent); + transition: left 0.5s cubic-bezier(0.4, 0, 0.2, 1); +} + +.experience-card:hover .experience-header::after { + left: 100%; +} + +/* Experience Body */ +.experience-body { + padding: var(--card-padding); + background: var(--color-nier-bg); +} + +/* Experience Title */ +.experience-title { + font-family: var(--font-noto-jp); + font-size: 0.95rem; + font-weight: 400; + letter-spacing: 0.02em; + line-height: 1.2; + margin: 0; + text-shadow: 0 1px 2px rgba(0,0,0,0.1); +} + +/* Status Badge */ +.status-badge { + padding: 0.375rem 0.75rem; + font-size: 0.7rem; + font-family: var(--font-terminal-retro); + text-transform: uppercase; + letter-spacing: 0.1em; + border-radius: 20px; + margin-bottom: 0.5rem; + display: inline-block; + box-shadow: 0 2px 4px rgba(0,0,0,0.1); + transition: var(--transition-smooth); +} + +.current-status { + background: linear-gradient(135deg, #4ade80 0%, #22c55e 100%); + color: white; +} + +.completed-status { + background: linear-gradient(135deg, var(--color-nier-accent) 0%, var(--color-nier-highlight) 100%); + color: var(--color-nier-text-light); +} + +/* Detail Blocks */ +.detail-block { + margin-bottom: var(--card-gap); + padding: 0.25rem; + border-left: 2px solid transparent; + transition: border-color 0.3s ease, padding-left 0.3s ease; +} + +.detail-block:hover { + border-left-color: var(--color-nier-accent); + padding-left: 0.5rem; +} + +.detail-label { + font-family: var(--font-terminal); + font-size: 0.75rem; + color: var(--color-nier-text-dark); + font-weight: 500; + text-transform: uppercase; + letter-spacing: 0.05em; + display: block; + margin-bottom: 0.25rem; + opacity: 0.8; + transition: opacity 0.3s ease; +} + +.detail-block:hover .detail-label { + opacity: 1; +} + +.detail-value { + font-family: var(--font-noto-jp); + color: var(--color-nier-text-dark); + font-size: 0.85rem; + line-height: 1.4; + display: block; +} + +/* Tech Stack Section */ +.tech-section { + margin-top: var(--card-gap); + padding-top: var(--card-gap); + border-top: 1px solid var(--color-nier-border); + position: relative; +} + +.tech-section::before { + content: ''; + position: absolute; + top: 0; + left: 0; + width: 0; + height: 1px; + background: var(--color-nier-accent); + animation: expandLine 0.6s ease-out calc(var(--animation-delay-base) * 12) forwards; +} + +.tech-grid { + display: flex; + flex-wrap: wrap; + gap: 0.25rem; + margin-top: 0.5rem; +} + +/* Tech Items */ +.tech-item { + background: linear-gradient(135deg, var(--color-nier-accent) 0%, var(--color-nier-highlight) 100%); + color: var(--color-nier-text-light); + padding: 0.25rem 0.5rem; + font-size: 0.7rem; + font-family: var(--font-terminal); + text-transform: uppercase; + letter-spacing: 0.05em; + border-radius: 3px; + white-space: nowrap; + transition: var(--transition-smooth); + box-shadow: 0 2px 4px rgba(0,0,0,0.1); + + /* Initial state for staggered animation */ + opacity: 0; + transform: scale(0.8) translateY(10px); + animation: techItemFadeIn 0.4s ease-out forwards; +} + +/* Staggered animation delays for tech items */ +.tech-item:nth-child(1) { animation-delay: calc(var(--animation-delay-base) * 13); } +.tech-item:nth-child(2) { animation-delay: calc(var(--animation-delay-base) * 14); } +.tech-item:nth-child(3) { animation-delay: calc(var(--animation-delay-base) * 15); } +.tech-item:nth-child(4) { animation-delay: calc(var(--animation-delay-base) * 16); } +.tech-item:nth-child(5) { animation-delay: calc(var(--animation-delay-base) * 17); } +.tech-item:nth-child(n+6) { animation-delay: calc(var(--animation-delay-base) * 18); } + +.tech-item:hover { + transform: translateY(-2px) scale(1.05); + box-shadow: 0 6px 12px rgba(0,0,0,0.2); +} + +/* Visual Effects */ +.corner-accent { + position: absolute; + top: 0; + right: 0; + width: 0; + height: 0; + border-left: 10px solid transparent; + border-top: 10px solid var(--color-nier-accent); + opacity: 0; + transition: opacity 0.3s ease; + animation: fadeIn 0.3s ease-out calc(var(--animation-delay-base) * 11) forwards; +} + +.experience-card:hover .corner-accent { + opacity: 1; + animation: none; +} + +.scan-line { + position: absolute; + top: 0; + left: 0; + right: 0; + height: 2px; + background: linear-gradient(90deg, transparent, var(--color-nier-accent), transparent); + will-change: transform; + opacity: 0; + animation: scanFadeIn 0.4s ease-out calc(var(--animation-delay-base) * 12) forwards, scan 4s ease-in-out calc(var(--animation-delay-base) * 15) infinite; +} + +/* Keyframe animations */ +@keyframes fadeInUp { + from { + opacity: 0; + transform: translateY(20px); + } + to { + opacity: 1; + transform: translateY(0); + } +} + +@keyframes enableColumnScrollAfterAnimation { + to { + overflow-y: auto; + } +} + +@keyframes slideInLeft { + from { + opacity: 0; + transform: translateX(-10px); + } + to { + opacity: 1; + transform: translateX(0); + } +} + +@keyframes cardFadeIn { + from { + opacity: 0; + transform: translateY(30px) scale(0.95); + } + to { + opacity: 1; + transform: translateY(0) scale(1); + } +} + +@keyframes techItemFadeIn { + from { + opacity: 0; + transform: scale(0.8) translateY(10px); + } + to { + opacity: 1; + transform: scale(1) translateY(0); + } +} + +@keyframes expandLine { + from { + width: 0; + } + to { + width: 30%; + } +} + +@keyframes fadeIn { + from { + opacity: 0; + } + to { + opacity: 1; + } +} + +@keyframes scanFadeIn { + from { + opacity: 0; + } + to { + opacity: 1; + } +} + +@keyframes scan { + 0% { + transform: translateX(-100%); + } + 100% { + transform: translateX(100%); + } +} + +/* Performance Optimizations */ +.experience-card, +.tech-item { + backface-visibility: hidden; + -webkit-backface-visibility: hidden; +} + +/* Responsive Design - Professional Column Specific */ +@media (max-width: 480px) { + .professional-column { + gap: 0.5rem; + padding-right: 0.25rem; + + /* Ensure columns are visible on mobile */ + min-height: auto; + + /* Simplified mobile column animations */ + animation-name: fadeInUp, enableColumnScrollAfterAnimation; + animation-duration: 0.3s, 0s; + animation-timing-function: ease-out, ease-out; + animation-delay: 0.15s, 1.5s; + animation-fill-mode: forwards, forwards; + } + + .column-title { + font-size: 0.9rem; + padding: 0.375rem; + margin-bottom: 0.5rem; + + /* Simplified title animation */ + animation-name: slideInLeft; + animation-duration: 0.3s; + animation-timing-function: ease-out; + animation-delay: 0.3s; + animation-fill-mode: forwards; + } + + .experience-list { + gap: 0.5rem; + } + + .experience-card { + margin-bottom: 0.5rem; + border-radius: 6px; + + /* Simplified card animations */ + animation-name: cardFadeIn; + animation-duration: 0.3s; + animation-timing-function: ease-out; + animation-delay: 0.4s; + animation-fill-mode: forwards; + } + + .experience-header { + padding: 0.75rem 0.5rem 0.5rem 0.5rem; + } + + .experience-body { + padding: 0.75rem 0.5rem; + } + + .experience-title { + font-size: 0.9rem; + line-height: 1.3; + margin-bottom: 0.25rem; + } + + .status-badge { + padding: 0.375rem 0.75rem; + font-size: 0.7rem; + margin-bottom: 0.75rem; + } + + .detail-block { + margin-bottom: 1rem; + padding: 0.5rem 0.25rem; + } + + .detail-label { + font-size: 0.7rem; + margin-bottom: 0.375rem; + } + + .detail-value { + font-size: 0.8rem; + line-height: 1.4; + } + + .tech-section { + margin-top: 1.25rem; + padding-top: 1rem; + } + + .tech-item { + padding: 0.25rem 0.5rem; + font-size: 0.7rem; + margin-bottom: 0.25rem; + + /* Simplified tech item animation */ + animation-name: techItemFadeIn; + animation-duration: 0.2s; + animation-timing-function: ease-out; + animation-delay: 0.6s; + animation-fill-mode: forwards; + } + + /* Remove complex animations on very small screens */ + @media (max-width: 360px) { + .experience-card, + .tech-item, + .corner-accent, + .scan-line { + animation: none !important; + opacity: 1 !important; + transform: none !important; + } + } +} + +@media (max-width: 768px) and (min-width: 481px) { + .column-title { + font-size: 0.95rem; + } + + .experience-title { + font-size: 0.9rem; + } + + .detail-value { + font-size: 0.8rem; + } +} + +/* Reduced Motion Support - Professional Column */ +@media (prefers-reduced-motion: reduce) { + .professional-column, + .column-title, + .experience-card, + .tech-item, + .corner-accent, + .scan-line, + .tech-section::before { + animation: none !important; + transition: none !important; + opacity: 1 !important; + transform: none !important; + } +} diff --git a/src/app/pages/experience/operative-history/column-professional-info/column-professional-info.component.html b/src/app/pages/experience/operative-history/column-professional-info/column-professional-info.component.html index 816caf0..c16e5ff 100644 --- a/src/app/pages/experience/operative-history/column-professional-info/column-professional-info.component.html +++ b/src/app/pages/experience/operative-history/column-professional-info/column-professional-info.component.html @@ -1 +1,47 @@ -

column-professional-info works!

+
+

[PROFESSIONAL_ARCHIVE]

+ +
+ @for (experience of experiences(); track experience.id) { +
+
+ @if (experience.status === 'current') { +
+ } + +
+
+ {{ experience.statusLabel }} +
+

+ {{ experience.title }} +

+
+ +
+
+ CLASSIFICATION: + {{ experience.classification }} +
+ +
+ TIMELINE: + {{ experience.timeline }} +
+ +
+
TECH_STACK:
+
+ @for (tech of experience.techStack; track tech) { + {{ tech }} + } +
+
+
+
+ } +
+
diff --git a/src/app/pages/experience/operative-history/column-professional-info/column-professional-info.component.ts b/src/app/pages/experience/operative-history/column-professional-info/column-professional-info.component.ts index d374e13..33c560e 100644 --- a/src/app/pages/experience/operative-history/column-professional-info/column-professional-info.component.ts +++ b/src/app/pages/experience/operative-history/column-professional-info/column-professional-info.component.ts @@ -1,11 +1,59 @@ -import { Component } from '@angular/core'; +import { Component, signal } from '@angular/core'; +import { Experience } from '../../../../shared/models/experience.model'; @Component({ selector: 'app-column-professional-info', imports: [], templateUrl: './column-professional-info.component.html', - styleUrl: './column-professional-info.component.css' + styleUrl: './column-professional-info.component.css', }) export class ColumnProfessionalInfoComponent { + private readonly _experiences = signal([ + { + id: 'senior-specialist', + title: 'PYTHON_API_SPECIALIST.EXE', + classification: 'Python & Django API/RPA Specialist', + objective: + 'Specialized in Python/Django development for API automation and RPA processes. Led technical interventions for complex enterprise HR system integrations, developing robust solutions that bridge business requirements with technical implementation.', + timeline: 'UKG | January 2024 - January 2025', + techStack: ['PYTHON', 'DJANGO', 'API', 'RPA'] as const, + status: 'completed', + statusLabel: 'ARCHIVED | SME_SPECIALIST', + }, + { + id: 'specialist-ii', + title: 'SYSTEMS_INTEGRATION_SME.EXE', + classification: 'Enterprise Systems Integration', + objective: + 'Subject Matter Expert (SME) for enterprise HRSD connectors and system integrations. Specialized in complex technical challenges involving API development, RPA automation, and SFTP protocols. Provided BI support and data visualization solutions.', + timeline: 'UKG | January 2023 - January 2024', + techStack: ['PYTHON', 'DJANGO', 'API', 'RPA'] as const, + status: 'completed', + statusLabel: 'ARCHIVED | SME_SPECIALIST', + }, + { + id: 'specialist', + title: 'SOLUTION_SUPPORT.EXE', + classification: 'B2B Solution Support', + objective: + 'Delivered high-level technical support for VIP business clients using HRSD solutions. Developed expertise in SaaS platforms and enterprise decision-making processes while managing critical client relationships.', + timeline: 'UKG | October 2021 - January 2023', + techStack: ['SAAS', 'HRSD', 'CLIENT_MGMT'] as const, + status: 'completed', + statusLabel: 'ARCHIVED | VIP_TIER', + }, + { + id: 'technician', + title: 'IT_TECHNICIAN.EXE', + classification: 'Information Technology Technician', + objective: + 'Provided VIP end-user support, managed hardware/software deployments, and implemented networking and information security practices in a mission-critical environment.', + timeline: 'Armée de Terre | July 2018 - December 2018', + techStack: ['NETWORKING', 'SECURITY', 'DEPLOYMENT'] as const, + status: 'completed', + statusLabel: 'ARCHIVED | MILITARY', + }, + ] as const); + readonly experiences = this._experiences.asReadonly(); } diff --git a/src/app/pages/experience/operative-history/operative-history.component.css b/src/app/pages/experience/operative-history/operative-history.component.css index a4a9918..1318b70 100644 --- a/src/app/pages/experience/operative-history/operative-history.component.css +++ b/src/app/pages/experience/operative-history/operative-history.component.css @@ -1,21 +1,7 @@ -/* Optimized Component Styles - Global theme variables already available */ +/* Parent Container Styles */ -:host { - font-family: var(--font-noto-jp); - letter-spacing: -0.02em; - line-height: 1.5; - display: block; - width: 100%; - height: 100%; - overflow: hidden; - - /* Faster initial fade-in animation */ - opacity: 0; - animation: fadeInHost 0.6s ease-out 0.05s forwards; -} - -/* CSS Custom Properties for reusability */ -:host { +/* CSS Custom Properties - Define these at parent level for child components */ +.operative-history-container { --card-padding: 0.75rem; --card-gap: 0.75rem; --border-radius: 4px; @@ -40,435 +26,12 @@ overflow: hidden; animation: enableScrollAfterAnimation 0s ease-out 3s forwards; - /* Faster container fade-in */ + /* Container fade-in */ opacity: 0; animation: fadeInContainer 0.5s ease-out 0.15s forwards, enableScrollAfterAnimation 0s ease-out 3s forwards; } -/* Column Base Styles */ -.column { - display: flex; - flex-direction: column; - gap: var(--card-gap); - min-height: 0; - padding-right: 0.5rem; - - /* Hide overflow initially */ - overflow: hidden; - animation: enableColumnScrollAfterAnimation 0s ease-out 3s forwards; - - /* Initial state for animation */ - opacity: 0; - transform: translateY(20px); -} - -/* Faster staggered column animations */ -.professional-column { - animation: fadeInUp var(--animation-duration) ease-out calc(var(--animation-delay-base) * 3) forwards, enableColumnScrollAfterAnimation 0s ease-out 3s forwards; -} - -.education-column { - animation: fadeInUp var(--animation-duration) ease-out calc(var(--animation-delay-base) * 4) forwards, enableColumnScrollAfterAnimation 0s ease-out 3s forwards; -} - -.personal-column { - animation: fadeInUp var(--animation-duration) ease-out calc(var(--animation-delay-base) * 5) forwards, enableColumnScrollAfterAnimation 0s ease-out 3s forwards; -} - -/* Sticky Column Titles */ -.column-title { - font-family: var(--font-terminal); - font-size: 1rem; - color: var(--color-nier-accent); - letter-spacing: 0.1em; - text-align: center; - margin-bottom: var(--card-gap); - padding: 0.5rem; - border-bottom: 1px solid var(--color-nier-border); - flex-shrink: 0; - position: sticky; - top: 0; - background: var(--color-nier-bg); - z-index: 10; - - /* Title animation */ - opacity: 0; - transform: translateX(-10px); - animation: slideInLeft 0.4s ease-out calc(var(--animation-delay-base) * 7) forwards; -} - -/* Base Card Styles */ -.experience-card, -.info-card { - border: 2px solid var(--color-nier-border); - background: var(--color-nier-bg); - position: relative; - transition: var(--transition-smooth); - margin-bottom: var(--card-gap); - flex-shrink: 0; - border-radius: var(--border-radius); - - /* Card initial state */ - opacity: 0; - transform: translateY(30px) scale(0.95); - will-change: transform, opacity; -} - -/* Staggered card animations */ -.experience-card { - animation: cardFadeIn var(--animation-duration) ease-out calc(var(--animation-delay-base) * 9) forwards; -} - -.info-card { - animation: cardFadeIn var(--animation-duration) ease-out calc(var(--animation-delay-base) * 10) forwards; -} - -/* Enhanced Card Hover Effects */ -.experience-card:hover, -.info-card:hover { - transform: translateY(-2px) scale(1.02); - box-shadow: var(--shadow-hover); - border-color: var(--color-nier-accent); -} - -.info-card:hover { - transform: translateY(-1px) scale(1.01); - box-shadow: var(--shadow-subtle); -} - -/* Optimized Card Overlay Effect */ -.experience-card::before { - content: ''; - position: absolute; - inset: 0; - background: linear-gradient(135deg, transparent 0%, rgba(41, 41, 37, 0.05) 100%); - opacity: 0; - transition: opacity 0.3s ease; - pointer-events: none; -} - -.experience-card:hover::before { - opacity: 1; -} - -/* Active Training Highlight */ -.active-training { - border-color: var(--color-nier-accent); - animation: cardFadeIn var(--animation-duration) ease-out calc(var(--animation-delay-base) * 9) forwards; -} - -/* Optimized Card Headers */ -.experience-header, -.info-header { - background: linear-gradient(135deg, var(--color-nier-dark) 0%, var(--color-nier-highlight) 100%); - color: var(--color-nier-text-light); - padding: var(--card-padding); - border-bottom: 2px solid var(--color-nier-border); - position: relative; - overflow: hidden; -} - -.info-header { - padding: 0.5rem; - font-family: var(--font-terminal); - font-size: 0.8rem; - text-transform: uppercase; - letter-spacing: 0.05em; -} - -/* Enhanced Shimmer Effect */ -.experience-header::after { - content: ''; - position: absolute; - top: 0; - left: -100%; - width: 100%; - height: 100%; - background: linear-gradient(90deg, transparent, rgba(255,255,255,0.1), transparent); - transition: left 0.5s cubic-bezier(0.4, 0, 0.2, 1); -} - -.experience-card:hover .experience-header::after { - left: 100%; -} - -/* Card Body Optimization */ -.experience-body, -.info-content { - padding: var(--card-padding); - background: var(--color-nier-bg); -} - -.info-content { - font-size: 0.85rem; - line-height: 1.4; -} - -/* Typography Scale */ -.experience-title { - font-family: var(--font-noto-jp); - font-size: 0.95rem; - font-weight: 400; - letter-spacing: 0.02em; - line-height: 1.2; - margin: 0; - text-shadow: 0 1px 2px rgba(0,0,0,0.1); -} - -/* Enhanced Detail Blocks */ -.detail-block { - margin-bottom: var(--card-gap); - padding: 0.25rem; - border-left: 2px solid transparent; - transition: border-color 0.3s ease, padding-left 0.3s ease; -} - -.detail-block:hover { - border-left-color: var(--color-nier-accent); - padding-left: 0.5rem; -} - -.detail-label { - font-family: var(--font-terminal); - font-size: 0.75rem; - color: var(--color-nier-text-dark); - font-weight: 500; - text-transform: uppercase; - letter-spacing: 0.05em; - display: block; - margin-bottom: 0.25rem; - opacity: 0.8; - transition: opacity 0.3s ease; -} - -.detail-block:hover .detail-label { - opacity: 1; -} - -.detail-value { - font-family: var(--font-noto-jp); - color: var(--color-nier-text-dark); - font-size: 0.85rem; - line-height: 1.4; - display: block; -} - -/* Enhanced Tech Stack Section */ -.tech-section { - margin-top: var(--card-gap); - padding-top: var(--card-gap); - border-top: 1px solid var(--color-nier-border); - position: relative; -} - -.tech-section::before { - content: ''; - position: absolute; - top: 0; - left: 0; - width: 0; - height: 1px; - background: var(--color-nier-accent); - animation: expandLine 0.6s ease-out calc(var(--animation-delay-base) * 12) forwards; -} - -.tech-grid { - display: flex; - flex-wrap: wrap; - gap: 0.25rem; - margin-top: 0.5rem; -} - -/* Enhanced Tech & Trait Items */ -.tech-item, -.trait-item { - background: linear-gradient(135deg, var(--color-nier-accent) 0%, var(--color-nier-highlight) 100%); - color: var(--color-nier-text-light); - padding: 0.25rem 0.5rem; - font-size: 0.7rem; - font-family: var(--font-terminal); - text-transform: uppercase; - letter-spacing: 0.05em; - border-radius: 3px; - white-space: nowrap; - transition: var(--transition-smooth); - box-shadow: 0 2px 4px rgba(0,0,0,0.1); - - /* Initial state for staggered animation */ - opacity: 0; - transform: scale(0.8) translateY(10px); - animation: techItemFadeIn 0.4s ease-out forwards; -} - -/* Staggered animation delays for tech items */ -.tech-item:nth-child(1) { animation-delay: calc(var(--animation-delay-base) * 13); } -.tech-item:nth-child(2) { animation-delay: calc(var(--animation-delay-base) * 14); } -.tech-item:nth-child(3) { animation-delay: calc(var(--animation-delay-base) * 15); } -.tech-item:nth-child(4) { animation-delay: calc(var(--animation-delay-base) * 16); } -.tech-item:nth-child(5) { animation-delay: calc(var(--animation-delay-base) * 17); } -.tech-item:nth-child(n+6) { animation-delay: calc(var(--animation-delay-base) * 18); } - -.tech-item:hover, -.trait-item:hover { - transform: translateY(-2px) scale(1.05); - box-shadow: 0 6px 12px rgba(0,0,0,0.2); -} - -.trait-item { - padding: 0.375rem 0.25rem; - text-align: center; - animation-delay: calc(var(--animation-delay-base) * 19); -} - -/* Enhanced Status Badges */ -.current-status, -.completed-status { - padding: 0.375rem 0.75rem; - font-size: 0.7rem; - font-family: var(--font-terminal-retro); - text-transform: uppercase; - letter-spacing: 0.1em; - border-radius: 20px; - margin-bottom: 0.5rem; - display: inline-block; - box-shadow: 0 2px 4px rgba(0,0,0,0.1); - transition: var(--transition-smooth); -} - -.current-status { - background: linear-gradient(135deg, #4ade80 0%, #22c55e 100%); - color: white; -} - -.completed-status { - background: linear-gradient(135deg, var(--color-nier-accent) 0%, var(--color-nier-highlight) 100%); - color: var(--color-nier-text-light); -} - -/* Personal Info Grid */ -.trait-grid { - display: grid; - grid-template-columns: repeat(2, 1fr); - gap: 0.25rem; -} - -.interest-item { - margin-bottom: 0.5rem; - display: flex; - align-items: center; - padding: 0.25rem; - border-radius: 2px; - transition: background-color 0.3s ease, transform 0.3s ease; - - /* Interest item animation */ - opacity: 0; - transform: translateX(-10px); - animation: slideInLeft 0.3s ease-out calc(var(--animation-delay-base) * 20) forwards; -} - -.interest-item:hover { - background-color: rgba(41, 41, 37, 0.05); - transform: translateX(2px); -} - -.interest-label { - font-family: var(--font-terminal); - font-size: 0.7rem; - color: var(--color-nier-text-dark); - text-transform: uppercase; - letter-spacing: 0.05em; - width: 60px; - flex-shrink: 0; - opacity: 0.8; - margin-right: 1rem; -} - -.interest-value { - font-family: var(--font-noto-jp); - font-size: 0.8rem; - color: var(--color-nier-text-dark); -} - -/* Enhanced Philosophy Section */ -.philosophy-text { - font-size: 0.8rem; - line-height: 1.5; - font-style: italic; - margin-bottom: var(--card-gap); - position: relative; - padding-left: 1rem; - - /* Philosophy text animation */ - opacity: 0; - animation: fadeIn 0.6s ease-out calc(var(--animation-delay-base) * 22) forwards; -} - -.philosophy-text::before { - content: '"'; - position: absolute; - left: 0; - top: -0.25rem; - font-size: 1.5rem; - color: var(--color-nier-accent); - opacity: 0; - animation: fadeIn 0.4s ease-out calc(var(--animation-delay-base) * 23) forwards; -} - -.philosophy-note { - font-family: var(--font-terminal); - font-size: 0.75rem; - color: var(--color-nier-text-dark); - opacity: 0; - margin-top: var(--card-gap); - padding-top: var(--card-gap); - border-top: 1px solid var(--color-nier-border); - line-height: 1.4; - animation: fadeIn 0.4s ease-out calc(var(--animation-delay-base) * 24) forwards; -} - -/* Visual Effects */ -.corner-accent { - position: absolute; - top: 0; - right: 0; - width: 0; - height: 0; - border-left: 10px solid transparent; - border-top: 10px solid var(--color-nier-accent); - opacity: 0; - transition: opacity 0.3s ease; - animation: fadeIn 0.3s ease-out calc(var(--animation-delay-base) * 11) forwards; -} - -.experience-card:hover .corner-accent { - opacity: 1; - animation: none; -} - -.scan-line { - position: absolute; - top: 0; - left: 0; - right: 0; - height: 2px; - background: linear-gradient(90deg, transparent, var(--color-nier-accent), transparent); - will-change: transform; - opacity: 0; - animation: scanFadeIn 0.4s ease-out calc(var(--animation-delay-base) * 12) forwards, scan 4s ease-in-out calc(var(--animation-delay-base) * 15) infinite; -} - /* Keyframe Animations */ -@keyframes fadeInHost { - from { - opacity: 0; - transform: scale(0.98); - } - to { - opacity: 1; - transform: scale(1); - } -} - @keyframes fadeInContainer { from { opacity: 0; @@ -480,86 +43,6 @@ } } -@keyframes fadeInUp { - from { - opacity: 0; - transform: translateY(20px); - } - to { - opacity: 1; - transform: translateY(0); - } -} - -@keyframes slideInLeft { - from { - opacity: 0; - transform: translateX(-10px); - } - to { - opacity: 1; - transform: translateX(0); - } -} - -@keyframes cardFadeIn { - from { - opacity: 0; - transform: translateY(30px) scale(0.95); - } - to { - opacity: 1; - transform: translateY(0) scale(1); - } -} - -@keyframes techItemFadeIn { - from { - opacity: 0; - transform: scale(0.8) translateY(10px); - } - to { - opacity: 1; - transform: scale(1) translateY(0); - } -} - -@keyframes expandLine { - from { - width: 0; - } - to { - width: 30%; - } -} - -@keyframes fadeIn { - from { - opacity: 0; - } - to { - opacity: 1; - } -} - -@keyframes scanFadeIn { - from { - opacity: 0; - } - to { - opacity: 1; - } -} - -@keyframes scan { - 0% { - transform: translateX(-100%); - } - 100% { - transform: translateX(100%); - } -} - /* Enable scrollbars after animations complete */ @keyframes enableScrollAfterAnimation { to { @@ -567,76 +50,8 @@ } } -@keyframes enableColumnScrollAfterAnimation { - to { - overflow-y: auto; - } -} - -/* Performance Optimizations */ -.experience-card, -.info-card, -.tech-item, -.trait-item { - backface-visibility: hidden; - -webkit-backface-visibility: hidden; -} - -/* Reduced Motion Support */ -@media (prefers-reduced-motion: reduce) { - :host, - .operative-history-container, - .column, - .column-title, - .experience-card, - .info-card, - .tech-item, - .trait-item, - .interest-item, - .philosophy-text, - .philosophy-text::before, - .philosophy-note, - .corner-accent, - .scan-line, - .tech-section::before { - animation: none !important; - transition: none !important; - } - - :host, - .operative-history-container, - .column, - .column-title, - .experience-card, - .info-card, - .tech-item, - .trait-item, - .interest-item, - .philosophy-text, - .philosophy-note, - .corner-accent { - opacity: 1 !important; - transform: none !important; - } - - .operative-history-container, - .column { - overflow-y: auto !important; - } -} - -/* Responsive Design - Optimized */ +/* Responsive Design */ @media (max-width: 480px) { - :host { - padding: 0; - /* Fallback for browsers that don't support multiple animations */ - animation-name: fadeInHost; - animation-duration: 0.6s; - animation-timing-function: ease-out; - animation-delay: 0.05s; - animation-fill-mode: forwards; - } - .operative-history-container { grid-template-columns: 1fr; gap: 0.5rem; @@ -653,221 +68,12 @@ animation-fill-mode: forwards, forwards; } - .column { - gap: 0.5rem; - padding-right: 0.25rem; - - /* Ensure columns are visible on mobile */ - min-height: auto; - - /* Simplified mobile column animations */ - animation-name: fadeInUp, enableColumnScrollAfterAnimation; - animation-duration: 0.3s, 0s; - animation-timing-function: ease-out, ease-out; - animation-fill-mode: forwards, forwards; - } - - .professional-column { - animation-delay: 0.15s, 1.5s; - } - - .education-column { - animation-delay: 0.2s, 1.5s; - } - - .personal-column { - animation-delay: 0.25s, 1.5s; - } - - .column-title { - font-size: 0.9rem; - padding: 0.375rem; - margin-bottom: 0.5rem; - - /* Simplified title animation */ - animation-name: slideInLeft; - animation-duration: 0.3s; - animation-timing-function: ease-out; - animation-delay: 0.3s; - animation-fill-mode: forwards; - } - - .experience-card, - .info-card { - margin-bottom: 0.5rem; - border-radius: 6px; - - /* Simplified card animations */ - animation-name: cardFadeIn; - animation-duration: 0.3s; - animation-timing-function: ease-out; - animation-fill-mode: forwards; - } - - .experience-card { - animation-delay: 0.4s; - } - - .info-card { - animation-delay: 0.5s; - } - - .experience-header, - .info-header { - padding: 0.75rem 0.5rem 0.5rem 0.5rem; - } - - .experience-body, - .info-content { - padding: 0.75rem 0.5rem; - } - - .experience-title { - font-size: 0.9rem; - line-height: 1.3; - margin-bottom: 0.25rem; - } - - .detail-block { - margin-bottom: 1rem; - padding: 0.5rem 0.25rem; - } - - .detail-label { - font-size: 0.7rem; - margin-bottom: 0.375rem; - } - - .detail-value { - font-size: 0.8rem; - line-height: 1.4; - } - - .tech-section { - margin-top: 1.25rem; - padding-top: 1rem; - } - - .tech-item { - padding: 0.25rem 0.5rem; - font-size: 0.7rem; - margin-bottom: 0.25rem; - - /* Simplified tech item animation */ - animation-name: techItemFadeIn; - animation-duration: 0.2s; - animation-timing-function: ease-out; - animation-delay: 0.6s; - animation-fill-mode: forwards; - } - - .current-status, - .completed-status { - padding: 0.375rem 0.75rem; - font-size: 0.7rem; - margin-bottom: 0.75rem; - } - - .trait-grid { - grid-template-columns: 1fr; - gap: 0.375rem; - } - - .trait-item { - padding: 0.5rem 0.375rem; - font-size: 0.75rem; - - /* Simplified trait animation */ - animation-name: techItemFadeIn; - animation-duration: 0.2s; - animation-timing-function: ease-out; - animation-delay: 0.7s; - animation-fill-mode: forwards; - } - - .interest-item { - margin-bottom: 0.75rem; - padding: 0.5rem 0.25rem; - - /* Simplified interest animation */ - animation-name: slideInLeft; - animation-duration: 0.2s; - animation-timing-function: ease-out; - animation-delay: 0.8s; - animation-fill-mode: forwards; - } - - .interest-label { - font-size: 0.75rem; - width: 70px; - } - - .interest-value { - font-size: 0.85rem; - } - - .philosophy-text { - font-size: 0.8rem; - padding-left: 0.75rem; - line-height: 1.5; - margin-bottom: 1rem; - - /* Simplified philosophy animation */ - animation-name: fadeIn; - animation-duration: 0.3s; - animation-timing-function: ease-out; - animation-delay: 0.9s; - animation-fill-mode: forwards; - } - - .philosophy-text::before { - /* Simple fade for quote mark */ - animation-name: fadeIn; - animation-duration: 0.2s; - animation-timing-function: ease-out; - animation-delay: 1s; - animation-fill-mode: forwards; - } - - .philosophy-note { - font-size: 0.75rem; - line-height: 1.4; - padding-top: 1rem; - - /* Simplified note animation */ - animation-name: fadeIn; - animation-duration: 0.2s; - animation-timing-function: ease-out; - animation-delay: 1.1s; - animation-fill-mode: forwards; - } - - .info-content { - font-size: 0.85rem; - line-height: 1.4; - } - /* Remove complex animations on very small screens */ @media (max-width: 360px) { - :host, - .operative-history-container, - .column, - .column-title, - .experience-card, - .info-card, - .tech-item, - .trait-item, - .interest-item, - .philosophy-text, - .philosophy-text::before, - .philosophy-note { + .operative-history-container { animation: none !important; opacity: 1 !important; transform: none !important; - } - - .operative-history-container, - .column { overflow-y: auto !important; } } @@ -878,19 +84,6 @@ grid-template-columns: 1fr; gap: 0.75rem; } - - .column-title { - font-size: 0.95rem; - } - - .experience-title { - font-size: 0.9rem; - } - - .detail-value, - .info-content { - font-size: 0.8rem; - } } @media (max-width: 1200px) and (min-width: 769px) { @@ -898,18 +91,21 @@ grid-template-columns: repeat(2, 1fr); gap: 0.75rem; } - - .personal-column { - grid-column: 1 / -1; - } } @media (min-width: 1201px) { .operative-history-container { gap: 1.25rem; } +} - .column { - padding-right: 0.75rem; +/* Reduced Motion Support */ +@media (prefers-reduced-motion: reduce) { + .operative-history-container { + animation: none !important; + transition: none !important; + opacity: 1 !important; + transform: none !important; + overflow-y: auto !important; } } diff --git a/src/app/pages/experience/operative-history/operative-history.component.html b/src/app/pages/experience/operative-history/operative-history.component.html index 1ceddd1..3c77f11 100644 --- a/src/app/pages/experience/operative-history/operative-history.component.html +++ b/src/app/pages/experience/operative-history/operative-history.component.html @@ -1,98 +1,7 @@
- -
-

[PROFESSIONAL_ARCHIVE]

+ -
- @for (experience of experiences(); track experience.id) { -
-
- @if (experience.status === 'current') { -
- } - -
-
- {{ experience.statusLabel }} -
-

- {{ experience.title }} -

-
- -
-
- CLASSIFICATION: - {{ experience.classification }} -
- -
- TIMELINE: - {{ experience.timeline }} -
- -
-
TECH_STACK:
-
- @for (tech of experience.techStack; track tech) { - {{ tech }} - } -
-
-
-
- } -
-
- - -
-

[EDUCATION_PROTOCOL]

- - @if (currentTraining(); as training) { -
-
-
- -
-
{{ training.statusLabel }}
-

{{ training.title }}

-
- -
-
- PROGRAM: - {{ training.classification }} -
- -
- INSTITUTION: - {{ training.timeline }} -
- -
-
CURRICULUM:
-
- @for (tech of training.techStack; track tech) { - {{ tech }} - } -
-
-
-
- } - - -
-
ACADEMIC_FOCUS
-
-

Full-stack development specialization with emphasis on modern web technologies and enterprise-grade solutions.

-
-
-
+
diff --git a/src/app/pages/experience/operative-history/operative-history.component.ts b/src/app/pages/experience/operative-history/operative-history.component.ts index 2f33c31..4d4bc34 100644 --- a/src/app/pages/experience/operative-history/operative-history.component.ts +++ b/src/app/pages/experience/operative-history/operative-history.component.ts @@ -2,6 +2,8 @@ import { Component, signal, computed } from '@angular/core'; import { CommonModule } from '@angular/common'; import { ColumnPersonalInfoComponent } from './column-personal-info/column-personal-info.component'; +import { ColumnEducationInfoComponent } from './column-education-info/column-education-info.component'; +import { ColumnProfessionalInfoComponent } from './column-professional-info/column-professional-info.component'; interface Experience { readonly id: string; @@ -18,84 +20,13 @@ interface Experience { @Component({ selector: 'app-operative-history', standalone: true, - imports: [CommonModule, ColumnPersonalInfoComponent], + imports: [ + CommonModule, + ColumnPersonalInfoComponent, + ColumnEducationInfoComponent, + ColumnProfessionalInfoComponent, + ], templateUrl: './operative-history.component.html', styleUrl: './operative-history.component.css', }) -export class OperativeHistoryComponent { - // Signals for reactive data - private readonly _experiences = signal([ - { - id: 'senior-specialist', - title: 'PYTHON_API_SPECIALIST.EXE', - classification: 'Python & Django API/RPA Specialist', - objective: - 'Specialized in Python/Django development for API automation and RPA processes. Led technical interventions for complex enterprise HR system integrations, developing robust solutions that bridge business requirements with technical implementation.', - timeline: 'UKG | January 2024 - January 2025', - techStack: ['PYTHON', 'DJANGO', 'API', 'RPA'] as const, - status: 'completed', - statusLabel: 'ARCHIVED | SME_SPECIALIST', - }, - { - id: 'specialist-ii', - title: 'SYSTEMS_INTEGRATION_SME.EXE', - classification: 'Enterprise Systems Integration', - objective: - 'Subject Matter Expert (SME) for enterprise HRSD connectors and system integrations. Specialized in complex technical challenges involving API development, RPA automation, and SFTP protocols. Provided BI support and data visualization solutions.', - timeline: 'UKG | January 2023 - January 2024', - techStack: ['PYTHON', 'DJANGO', 'API', 'RPA'] as const, - status: 'completed', - statusLabel: 'ARCHIVED | SME_SPECIALIST', - }, - { - id: 'specialist', - title: 'SOLUTION_SUPPORT.EXE', - classification: 'B2B Solution Support', - objective: - 'Delivered high-level technical support for VIP business clients using HRSD solutions. Developed expertise in SaaS platforms and enterprise decision-making processes while managing critical client relationships.', - timeline: 'UKG | October 2021 - January 2023', - techStack: ['SAAS', 'HRSD', 'CLIENT_MGMT'] as const, - status: 'completed', - statusLabel: 'ARCHIVED | VIP_TIER', - }, - { - id: 'technician', - title: 'IT_TECHNICIAN.EXE', - classification: 'Information Technology Technician', - objective: - 'Provided VIP end-user support, managed hardware/software deployments, and implemented networking and information security practices in a mission-critical environment.', - timeline: 'Armée de Terre | July 2018 - December 2018', - techStack: ['NETWORKING', 'SECURITY', 'DEPLOYMENT'] as const, - status: 'completed', - statusLabel: 'ARCHIVED | MILITARY', - }, - ] as const); - - private readonly _currentTraining = signal({ - id: 'developer-training', - title: 'DEVELOPER_TRAINING.EXE', - classification: "Concepteur Développeur d'Applications (RNCP Level BAC+4)", - objective: - 'Intensive full-stack development program focusing on modern web technologies including TypeScript, Node.js, and contemporary development frameworks. Building comprehensive skills in both frontend and backend development.', - timeline: "École O'clock | January 2025 - October 2025", - techStack: [ - 'TYPESCRIPT', - 'NODE.JS', - 'FULL_STACK', - 'WEB_FRAMEWORKS', - ] as const, - status: 'current', - statusLabel: 'ACTIVE | IN_PROGRESS', - isCurrent: true, - } as const); - - // Public computed signals for template - readonly experiences = this._experiences.asReadonly(); - readonly currentTraining = this._currentTraining.asReadonly(); - - // Computed signals for derived data - readonly totalExperience = computed(() => this.experiences().length); - readonly currentTechStack = computed(() => [ - ...new Set(this.experiences().flatMap((exp) => exp.techStack)), - ]); -} +export class OperativeHistoryComponent {} diff --git a/src/app/shared/models/experience.model.ts b/src/app/shared/models/experience.model.ts new file mode 100644 index 0000000..d132765 --- /dev/null +++ b/src/app/shared/models/experience.model.ts @@ -0,0 +1,13 @@ +type Experience = { + readonly id: string; + readonly title: string; + readonly classification: string; + readonly objective: string; + readonly timeline: string; + readonly techStack: readonly string[]; + readonly status: 'current' | 'completed'; + readonly statusLabel: string; + readonly isCurrent?: boolean; +}; + +export { type Experience };