From 62a5d41086ad2963dd8e9a7daed71c9e7cba22bc Mon Sep 17 00:00:00 2001 From: AdamBtech <60339324+AdamBtech@users.noreply.github.com> Date: Tue, 27 May 2025 20:30:03 +0200 Subject: [PATCH] Added scrollbar and history page --- .../contact-content.component.html | 2 +- .../experience/experience.component.html | 9 +- .../pages/experience/experience.component.ts | 3 +- .../operative-history.component.css | 555 ++++++++++++++++++ .../operative-history.component.html | 143 +++++ .../operative-history.component.ts | 112 ++++ src/styles.css | 168 ++++++ 7 files changed, 988 insertions(+), 4 deletions(-) create mode 100644 src/app/pages/experience/operative-history/operative-history.component.css create mode 100644 src/app/pages/experience/operative-history/operative-history.component.html create mode 100644 src/app/pages/experience/operative-history/operative-history.component.ts diff --git a/src/app/pages/contact/contact-content/contact-content.component.html b/src/app/pages/contact/contact-content/contact-content.component.html index 8ed6915..3feb14b 100644 --- a/src/app/pages/contact/contact-content/contact-content.component.html +++ b/src/app/pages/contact/contact-content/contact-content.component.html @@ -83,7 +83,7 @@ -
+
COLLABORATION STATUS
diff --git a/src/app/pages/experience/experience.component.html b/src/app/pages/experience/experience.component.html index 97807d4..e48996a 100644 --- a/src/app/pages/experience/experience.component.html +++ b/src/app/pages/experience/experience.component.html @@ -1,3 +1,8 @@ -
- +
+
+ +
+ +
+
diff --git a/src/app/pages/experience/experience.component.ts b/src/app/pages/experience/experience.component.ts index 2fa538e..833c4ac 100644 --- a/src/app/pages/experience/experience.component.ts +++ b/src/app/pages/experience/experience.component.ts @@ -1,9 +1,10 @@ import { Component } from '@angular/core'; import { SectionTitleComponent } from '../../components/section-title/section-title.component'; +import { OperativeHistoryComponent } from './operative-history/operative-history.component'; @Component({ selector: 'app-experience', - imports: [SectionTitleComponent], + imports: [SectionTitleComponent, OperativeHistoryComponent], templateUrl: './experience.component.html', styleUrl: './experience.component.css', }) diff --git a/src/app/pages/experience/operative-history/operative-history.component.css b/src/app/pages/experience/operative-history/operative-history.component.css new file mode 100644 index 0000000..53d69f6 --- /dev/null +++ b/src/app/pages/experience/operative-history/operative-history.component.css @@ -0,0 +1,555 @@ +/* Optimized Component Styles - Global theme variables already available */ + +:host { + font-family: var(--font-noto-jp); + letter-spacing: -0.02em; + line-height: 1.5; + display: block; + width: 100%; + height: 100%; + overflow: hidden; +} + +/* CSS Custom Properties for reusability */ +:host { + --card-padding: 0.75rem; + --card-gap: 0.75rem; + --border-radius: 4px; + --transition-smooth: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); + --shadow-hover: 0 8px 25px rgba(41, 41, 37, 0.15); + --shadow-subtle: 0 4px 12px rgba(41, 41, 37, 0.1); +} + +/* Main Grid Layout */ +.operative-history-container { + display: grid; + grid-template-columns: repeat(3, 1fr); + gap: 1rem; + width: 100%; + height: 100%; + max-height: calc(100vh - 8rem); + overflow-y: auto; +} + +/* Column Base Styles */ +.column { + display: flex; + flex-direction: column; + gap: var(--card-gap); + min-height: 0; + overflow-y: auto; + padding-right: 0.5rem; +} + +/* 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; +} + +/* 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); +} + +/* 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); +} + +/* 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: 30%; + height: 1px; + background: var(--color-nier-accent); +} + +.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); +} + +.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; +} + +/* 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: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; +} + +.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::before { + content: '"'; + position: absolute; + left: 0; + top: -0.25rem; + font-size: 1.5rem; + color: var(--color-nier-accent); + opacity: 0.3; +} + +.philosophy-note { + font-family: var(--font-terminal); + font-size: 0.75rem; + color: var(--color-nier-text-dark); + opacity: 0.8; + margin-top: var(--card-gap); + padding-top: var(--card-gap); + border-top: 1px solid var(--color-nier-border); + 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.7; + transition: opacity 0.3s ease; +} + +.experience-card:hover .corner-accent { + opacity: 1; +} + +.scan-line { + position: absolute; + top: 0; + left: 0; + right: 0; + height: 2px; + background: linear-gradient(90deg, transparent, var(--color-nier-accent), transparent); + animation: scan 4s ease-in-out infinite; + will-change: transform; +} + +/* Keyframe Animations */ +@keyframes scan { + 0% { + transform: translateX(-100%); + } + 100% { + transform: translateX(100%); + } +} + +/* Performance Optimizations */ +.experience-card, +.info-card, +.tech-item, +.trait-item { + backface-visibility: hidden; + -webkit-backface-visibility: hidden; +} + +/* Responsive Design - Optimized */ +@media (max-width: 480px) { + :host { + padding: 0; + } + + .operative-history-container { + grid-template-columns: 1fr; + gap: 0.5rem; + max-height: calc(100vh - 6rem); + } + + .column { + gap: 0.5rem; + padding-right: 0.25rem; + } + + .column-title { + font-size: 0.9rem; + padding: 0.375rem; + margin-bottom: 0.5rem; + } + + .experience-card, + .info-card { + margin-bottom: 0.5rem; + border-radius: 6px; + } + + .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; + } + + .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; + } + + .interest-item { + margin-bottom: 0.75rem; + padding: 0.5rem 0.25rem; + } + + .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; + } + + .philosophy-note { + font-size: 0.75rem; + line-height: 1.4; + padding-top: 1rem; + } + + .info-content { + font-size: 0.85rem; + line-height: 1.4; + } +} + +@media (max-width: 768px) and (min-width: 481px) { + .operative-history-container { + 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) { + .operative-history-container { + 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; + } +} diff --git a/src/app/pages/experience/operative-history/operative-history.component.html b/src/app/pages/experience/operative-history/operative-history.component.html new file mode 100644 index 0000000..dde9fcd --- /dev/null +++ b/src/app/pages/experience/operative-history/operative-history.component.html @@ -0,0 +1,143 @@ +
+ +
+

[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.

+
+
+
+ + +
+

[PERSONAL_DATA]

+ +
+
INTERESTS
+
+
+ GENRE: + Science Fiction +
+
+ STUDY: + Philosophy +
+
+ PETS: + 6 Guinea Pigs +
+
+
+ +
+
CORE_TRAITS
+
+
+ CURIOUS + PERSISTENT + ANALYTICAL + CREATIVE +
+
+
+ +
+
PHILOSOPHY
+
+

+ "The most elegant code emerges from understanding both the technical substrate and the consciousness it serves." +

+
+ {{ personalNote() }} +
+
+
+
+
diff --git a/src/app/pages/experience/operative-history/operative-history.component.ts b/src/app/pages/experience/operative-history/operative-history.component.ts new file mode 100644 index 0000000..9653379 --- /dev/null +++ b/src/app/pages/experience/operative-history/operative-history.component.ts @@ -0,0 +1,112 @@ +// operative-history.component.ts +import { Component, signal, computed } from '@angular/core'; +import { CommonModule } from '@angular/common'; + +interface 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; +} + +@Component({ + selector: 'app-operative-history', + standalone: true, + imports: [CommonModule], + 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); + + private readonly _philosophyText = signal([ + 'Four years navigating the intersection between human needs and machine logic has taught me that the most elegant code emerges from understanding both the technical substrate and the consciousness it serves. My journey through enterprise system matrices—from military-grade security protocols to corporate data synthesis—has prepared me for a world where the line between human intention and digital execution grows ever thinner.', + 'I approach development like a philosopher examining the nature of existence: with persistent curiosity and the understanding that every system, no matter how complex, serves a fundamentally human purpose. In a cyberpunk reality where APIs are neural pathways and databases are digital memories, I believe in crafting code that honors both computational efficiency and human dignity.', + 'The future belongs to those who can bridge the organic and the synthetic, who understand that behind every elegant algorithm lies a human story waiting to be told.', + ] as const); + + private readonly _personalNote = signal( + 'In the spaces between keystrokes and compiler runs, I contemplate the philosophical implications of our digital convergence. When not debugging the matrix, I tend to six small organic beings who remind me that even in our increasingly automated world, care and attention to living creatures remains profoundly important.', + ); + + // Public computed signals for template + readonly experiences = this._experiences.asReadonly(); + readonly currentTraining = this._currentTraining.asReadonly(); + readonly philosophyText = this._philosophyText.asReadonly(); + readonly personalNote = this._personalNote.asReadonly(); + + // Computed signals for derived data + readonly totalExperience = computed(() => this.experiences().length); + readonly currentTechStack = computed(() => [ + ...new Set(this.experiences().flatMap((exp) => exp.techStack)), + ]); +} diff --git a/src/styles.css b/src/styles.css index 40900f4..35b4686 100644 --- a/src/styles.css +++ b/src/styles.css @@ -121,4 +121,172 @@ border: 1px solid var(--color-nier-border); transition: all 0.3s ease; } + + /* ===================== NIER CUSTOM SCROLLBAR ===================== */ + + /* Global scrollbar for all elements */ + * { + scrollbar-width: thin; + scrollbar-color: var(--color-nier-accent) var(--color-nier-border); + } + + /* WebKit browsers (Chrome, Safari, Edge) */ + ::-webkit-scrollbar { + width: 12px; + height: 12px; + } + + ::-webkit-scrollbar-track { + background: var(--color-nier-bg); + border: 1px solid var(--color-nier-border); + border-radius: 2px; + } + + ::-webkit-scrollbar-thumb { + background: linear-gradient(135deg, var(--color-nier-accent) 0%, var(--color-nier-highlight) 100%); + border: 1px solid var(--color-nier-border); + border-radius: 1px; + transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); + } + + ::-webkit-scrollbar-thumb:hover { + background: linear-gradient(135deg, var(--color-nier-highlight) 0%, var(--color-nier-accent) 100%); + transform: scale(1.1); + } + + ::-webkit-scrollbar-thumb:active { + background: var(--color-nier-dark); + transform: scale(0.95); + } + + ::-webkit-scrollbar-corner { + background: var(--color-nier-bg); + border: 1px solid var(--color-nier-border); + } + + /* Body scrollbar (main page scroll) */ + body::-webkit-scrollbar { + width: 14px; + } + + body::-webkit-scrollbar-track { + background: var(--color-nier-checkered-bg); + background-size: 8px 8px; + background-image: + linear-gradient(to right, var(--color-nier-checkered-grid) 1px, transparent 1px), + linear-gradient(to bottom, var(--color-nier-checkered-grid) 1px, transparent 1px); + border: 2px solid var(--color-nier-border); + } + + /* Code blocks and pre elements */ + pre::-webkit-scrollbar, + code::-webkit-scrollbar { + width: 8px; + height: 8px; + } + + pre::-webkit-scrollbar-track, + code::-webkit-scrollbar-track { + background: var(--color-nier-dark); + border: 1px solid var(--color-nier-accent); + } + + pre::-webkit-scrollbar-thumb, + code::-webkit-scrollbar-thumb { + background: var(--color-nier-accent); + border: none; + } + + /* Tables */ + table::-webkit-scrollbar { + width: 10px; + height: 10px; + } + + /* Modal and overlay scrollbars */ + .modal::-webkit-scrollbar, + .overlay::-webkit-scrollbar, + .dialog::-webkit-scrollbar, + [role="dialog"]::-webkit-scrollbar { + width: 8px; + } + + .modal::-webkit-scrollbar-track, + .overlay::-webkit-scrollbar-track, + .dialog::-webkit-scrollbar-track, + [role="dialog"]::-webkit-scrollbar-track { + background: var(--color-nier-mid); + border: 1px solid var(--color-nier-border); + } + + /* Responsive adjustments */ + @media (max-width: 768px) { + ::-webkit-scrollbar { + width: 8px; + height: 8px; + } + + body::-webkit-scrollbar { + width: 10px; + } + + ::-webkit-scrollbar-thumb { + border-radius: 4px; + } + } + + /* High contrast mode support */ + @media (prefers-contrast: high) { + ::-webkit-scrollbar-thumb { + background: var(--color-nier-text-dark); + border: 2px solid var(--color-nier-accent); + } + + ::-webkit-scrollbar-track { + background: var(--color-nier-bg); + border: 2px solid var(--color-nier-border); + } + } + + /* Reduced motion support */ + @media (prefers-reduced-motion: reduce) { + ::-webkit-scrollbar-thumb { + transition: none; + transform: none; + } + + ::-webkit-scrollbar-thumb:hover, + ::-webkit-scrollbar-thumb:active { + transform: none; + } + } + + /* Special scrollbar for checkered backgrounds */ + .checkered-bg::-webkit-scrollbar-track, + .checkered-background::-webkit-scrollbar-track { + background: var(--color-nier-checkered-bg); + background-size: 6px 6px; + background-image: + linear-gradient(to right, var(--color-nier-checkered-grid) 1px, transparent 1px), + linear-gradient(to bottom, var(--color-nier-checkered-grid) 1px, transparent 1px); + } + + /* NieR UI specific scrollbars */ + .nier-panel::-webkit-scrollbar, + .nier-menu::-webkit-scrollbar { + width: 10px; + } + + .nier-panel::-webkit-scrollbar-track, + .nier-menu::-webkit-scrollbar-track { + background: var(--color-nier-bg); + border: 2px inset var(--color-nier-border); + } + + .nier-panel::-webkit-scrollbar-thumb, + .nier-menu::-webkit-scrollbar-thumb { + background: var(--color-nier-accent); + border: 1px outset var(--color-nier-highlight); + border-radius: 0; + } }