Add complete planning documentation for CSS architecture refactoring project: - 7-phase implementation plan (92-120 hours) - 123 detailed tasks across all phases - Target: ~3,260 lines CSS reduction (40-50%) - Complete requirements analysis - Progress tracking system - Phase-by-phase breakdown with acceptance criteria Documentation structure: - features/README.md - Project overview and quick start - features/CSS_REFACTORING_PLAN.md - Implementation strategy - features/CSS_REFACTORING_REQUIREMENTS.md - Detailed requirements - features/PROGRESS_TRACKER.md - Live progress tracking - features/phases/*.md - 7 phase documents with tasks Ready to begin Phase 1: Forms Standardization 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
731 lines
15 KiB
Markdown
731 lines
15 KiB
Markdown
# Phase 2: Fundație Pattern-uri Globale 🏗️
|
|
|
|
**Priority:** Foundation pentru future phases
|
|
**Duration:** 8-10 hours
|
|
**Status:** ⏸️ Not Started
|
|
**Risk Level:** Low (additive changes only)
|
|
|
|
---
|
|
|
|
## Obiective
|
|
|
|
1. **Creare fișiere pattern globale** - 5 fișiere CSS noi
|
|
2. **Extract pattern-uri repetate** - Loading spinners, trends, breakdowns
|
|
3. **Design tokens extinse** - Card-specific, animations, interactivity
|
|
4. **PrimeVue overrides centralizate** - Pregătire pentru Phase 3
|
|
5. **Zero modificări vizuale** - Setup fără impact
|
|
|
|
---
|
|
|
|
## Task Breakdown (15 tasks)
|
|
|
|
### 1. File Creation (5 tasks)
|
|
|
|
#### Task 1.1: Create interactive.css
|
|
**Status:** ⏸️ | **Est:** 90 min
|
|
|
|
**File:** `reports-app/frontend/src/assets/css/patterns/interactive.css`
|
|
|
|
```css
|
|
/* Interactive Patterns - ROA2WEB */
|
|
|
|
/* ===== Loading Spinners ===== */
|
|
.loading-spinner {
|
|
width: var(--spinner-size, 40px);
|
|
height: var(--spinner-size, 40px);
|
|
border: 4px solid var(--color-border);
|
|
border-top-color: var(--color-primary);
|
|
border-radius: var(--radius-full);
|
|
animation: spin 1s linear infinite;
|
|
}
|
|
|
|
.loading-spinner-sm {
|
|
--spinner-size: 24px;
|
|
border-width: 3px;
|
|
}
|
|
|
|
.loading-spinner-lg {
|
|
--spinner-size: 56px;
|
|
border-width: 5px;
|
|
}
|
|
|
|
@keyframes spin {
|
|
to { transform: rotate(360deg); }
|
|
}
|
|
|
|
/* ===== Trend Indicators ===== */
|
|
.trend {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
gap: var(--space-xs);
|
|
font-size: var(--text-sm);
|
|
font-weight: var(--font-medium);
|
|
}
|
|
|
|
.trend-up {
|
|
color: var(--color-success);
|
|
}
|
|
|
|
.trend-down {
|
|
color: var(--color-error);
|
|
}
|
|
|
|
.trend-neutral {
|
|
color: var(--color-text-secondary);
|
|
}
|
|
|
|
.trend-icon {
|
|
font-size: 0.75rem;
|
|
}
|
|
|
|
/* ===== Collapse/Expand Patterns ===== */
|
|
.collapsible-header {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
cursor: pointer;
|
|
user-select: none;
|
|
padding: var(--space-sm);
|
|
border-radius: var(--radius-sm);
|
|
transition: background-color var(--transition-fast);
|
|
}
|
|
|
|
.collapsible-header:hover {
|
|
background: var(--color-bg-secondary);
|
|
}
|
|
|
|
.collapse-icon {
|
|
font-size: 0.625rem;
|
|
color: var(--color-text-secondary);
|
|
transition: transform var(--transition-fast);
|
|
display: inline-block;
|
|
width: 1rem;
|
|
}
|
|
|
|
.collapse-icon.expanded {
|
|
transform: rotate(90deg);
|
|
}
|
|
|
|
/* ===== Card Hover Effects ===== */
|
|
.card-hover {
|
|
transition: all var(--transition-fast);
|
|
}
|
|
|
|
.card-hover:hover {
|
|
box-shadow: var(--shadow-md);
|
|
transform: translateY(var(--hover-lift, -2px));
|
|
border-color: var(--color-primary);
|
|
}
|
|
|
|
/* ===== Sparkline Containers ===== */
|
|
.sparkline-container {
|
|
width: 100%;
|
|
background: var(--color-bg-secondary);
|
|
border: 1px solid var(--color-border);
|
|
border-radius: var(--radius-sm);
|
|
padding: var(--space-sm);
|
|
}
|
|
|
|
.sparkline-chart {
|
|
width: 100%;
|
|
height: var(--sparkline-height, 80px);
|
|
position: relative;
|
|
}
|
|
|
|
.sparkline-chart-lg {
|
|
--sparkline-height: 150px;
|
|
}
|
|
|
|
.sparkline-canvas {
|
|
width: 100% !important;
|
|
height: 100% !important;
|
|
display: block;
|
|
}
|
|
```
|
|
|
|
**Acceptance Criteria:**
|
|
- [ ] File created in correct location
|
|
- [ ] All patterns documented with comments
|
|
- [ ] CSS variables used throughout
|
|
- [ ] No hardcoded values
|
|
|
|
---
|
|
|
|
#### Task 1.2: Create dashboard.css
|
|
**Status:** ⏸️ | **Est:** 2 hours
|
|
|
|
**File:** `reports-app/frontend/src/assets/css/patterns/dashboard.css`
|
|
|
|
```css
|
|
/* Dashboard Patterns - ROA2WEB */
|
|
|
|
/* ===== Page Headers ===== */
|
|
.page-header {
|
|
margin-bottom: var(--space-xl);
|
|
text-align: center;
|
|
}
|
|
|
|
.page-title {
|
|
margin: 0 0 var(--space-sm) 0;
|
|
font-size: var(--text-3xl);
|
|
font-weight: var(--font-bold);
|
|
color: var(--color-text);
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
gap: var(--space-md);
|
|
}
|
|
|
|
.page-subtitle {
|
|
margin: 0;
|
|
font-size: var(--text-base);
|
|
color: var(--color-text-secondary);
|
|
}
|
|
|
|
/* ===== Section Structure ===== */
|
|
.section-header {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
padding: var(--space-lg);
|
|
background: var(--color-bg-secondary);
|
|
border-bottom: 1px solid var(--color-border);
|
|
flex-wrap: wrap;
|
|
gap: var(--space-md);
|
|
}
|
|
|
|
.section-title {
|
|
font-size: var(--text-xl);
|
|
font-weight: var(--font-semibold);
|
|
color: var(--color-text);
|
|
margin: 0;
|
|
}
|
|
|
|
.section-controls {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: var(--space-md);
|
|
flex-wrap: wrap;
|
|
}
|
|
|
|
/* ===== Metrics Grid ===== */
|
|
.metrics-row {
|
|
display: grid;
|
|
grid-template-columns: repeat(2, 1fr);
|
|
gap: var(--space-lg);
|
|
margin-bottom: var(--space-xl);
|
|
}
|
|
|
|
@media (max-width: 1024px) {
|
|
.metrics-row {
|
|
grid-template-columns: 1fr;
|
|
}
|
|
}
|
|
|
|
/* ===== Breakdown Patterns ===== */
|
|
.breakdown-section {
|
|
padding-top: var(--space-lg);
|
|
border-top: 1px solid var(--color-border);
|
|
margin-top: var(--space-lg);
|
|
}
|
|
|
|
.breakdown-item {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
padding: var(--space-sm) 0;
|
|
}
|
|
|
|
.breakdown-label {
|
|
font-size: var(--text-sm);
|
|
color: var(--color-text-secondary);
|
|
font-weight: var(--font-medium);
|
|
}
|
|
|
|
.breakdown-value {
|
|
font-size: var(--text-base);
|
|
color: var(--color-text);
|
|
font-weight: var(--font-semibold);
|
|
font-family: var(--font-mono, monospace);
|
|
}
|
|
|
|
.breakdown-subitems {
|
|
padding-left: var(--space-lg);
|
|
margin-top: var(--space-sm);
|
|
}
|
|
|
|
.breakdown-subitem {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
padding: var(--space-xs) 0;
|
|
}
|
|
|
|
.breakdown-sublabel {
|
|
color: var(--color-text-secondary);
|
|
font-size: var(--text-sm);
|
|
}
|
|
|
|
.breakdown-subvalue {
|
|
font-weight: var(--font-medium);
|
|
font-family: var(--font-mono, monospace);
|
|
font-size: var(--text-sm);
|
|
}
|
|
```
|
|
|
|
**Acceptance Criteria:**
|
|
- [ ] All dashboard patterns defined
|
|
- [ ] Responsive grid included
|
|
- [ ] Breakdown patterns complete
|
|
|
|
---
|
|
|
|
#### Task 1.3: Create animations.css
|
|
**Status:** ⏸️ | **Est:** 30 min
|
|
|
|
**File:** `reports-app/frontend/src/assets/css/patterns/animations.css`
|
|
|
|
```css
|
|
/* Animations - ROA2WEB */
|
|
|
|
/* Slide Down Animation */
|
|
@keyframes slideDown {
|
|
from {
|
|
opacity: 0;
|
|
transform: translateY(-10px);
|
|
}
|
|
to {
|
|
opacity: 1;
|
|
transform: translateY(0);
|
|
}
|
|
}
|
|
|
|
.slide-down {
|
|
animation: slideDown var(--duration-fast) ease-out;
|
|
}
|
|
|
|
/* Fade In Animation */
|
|
@keyframes fadeIn {
|
|
from { opacity: 0; }
|
|
to { opacity: 1; }
|
|
}
|
|
|
|
.fade-in {
|
|
animation: fadeIn var(--duration-normal) ease-in;
|
|
}
|
|
|
|
/* Slide In From Right */
|
|
@keyframes slideInRight {
|
|
from {
|
|
opacity: 0;
|
|
transform: translateX(20px);
|
|
}
|
|
to {
|
|
opacity: 1;
|
|
transform: translateX(0);
|
|
}
|
|
}
|
|
|
|
.slide-in-right {
|
|
animation: slideInRight var(--duration-normal) ease-out;
|
|
}
|
|
|
|
/* Pulse Animation */
|
|
@keyframes pulse {
|
|
0%, 100% { opacity: 1; }
|
|
50% { opacity: 0.5; }
|
|
}
|
|
|
|
.pulse {
|
|
animation: pulse var(--duration-slower) ease-in-out infinite;
|
|
}
|
|
```
|
|
|
|
**Acceptance Criteria:**
|
|
- [ ] Common animations defined
|
|
- [ ] Duration variables used
|
|
- [ ] Utility classes created
|
|
|
|
---
|
|
|
|
#### Task 1.4: Create tokens.css
|
|
**Status:** ⏸️ | **Est:** 45 min
|
|
|
|
**File:** `reports-app/frontend/src/assets/css/core/tokens.css`
|
|
|
|
```css
|
|
/* Extended Design Tokens - ROA2WEB */
|
|
|
|
:root {
|
|
/* ===== Card Tokens ===== */
|
|
--card-padding: var(--space-lg);
|
|
--card-padding-sm: var(--space-md);
|
|
--card-padding-lg: var(--space-xl);
|
|
--card-gap: var(--space-md);
|
|
--card-min-height: 280px;
|
|
|
|
/* ===== Typography Tokens ===== */
|
|
--value-size: 1.5rem;
|
|
--value-size-lg: 2rem;
|
|
--label-size: 0.875rem;
|
|
--sublabel-size: 0.8125rem;
|
|
|
|
/* ===== Interactive Tokens ===== */
|
|
--hover-lift: -2px;
|
|
--active-lift: 0px;
|
|
--focus-ring: 0 0 0 3px rgba(var(--color-primary-rgb, 59, 130, 246), 0.1);
|
|
|
|
/* ===== Animation Durations ===== */
|
|
--duration-instant: 100ms;
|
|
--duration-fast: 150ms;
|
|
--duration-normal: 250ms;
|
|
--duration-slow: 350ms;
|
|
--duration-slower: 500ms;
|
|
|
|
/* ===== Component Sizing ===== */
|
|
--spinner-size: 40px;
|
|
--spinner-size-sm: 24px;
|
|
--spinner-size-lg: 56px;
|
|
--spinner-border: 4px;
|
|
|
|
/* ===== Dashboard Metrics ===== */
|
|
--metric-gap: 1rem;
|
|
--sparkline-height: 80px;
|
|
--sparkline-height-lg: 150px;
|
|
}
|
|
```
|
|
|
|
**Acceptance Criteria:**
|
|
- [ ] All extended tokens defined
|
|
- [ ] References existing variables
|
|
- [ ] No hardcoded values
|
|
|
|
---
|
|
|
|
#### Task 1.5: Create primevue-overrides.css
|
|
**Status:** ⏸️ | **Est:** 2 hours
|
|
|
|
**File:** `reports-app/frontend/src/assets/css/vendor/primevue-overrides.css`
|
|
|
|
```css
|
|
/* PrimeVue Component Overrides - ROA2WEB */
|
|
/* Global customization of PrimeVue saga-blue theme */
|
|
|
|
/* ===== Input Components ===== */
|
|
.p-inputtext,
|
|
.p-password input,
|
|
.p-dropdown,
|
|
.p-calendar input,
|
|
.p-autocomplete input {
|
|
border: 2px solid var(--color-border) !important;
|
|
border-radius: var(--radius-md) !important;
|
|
padding: var(--space-sm) var(--space-md) !important;
|
|
font-size: var(--text-base) !important;
|
|
font-family: inherit !important;
|
|
color: var(--color-text) !important;
|
|
background: var(--color-bg) !important;
|
|
transition: all var(--transition-fast) !important;
|
|
min-height: 44px !important;
|
|
}
|
|
|
|
/* ===== Focus States ===== */
|
|
.p-inputtext:focus,
|
|
.p-password input:focus,
|
|
.p-dropdown:focus,
|
|
.p-calendar input:focus,
|
|
.p-autocomplete input:focus {
|
|
outline: none !important;
|
|
border-color: var(--color-primary) !important;
|
|
box-shadow: var(--focus-ring) !important;
|
|
}
|
|
|
|
/* ===== Hover States ===== */
|
|
.p-inputtext:hover:not(:disabled),
|
|
.p-password input:hover:not(:disabled),
|
|
.p-dropdown:hover:not(:disabled) {
|
|
border-color: var(--color-border-dark, #d1d5db) !important;
|
|
}
|
|
|
|
/* ===== Disabled States ===== */
|
|
.p-inputtext:disabled,
|
|
.p-password input:disabled,
|
|
.p-dropdown:disabled {
|
|
background: var(--color-bg-muted, #f3f4f6) !important;
|
|
color: var(--color-text-muted, #9ca3af) !important;
|
|
opacity: 0.6 !important;
|
|
cursor: not-allowed !important;
|
|
}
|
|
|
|
/* ===== Validation States ===== */
|
|
.p-invalid.p-component,
|
|
.p-inputtext.p-invalid,
|
|
.p-password.p-invalid input {
|
|
border-color: var(--color-error, #ef4444) !important;
|
|
}
|
|
|
|
/* ===== Button Overrides ===== */
|
|
.p-button {
|
|
padding: var(--space-sm) var(--space-md) !important;
|
|
font-size: var(--text-sm) !important;
|
|
font-weight: var(--font-medium) !important;
|
|
border-radius: var(--radius-md) !important;
|
|
transition: all var(--transition-fast) !important;
|
|
}
|
|
|
|
.p-button:hover {
|
|
transform: translateY(-1px) !important;
|
|
box-shadow: var(--shadow-md) !important;
|
|
}
|
|
|
|
/* ===== DataTable ===== */
|
|
.p-datatable .p-datatable-thead > tr > th {
|
|
background: var(--color-bg-muted, #f9fafb) !important;
|
|
color: var(--color-text) !important;
|
|
font-weight: var(--font-semibold) !important;
|
|
border-bottom: 2px solid var(--color-border) !important;
|
|
padding: var(--space-md) var(--space-lg) !important;
|
|
}
|
|
|
|
.p-datatable .p-datatable-tbody > tr {
|
|
transition: background-color var(--transition-fast) !important;
|
|
}
|
|
|
|
.p-datatable .p-datatable-tbody > tr:hover {
|
|
background: var(--color-bg-secondary, #f8fafc) !important;
|
|
}
|
|
|
|
/* ===== Card ===== */
|
|
.p-card {
|
|
box-shadow: var(--shadow-sm) !important;
|
|
border: 1px solid var(--color-border) !important;
|
|
border-radius: var(--card-radius, 8px) !important;
|
|
}
|
|
|
|
.p-card .p-card-header {
|
|
background: var(--color-bg-secondary) !important;
|
|
border-bottom: 1px solid var(--color-border) !important;
|
|
padding: var(--space-lg) !important;
|
|
}
|
|
|
|
.p-card .p-card-body {
|
|
padding: var(--space-lg) !important;
|
|
}
|
|
|
|
/* ===== Mobile Optimizations ===== */
|
|
@media (max-width: 768px) {
|
|
.p-inputtext,
|
|
.p-password input,
|
|
.p-dropdown,
|
|
.p-calendar input {
|
|
font-size: 16px !important; /* Prevent iOS zoom */
|
|
}
|
|
}
|
|
```
|
|
|
|
**Acceptance Criteria:**
|
|
- [ ] All common PrimeVue components styled
|
|
- [ ] Design tokens used (not hardcoded)
|
|
- [ ] Mobile optimizations included
|
|
- [ ] Ready for Phase 3 migration
|
|
|
|
---
|
|
|
|
### 2. Integration (2 tasks)
|
|
|
|
#### Task 2.1: Update main.css
|
|
**Status:** ⏸️ | **Est:** 15 min
|
|
|
|
**File:** `reports-app/frontend/src/assets/css/main.css`
|
|
|
|
**Add after existing imports:**
|
|
```css
|
|
/* Main CSS Entry Point - ROA2WEB */
|
|
|
|
/* 1. Core Foundation */
|
|
@import './core/variables.css';
|
|
@import './core/tokens.css'; /* NEW */
|
|
@import './core/reset.css';
|
|
@import './core/typography.css';
|
|
|
|
/* 2. Layout System */
|
|
@import './layout/grid.css';
|
|
@import './layout/containers.css';
|
|
@import './layout/navigation.css';
|
|
|
|
/* 3. Component Library */
|
|
@import './components/cards.css';
|
|
@import './components/buttons.css';
|
|
@import './components/tables.css';
|
|
@import './components/forms.css';
|
|
@import './components/stats.css';
|
|
|
|
/* 4. Patterns */
|
|
@import './patterns/interactive.css'; /* NEW */
|
|
@import './patterns/dashboard.css'; /* NEW */
|
|
@import './patterns/animations.css'; /* NEW */
|
|
|
|
/* 5. Utilities */
|
|
@import './utilities/spacing.css';
|
|
@import './utilities/display.css';
|
|
@import './utilities/text.css';
|
|
@import './utilities/flex.css';
|
|
|
|
/* 6. Vendor Overrides */
|
|
@import './vendor/primevue-overrides.css'; /* NEW */
|
|
|
|
/* 7. Mobile Optimizations */
|
|
@import './mobile.css';
|
|
```
|
|
|
|
**Acceptance Criteria:**
|
|
- [ ] All new files imported
|
|
- [ ] Import order correct (core → patterns → vendor)
|
|
- [ ] No syntax errors
|
|
|
|
---
|
|
|
|
#### Task 2.2: Verify No Visual Changes
|
|
**Status:** ⏸️ | **Est:** 30 min
|
|
|
|
```bash
|
|
# Build and verify
|
|
npm run build
|
|
|
|
# Check bundle size
|
|
ls -lh dist/assets/*.css
|
|
|
|
# Run dev server
|
|
npm run dev
|
|
|
|
# Visually check pages
|
|
```
|
|
|
|
**Check all pages:**
|
|
- [ ] Login page unchanged
|
|
- [ ] Dashboard unchanged
|
|
- [ ] Invoices unchanged
|
|
- [ ] No console errors
|
|
- [ ] No CSS warnings
|
|
|
|
**Acceptance Criteria:**
|
|
- [ ] Zero visual changes
|
|
- [ ] Build successful
|
|
- [ ] No errors in console
|
|
|
|
---
|
|
|
|
### 3. Testing & Documentation (3 tasks)
|
|
|
|
#### Task 3.1: Build Verification
|
|
**Status:** ⏸️ | **Est:** 15 min
|
|
|
|
```bash
|
|
cd reports-app/frontend
|
|
|
|
# Clean build
|
|
rm -rf dist/
|
|
npm run build
|
|
|
|
# Check for errors
|
|
echo $? # Should be 0
|
|
|
|
# Verify CSS files
|
|
ls -la dist/assets/*.css
|
|
```
|
|
|
|
**Acceptance Criteria:**
|
|
- [ ] Build completes without errors
|
|
- [ ] CSS bundle created
|
|
- [ ] No missing imports
|
|
|
|
---
|
|
|
|
#### Task 3.2: Pattern Documentation
|
|
**Status:** ⏸️ | **Est:** 45 min
|
|
|
|
**Create:** `docs/CSS_PATTERNS_REFERENCE.md`
|
|
|
|
**Content:**
|
|
```markdown
|
|
# ROA2WEB CSS Patterns Reference
|
|
|
|
## Interactive Patterns
|
|
|
|
### Loading Spinner
|
|
\`\`\`html
|
|
<div class="loading-spinner"></div>
|
|
<div class="loading-spinner loading-spinner-sm"></div>
|
|
<div class="loading-spinner loading-spinner-lg"></div>
|
|
\`\`\`
|
|
|
|
### Trend Indicator
|
|
\`\`\`html
|
|
<span class="trend trend-up">
|
|
<i class="pi pi-arrow-up trend-icon"></i>
|
|
+15%
|
|
</span>
|
|
\`\`\`
|
|
|
|
<!-- More patterns... -->
|
|
```
|
|
|
|
**Acceptance Criteria:**
|
|
- [ ] All patterns documented with examples
|
|
- [ ] HTML examples provided
|
|
- [ ] Use cases explained
|
|
|
|
---
|
|
|
|
#### Task 3.3: Commit Phase 2
|
|
**Status:** ⏸️ | **Est:** 10 min
|
|
|
|
```bash
|
|
git add .
|
|
git commit -m "feat(css): Phase 2 - Add global pattern foundation
|
|
|
|
- Create interactive.css (loading, trends, collapse)
|
|
- Create dashboard.css (headers, metrics, breakdowns)
|
|
- Create animations.css (slideDown, fadeIn, pulse)
|
|
- Create tokens.css (extended design tokens)
|
|
- Create primevue-overrides.css (centralized PrimeVue styling)
|
|
- Update main.css with new imports
|
|
- Zero visual changes (additive only)
|
|
|
|
Files created: 5 new CSS files
|
|
Lines added: ~600 lines
|
|
Phase: 2/7 complete
|
|
"
|
|
|
|
git push origin feature/css-refactoring
|
|
```
|
|
|
|
**Acceptance Criteria:**
|
|
- [ ] All files committed
|
|
- [ ] Commit message descriptive
|
|
- [ ] Pushed to remote
|
|
|
|
---
|
|
|
|
## Completion Criteria
|
|
|
|
- [ ] 5 new CSS files created
|
|
- [ ] All patterns implemented
|
|
- [ ] main.css updated
|
|
- [ ] Zero visual changes
|
|
- [ ] Build successful
|
|
- [ ] Documentation created
|
|
- [ ] Committed to git
|
|
|
|
---
|
|
|
|
## Next Phase
|
|
|
|
**Phase 3:** PrimeVue Centralizare
|
|
- Migrate all component `:deep()` to global
|
|
- Eliminate `!important` from components
|
|
- See: [phase-3-primevue.md](./phase-3-primevue.md)
|
|
|
|
---
|
|
|
|
**Created:** 2025-11-18
|
|
**Status:** ⏸️ Not Started
|