feat(dashboard): add datorat/achitat/sold breakdown for budget debts

Replaces "luna prec / luna curentă" columns with a clearer accounting
reconciliation flow: Datorat (owed) → Achitat (paid) → Sold (remaining).
Backend models gain 3 new fields per sub-account and group. Frontend
shows ✓ when a debt is fully cleared. Mobile TVA card now shows both
total and remaining sold. SwipeableCards gains fixedDots/fillHeight props
for better layout above MobileBottomNav. Telegram formatter updated to
use new fields and drops redundant RON suffix from amounts.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Claude Agent
2026-02-23 15:05:41 +00:00
parent aac49542e4
commit 6c78fec8a7
8 changed files with 606 additions and 123 deletions

View File

@@ -3,7 +3,6 @@
<!-- Header -->
<div class="card-header">
<h3 class="card-title">
<i class="pi pi-chart-bar"></i>
Indicatori Financiari
</h3>
<div class="period-selector-wrapper">
@@ -102,7 +101,7 @@
<!-- Lichiditate -->
<div class="indicator-section" v-if="lichiditate">
<h4 class="section-title" @click="toggleSubIndicators('lichiditate')">
<span>💧 Lichiditate</span>
<span>Lichiditate</span>
<i class="pi" :class="subIndicatorsExpanded.lichiditate ? 'pi-chevron-up' : 'pi-chevron-down'"></i>
</h4>
<div class="section-items">
@@ -178,7 +177,7 @@
<!-- Eficiență -->
<div class="indicator-section" v-if="eficienta">
<h4 class="section-title" @click="toggleSubIndicators('eficienta')">
<span> Eficiență</span>
<span>Eficiență</span>
<i class="pi" :class="subIndicatorsExpanded.eficienta ? 'pi-chevron-up' : 'pi-chevron-down'"></i>
</h4>
<div class="section-items">
@@ -290,7 +289,7 @@
<!-- Risc -->
<div class="indicator-section" v-if="risc">
<h4 class="section-title" @click="toggleSubIndicators('risc')">
<span> Risc</span>
<span>Risc</span>
<i class="pi" :class="subIndicatorsExpanded.risc ? 'pi-chevron-up' : 'pi-chevron-down'"></i>
</h4>
<div class="section-items">
@@ -393,7 +392,7 @@
<!-- Cash Flow -->
<div class="indicator-section" v-if="cash_flow">
<h4 class="section-title" @click="toggleSubIndicators('cashflow')">
<span>💰 Cash Flow</span>
<span>Cash Flow</span>
<i class="pi" :class="subIndicatorsExpanded.cashflow ? 'pi-chevron-up' : 'pi-chevron-down'"></i>
</h4>
<div class="section-items">
@@ -478,7 +477,7 @@
<!-- Dinamică -->
<div class="indicator-section" v-if="dinamica">
<h4 class="section-title" @click="toggleSubIndicators('dinamica')">
<span>📈 Dinamică</span>
<span>Dinamică</span>
<i class="pi" :class="subIndicatorsExpanded.dinamica ? 'pi-chevron-up' : 'pi-chevron-down'"></i>
</h4>
<div class="section-items">
@@ -554,7 +553,7 @@
<!-- Profitabilitate -->
<div class="indicator-section" v-if="profitabilitate">
<h4 class="section-title" @click="toggleSubIndicators('profitabilitate')">
<span>💹 Profitabilitate</span>
<span>Profitabilitate</span>
<i class="pi" :class="subIndicatorsExpanded.profitabilitate ? 'pi-chevron-up' : 'pi-chevron-down'"></i>
</h4>
<div class="section-items">
@@ -666,7 +665,7 @@
<!-- Altman Z-Score -->
<div class="indicator-section" v-if="altman_zscore">
<h4 class="section-title" @click="toggleSubIndicators('altman')">
<span>🎯 Altman Z-Score</span>
<span>Altman Z-Score</span>
<i class="pi" :class="subIndicatorsExpanded.altman ? 'pi-chevron-up' : 'pi-chevron-down'"></i>
</h4>
<div class="section-items">
@@ -738,7 +737,7 @@
<!-- Solvabilitate -->
<div class="indicator-section" v-if="solvabilitate">
<h4 class="section-title" @click="toggleSubIndicators('solvabilitate')">
<span>🏛 Solvabilitate</span>
<span>Solvabilitate</span>
<i class="pi" :class="subIndicatorsExpanded.solvabilitate ? 'pi-chevron-up' : 'pi-chevron-down'"></i>
</h4>
<div class="section-items">
@@ -830,7 +829,7 @@
<!-- Lichiditate -->
<div class="indicator-category">
<h4 class="category-title" @click="toggleSubIndicators('lichiditate')">
<span>💧 Lichiditate</span>
<span>Lichiditate</span>
<i class="pi" :class="subIndicatorsExpanded.lichiditate ? 'pi-chevron-up' : 'pi-chevron-down'"></i>
</h4>
<div class="category-items">
@@ -898,7 +897,7 @@
<!-- Eficiență -->
<div class="indicator-category">
<h4 class="category-title" @click="toggleSubIndicators('eficienta')">
<span> Eficiență</span>
<span>Eficiență</span>
<i class="pi" :class="subIndicatorsExpanded.eficienta ? 'pi-chevron-up' : 'pi-chevron-down'"></i>
</h4>
<div class="category-items">
@@ -998,7 +997,7 @@
<!-- Risc -->
<div class="indicator-category">
<h4 class="category-title" @click="toggleSubIndicators('risc')">
<span> Risc</span>
<span>Risc</span>
<i class="pi" :class="subIndicatorsExpanded.risc ? 'pi-chevron-up' : 'pi-chevron-down'"></i>
</h4>
<div class="category-items">
@@ -1089,7 +1088,7 @@
<!-- Cash Flow -->
<div class="indicator-category">
<h4 class="category-title" @click="toggleSubIndicators('cashflow')">
<span>💰 Cash Flow</span>
<span>Cash Flow</span>
<i class="pi" :class="subIndicatorsExpanded.cashflow ? 'pi-chevron-up' : 'pi-chevron-down'"></i>
</h4>
<div class="category-items">
@@ -1166,7 +1165,7 @@
<!-- Dinamică -->
<div class="indicator-category">
<h4 class="category-title" @click="toggleSubIndicators('dinamica')">
<span>📈 Dinamică</span>
<span>Dinamică</span>
<i class="pi" :class="subIndicatorsExpanded.dinamica ? 'pi-chevron-up' : 'pi-chevron-down'"></i>
</h4>
<div class="category-items">
@@ -1234,7 +1233,7 @@
<!-- Altman Z-Score -->
<div class="indicator-category">
<h4 class="category-title" @click="toggleSubIndicators('altman')">
<span>🎯 Altman Z-Score</span>
<span>Altman Z-Score</span>
<i class="pi" :class="subIndicatorsExpanded.altman ? 'pi-chevron-up' : 'pi-chevron-down'"></i>
</h4>
<div class="category-items">
@@ -1305,7 +1304,7 @@
<!-- Profitabilitate -->
<div class="indicator-category" v-if="profitabilitate">
<h4 class="category-title" @click="toggleSubIndicators('profitabilitate')">
<span>💰 Profitabilitate</span>
<span>Profitabilitate</span>
<i class="pi" :class="subIndicatorsExpanded.profitabilitate ? 'pi-chevron-up' : 'pi-chevron-down'"></i>
</h4>
<div class="category-items">
@@ -1400,7 +1399,7 @@
<!-- Solvabilitate -->
<div class="indicator-category" v-if="solvabilitate">
<h4 class="category-title" @click="toggleSubIndicators('solvabilitate')">
<span>🏛 Solvabilitate</span>
<span>Solvabilitate</span>
<i class="pi" :class="subIndicatorsExpanded.solvabilitate ? 'pi-chevron-up' : 'pi-chevron-down'"></i>
</h4>
<div class="category-items">
@@ -1712,7 +1711,7 @@ const formatCurrency = (value) => {
maximumFractionDigits: 0
})
const sign = num < 0 ? '-' : num > 0 ? '+' : ''
return `${sign}${formatted} RON`
return `${sign}${formatted}`
}
// Normalize status for consistent styling
@@ -1823,8 +1822,8 @@ const handlePeriodChange = () => {
<style scoped>
/* Card Container */
.financial-indicators-card {
background: var(--surface-card);
border: 1px solid var(--surface-border);
background: transparent;
border: none;
border-radius: var(--radius-md);
padding: var(--space-md);
display: flex;
@@ -1959,7 +1958,7 @@ const handlePeriodChange = () => {
/* Each category section */
.indicator-section {
background: var(--surface-ground);
background: transparent;
border-radius: var(--radius-md);
padding: var(--space-md);
border: 1px solid var(--surface-border);
@@ -2253,7 +2252,6 @@ const handlePeriodChange = () => {
display: flex;
justify-content: center;
padding-top: var(--space-sm);
border-top: 1px solid var(--surface-border);
}
.expand-toggle-btn {
@@ -2388,7 +2386,7 @@ const handlePeriodChange = () => {
================================================ */
.mobile-footer {
padding: var(--space-sm);
background: var(--surface-ground);
background: transparent;
}
/* ================================================
@@ -2410,7 +2408,10 @@ const handlePeriodChange = () => {
/* Category sections */
.indicator-category {
margin-bottom: var(--space-lg);
border: 1px solid var(--surface-border);
border-radius: var(--radius-md);
padding: var(--space-md);
margin-bottom: var(--space-md);
}
.category-title {

View File

@@ -359,7 +359,7 @@ const handleMouseLeave = () => {
<style scoped>
/* Indicator Item Container */
.indicator-item {
background: var(--surface-ground);
background: transparent;
border: 1px solid var(--surface-border);
border-radius: var(--radius-sm);
padding: var(--space-md);

View File

@@ -8,9 +8,18 @@
<div class="solduri-compact-card__header">
<div class="solduri-compact-card__content">
<span class="solduri-compact-card__label">{{ label }}</span>
<span class="solduri-compact-card__value" :class="valueColorClass">
<!-- type !== 'tva': simple value -->
<span v-if="type !== 'tva'" class="solduri-compact-card__value" :class="valueColorClass">
{{ formatAmount(total) }}
</span>
<!-- type === 'tva': datorat · sold on same line, same font -->
<div v-else class="solduri-compact-card__debt-line">
<span class="solduri-compact-card__value" :class="valueColorClass">{{ formatAmount(total) }}</span>
<span class="solduri-compact-card__debt-sep">·</span>
<span class="solduri-compact-card__value solduri-compact-card__value--sold">
{{ soldTotal !== undefined && soldTotal > 0 ? formatAmount(soldTotal) : '0 ✓' }}
</span>
</div>
</div>
<i
class="pi pi-chevron-down solduri-compact-card__chevron"
@@ -90,10 +99,17 @@
<!-- TVA / Datorii Buget: Breakdown pe grupe (TVA/BASS/CAM) cu sub-conturi -->
<template v-else-if="type === 'tva'">
<template v-if="Array.isArray(breakdown) && (breakdown as any[]).length">
<!-- Header coloane -->
<div class="solduri-compact-card__debt-header">
<span></span>
<span class="solduri-compact-card__col-head">Datorat</span>
<span class="solduri-compact-card__col-head">Sold</span>
</div>
<div v-for="group in (breakdown as any[])" :key="group.key">
<!-- Rând grup -->
<div
class="solduri-compact-card__breakdown-item solduri-compact-card__breakdown-group"
class="solduri-compact-card__breakdown-group"
@click.stop="toggleGroup(group.key)"
>
<span class="solduri-compact-card__breakdown-label solduri-compact-card__group-label">
@@ -102,10 +118,14 @@
{{ group.label }}
</span>
<span class="solduri-compact-card__breakdown-value">
{{ group.precedent !== 0 ? formatAmount(group.precedent) : '-' }}
{{ group.datorat > 0 ? formatAmount(group.datorat) : '-' }}
</span>
<span class="solduri-compact-card__breakdown-value"
:class="group.sold <= 0 && group.datorat > 0 ? 'solduri-compact-card__cleared' : ''">
{{ group.sold > 0 ? formatAmount(group.sold) : (group.datorat > 0 ? '✓' : '-') }}
</span>
</div>
<!-- Sub-conturi -->
<!-- Sub-conturi expandabile -->
<div v-show="expandedGroups.has(group.key)">
<div
v-for="acc in group.sub_accounts"
@@ -114,11 +134,32 @@
>
<span class="solduri-compact-card__breakdown-sublabel">{{ acc.label }}</span>
<span class="solduri-compact-card__breakdown-subvalue">
{{ acc.precedent !== 0 ? formatAmount(acc.precedent) : '-' }}
{{ acc.datorat > 0 ? formatAmount(acc.datorat) : '-' }}
</span>
<span class="solduri-compact-card__breakdown-subvalue">
{{ acc.sold > 0 ? formatAmount(acc.sold) : (acc.datorat > 0 ? '✓' : '-') }}
</span>
</div>
</div>
</div>
<!-- Obligații luna curentă -->
<template v-if="(breakdown as any[]).some((g: any) => g.curent > 0)">
<div class="solduri-compact-card__divider"></div>
<div class="solduri-compact-card__curent-summary">
<span class="solduri-compact-card__curent-title">Obligații curente:</span>
<span
v-for="g in (breakdown as any[]).filter((g: any) => g.curent > 0)"
:key="'c-' + g.key"
class="solduri-compact-card__curent-chip"
>
{{ g.label }} {{ formatAmount(g.curent) }}
</span>
<span class="solduri-compact-card__curent-total">
= {{ formatAmount(curentTotal) }}
</span>
</div>
</template>
</template>
<template v-else>
<div class="solduri-compact-card__breakdown-item">
@@ -163,6 +204,7 @@ type BreakdownType = TrezorerieBreakdown | ClientiFurnizoriBreakdown | null
const props = defineProps<{
type: CardType
total: number
soldTotal?: number
breakdown?: BreakdownType
casaTotal?: number
bancaTotal?: number
@@ -203,6 +245,14 @@ const valueColorClass = computed(() => {
return ''
})
// Computed: Total obligații curente (doar pentru type === 'tva')
const curentTotal = computed(() => {
if (!Array.isArray(props.breakdown)) return 0
return (props.breakdown as any[])
.filter((g: any) => Number(g.curent || 0) > 0)
.reduce((sum: number, g: any) => sum + Number(g.curent || 0), 0)
})
// Computed: Check if breakdown data exists
const hasBreakdown = computed(() => {
if (props.type === 'trezorerie') {
@@ -303,6 +353,24 @@ const formatPeriodLabel = (key: string): string => {
line-height: var(--leading-tight);
}
/* Debt line: datorat · sold inline, same font */
.solduri-compact-card__debt-line {
display: flex;
align-items: baseline;
gap: var(--space-xs);
flex-wrap: wrap;
}
.solduri-compact-card__debt-sep {
color: var(--text-color-secondary);
font-size: var(--text-lg);
font-weight: var(--font-bold);
}
.solduri-compact-card__value--sold {
color: var(--text-color-secondary);
}
/* Value color modifiers */
.solduri-compact-card__value--success {
color: var(--green-600);
@@ -385,10 +453,35 @@ const formatPeriodLabel = (key: string): string => {
font-family: var(--font-mono, monospace);
}
/* TVA: 3-column grid layout (label | datorat | sold) */
.solduri-compact-card__debt-header,
.solduri-compact-card__breakdown-group,
.solduri-compact-card__breakdown-subitem {
display: grid;
grid-template-columns: 1fr auto auto;
gap: var(--space-sm);
align-items: center;
}
.solduri-compact-card__col-head {
font-size: var(--text-xs);
color: var(--text-color-secondary);
text-align: right;
min-width: 54px;
}
/* Override: breakdown-value/subvalue right-aligned with min-width in grid */
.solduri-compact-card__breakdown-group .solduri-compact-card__breakdown-value,
.solduri-compact-card__breakdown-subitem .solduri-compact-card__breakdown-subvalue {
text-align: right;
min-width: 54px;
}
/* TVA grup toggle */
.solduri-compact-card__breakdown-group {
cursor: pointer;
font-weight: var(--font-semibold);
padding: var(--space-xs) 0;
}
.solduri-compact-card__breakdown-group:hover { background: var(--surface-hover); }
@@ -405,6 +498,49 @@ const formatPeriodLabel = (key: string): string => {
}
.solduri-compact-card__group-toggle--expanded { transform: rotate(90deg); }
/* Cleared (paid) indicator */
.solduri-compact-card__cleared {
color: var(--green-600);
font-weight: var(--font-semibold);
}
/* Divider between breakdown and obligații curente */
.solduri-compact-card__divider {
height: 1px;
background: var(--surface-border);
margin: var(--space-sm) 0;
}
/* Obligații curente section */
.solduri-compact-card__curent-summary {
display: flex;
flex-wrap: wrap;
gap: var(--space-xs);
align-items: center;
}
.solduri-compact-card__curent-title {
font-size: var(--text-xs);
color: var(--text-color-secondary);
}
.solduri-compact-card__curent-chip {
font-size: var(--text-sm);
font-weight: var(--font-semibold);
background: var(--surface-hover);
border-radius: var(--radius-sm);
padding: 2px var(--space-xs);
color: var(--text-color);
}
.solduri-compact-card__curent-total {
font-size: var(--text-sm);
font-weight: var(--font-bold);
font-family: var(--font-mono, monospace);
color: var(--text-color);
margin-left: var(--space-xs);
}
/* Responsive - Mobile */
@media (max-width: 768px) {
.solduri-compact-card {

View File

@@ -50,7 +50,7 @@
<div class="metrics-cards-section">
<!-- Mobile: Swipeable KPI Cards Carousel -->
<!-- US-2002: 6 pages - first page is 2x2 grid with solduri, pages 2-5 are original graph cards, page 6 is financial indicators -->
<SwipeableCards v-if="isMobile" :totalCards="6" class="mobile-kpi-carousel">
<SwipeableCards v-if="isMobile" :totalCards="6" :fixed-dots="true" :fill-height="true" class="mobile-kpi-carousel">
<!-- Page 1: Grid 2x2 cu Solduri Compacte -->
<template #card-0>
<div class="solduri-grid-2x2">
@@ -73,7 +73,8 @@
/>
<SolduriCompactCard
type="tva"
:total="tvaPreviousMonthNet"
:total="budgetDebtTotalPrecedent"
:sold-total="budgetDebtSold"
:breakdown="tvaBreakdown"
/>
</div>
@@ -228,14 +229,15 @@
</CollapsibleCard>
<CollapsibleCard
label="Datorii la buget"
:value="budgetDebtTotalPrecedent"
:value-class="budgetDebtTotalPrecedent > 0 ? 'negative' : 'positive'"
:value="budgetDebtHeaderValue"
:value-class="budgetDebtSold > 0 ? 'negative' : (budgetDebtTotalPrecedent > 0 ? 'positive' : '')"
>
<div class="budget-debt-breakdown-desktop">
<div class="budget-debt-breakdown-header">
<span class="budget-debt-col-label">Categorie</span>
<span class="budget-debt-col-header-value">Luna prec.</span>
<span class="budget-debt-col-header-value">Luna curentă</span>
<span></span>
<span class="budget-debt-col-header-value">Datorat</span>
<span class="budget-debt-col-header-value budget-debt-col-achitat">Achitat</span>
<span class="budget-debt-col-header-value">Sold</span>
</div>
<template v-for="group in budgetDebtBreakdown" :key="group.key">
@@ -250,10 +252,13 @@
{{ group.label }}
</span>
<span class="budget-debt-col-value">
{{ group.precedent !== 0 ? formatAmount(group.precedent) : '-' }}
{{ group.datorat > 0 ? formatAmount(group.datorat) : '-' }}
</span>
<span class="budget-debt-col-value">
{{ group.curent !== 0 ? formatAmount(group.curent) : '-' }}
<span class="budget-debt-col-value budget-debt-paid budget-debt-col-achitat">
{{ group.achitat > 0 ? formatAmount(group.achitat) : '-' }}
</span>
<span class="budget-debt-col-value" :class="{ 'budget-debt-cleared': group.sold <= 0 && group.datorat > 0 }">
{{ group.sold > 0 ? formatAmount(group.sold) : (group.datorat > 0 ? '✓' : '-') }}
</span>
</div>
@@ -266,10 +271,13 @@
>
<span class="budget-debt-col-label budget-debt-sub-label">{{ acc.label }}</span>
<span class="budget-debt-col-value budget-debt-sub-value">
{{ acc.precedent !== 0 ? formatAmount(acc.precedent) : '-' }}
{{ acc.datorat > 0 ? formatAmount(acc.datorat) : '-' }}
</span>
<span class="budget-debt-col-value budget-debt-sub-value">
{{ acc.curent !== 0 ? formatAmount(acc.curent) : '-' }}
<span class="budget-debt-col-value budget-debt-sub-value budget-debt-paid budget-debt-col-achitat">
{{ acc.achitat > 0 ? formatAmount(acc.achitat) : '-' }}
</span>
<span class="budget-debt-col-value budget-debt-sub-value" :class="{ 'budget-debt-cleared': acc.sold <= 0 && acc.datorat > 0 }">
{{ acc.sold > 0 ? formatAmount(acc.sold) : (acc.datorat > 0 ? '✓' : '-') }}
</span>
</div>
</div>
@@ -278,6 +286,20 @@
<div v-if="budgetDebtBreakdown.length === 0" class="budget-debt-breakdown-empty">
Nu există datorii înregistrate
</div>
<!-- Obligații luna curentă - compact, fără sub-secțiune -->
<template v-if="budgetDebtBreakdownCurent.length > 0">
<div class="budget-debt-section-divider"></div>
<div class="budget-debt-curent-summary">
<span class="budget-debt-curent-title">Obligații curente:</span>
<span
v-for="group in budgetDebtBreakdownCurent"
:key="'crt-' + group.key"
class="budget-debt-curent-chip"
>{{ group.label }} {{ formatAmount(group.curent) }}</span>
<span class="budget-debt-curent-total">= {{ formatAmount(budgetDebtTotalCurent) }}</span>
</div>
</template>
</div>
</CollapsibleCard>
</div>
@@ -592,17 +614,44 @@ const tvaPreviousMonthNet = computed(() => {
return (prev.plata || 0) - (prev.recuperat || 0);
});
// Breakdown pe grupe datorii buget (TVA/BASS/CAM cu sub-conturi)
// Breakdown pe grupe datorii buget - DOAR grupe cu datorii din luna precedentă
const budgetDebtBreakdown = computed(() => {
return dashboardStore.summary?.budget_debt_breakdown || [];
return (dashboardStore.summary?.budget_debt_breakdown || [])
.filter(g => Number(g.datorat || 0) !== 0 || Number(g.precedent || 0) !== 0);
});
// Filtrare grupe cu obligații luna curentă (pentru secțiunea compactă)
const budgetDebtBreakdownCurent = computed(() =>
(dashboardStore.summary?.budget_debt_breakdown || []).filter(g => Number(g.curent || 0) > 0)
);
// Total obligații curente (suma tuturor grupurilor din luna curentă)
const budgetDebtTotalCurent = computed(() =>
budgetDebtBreakdownCurent.value.reduce((sum, g) => sum + Number(g.curent || 0), 0)
);
// Total precedent din toate grupurile (pentru header CollapsibleCard)
const budgetDebtTotalPrecedent = computed(() => {
const groups = dashboardStore.summary?.budget_debt_breakdown || [];
return groups.reduce((sum, g) => sum + Number(g.precedent || 0), 0);
});
// Sold final total (cât mai rămâne de plată după plățile din luna curentă)
const budgetDebtSold = computed(() => {
const groups = dashboardStore.summary?.budget_debt_breakdown || [];
return groups.reduce((sum, g) => sum + Number(g.sold || 0), 0);
});
// Header card: format "X.XXX (Y.YYY)" — total datorat și sold rămas
const budgetDebtHeaderValue = computed(() => {
const datorat = budgetDebtTotalPrecedent.value;
const sold = budgetDebtSold.value;
if (datorat === 0 && sold === 0) return '-';
const fmt = (n) => new Intl.NumberFormat('ro-RO').format(Math.round(Math.abs(n)));
if (sold <= 0 && datorat > 0) return `${fmt(datorat)} (0 ✓)`;
return `${fmt(datorat)} (${fmt(sold)})`;
});
const tvaBreakdown = computed(() => {
return dashboardStore.summary?.budget_debt_breakdown || [];
});
@@ -1658,6 +1707,39 @@ onUnmounted(() => {
width: 100%;
}
/* Mobile Budget Card wrapper (card-6 in SwipeableCards) */
.mobile-budget-card {
background: var(--surface-card);
border-radius: var(--radius-md);
border: 1px solid var(--surface-border);
overflow: hidden;
}
.mobile-budget-card-header {
display: flex;
align-items: center;
justify-content: space-between;
padding: var(--space-sm) var(--space-md);
border-bottom: 1px solid var(--surface-border);
}
.mobile-budget-card-title {
font-size: var(--text-sm);
font-weight: var(--font-semibold);
color: var(--text-color-secondary);
text-transform: uppercase;
letter-spacing: 0.04em;
}
.mobile-budget-card-value {
font-size: var(--text-sm);
font-weight: var(--font-semibold);
color: var(--text-color);
}
.mobile-budget-card-value.positive { color: var(--green-600); }
.mobile-budget-card-value.negative { color: var(--red-600); }
/* Budget Debt Breakdown in Desktop CollapsibleCard */
.budget-debt-breakdown-desktop {
display: flex;
@@ -1667,7 +1749,7 @@ onUnmounted(() => {
.budget-debt-breakdown-header {
display: grid;
grid-template-columns: 1fr auto auto;
grid-template-columns: 1fr auto auto auto;
gap: var(--space-md);
padding: var(--space-xs) 0 var(--space-sm) 0;
border-bottom: 1px solid var(--surface-border);
@@ -1676,7 +1758,7 @@ onUnmounted(() => {
.budget-debt-breakdown-row {
display: grid;
grid-template-columns: 1fr auto auto;
grid-template-columns: 1fr auto auto auto;
gap: var(--space-md);
padding: var(--space-xs) 0;
align-items: center;
@@ -1701,7 +1783,7 @@ onUnmounted(() => {
font-family: var(--font-mono, monospace);
color: var(--color-text);
white-space: nowrap;
min-width: 130px;
min-width: 100px;
text-align: right;
}
@@ -1712,10 +1794,29 @@ onUnmounted(() => {
letter-spacing: 0.05em;
color: var(--color-text-secondary);
white-space: nowrap;
min-width: 130px;
min-width: 100px;
text-align: right;
}
/* Coloana "Achitat" - verde pentru plăți efectuate */
.budget-debt-paid {
color: var(--green-600);
}
[data-theme="dark"] .budget-debt-paid {
color: var(--green-400);
}
/* Coloana "Sold" când e 0 (datoria achitată integral) */
.budget-debt-cleared {
color: var(--green-600);
font-weight: var(--font-bold);
}
[data-theme="dark"] .budget-debt-cleared {
color: var(--green-400);
}
.budget-debt-breakdown-empty {
padding: var(--space-sm) 0;
color: var(--color-text-secondary);
@@ -1756,6 +1857,66 @@ onUnmounted(() => {
.budget-debt-sub-label { padding-left: var(--space-md); font-size: var(--text-xs); }
.budget-debt-sub-value { font-size: var(--text-xs); }
/* Mobile: reduce columns (hide Achitat, shrink values) */
@media (max-width: 768px) {
.budget-debt-breakdown-header,
.budget-debt-breakdown-row {
grid-template-columns: 1fr auto auto;
gap: var(--space-sm);
}
.budget-debt-col-achitat {
display: none;
}
.budget-debt-col-value {
min-width: 72px;
}
.budget-debt-breakdown-desktop {
padding: var(--space-sm);
}
}
/* Separator între precedent și curent */
.budget-debt-section-divider {
height: 1px;
background: var(--surface-border);
margin: var(--space-sm) 0;
}
/* Obligații curente - compact, o singură linie */
.budget-debt-curent-summary {
display: flex;
flex-wrap: wrap;
align-items: center;
gap: var(--space-sm);
padding: var(--space-xs) 0;
}
.budget-debt-curent-title {
font-size: var(--text-xs);
font-weight: var(--font-semibold);
color: var(--text-color-secondary);
text-transform: uppercase;
letter-spacing: 0.04em;
}
.budget-debt-curent-chip {
font-size: var(--text-sm);
font-weight: var(--font-semibold);
font-family: var(--font-mono, monospace);
color: var(--text-color-secondary);
}
.budget-debt-curent-total {
font-size: var(--text-sm);
font-weight: var(--font-bold);
font-family: var(--font-mono, monospace);
color: var(--text-color);
margin-left: var(--space-xs);
}
/* Responsive - All breakpoints consolidated */
@media (max-width: 1200px) {
.metrics-row {
@@ -1787,6 +1948,74 @@ onUnmounted(() => {
margin-bottom: var(--space-lg);
}
/* Eliminare culori semantice în contextul caruselului mobil */
/* Clase globale utility (colors.css): text-success/error/primary/danger */
.mobile-kpi-carousel :deep(.text-success),
.mobile-kpi-carousel :deep(.text-error),
.mobile-kpi-carousel :deep(.text-primary),
.mobile-kpi-carousel :deep(.text-danger) {
color: var(--text-color) !important;
}
/* Clase positive/negative pe header-total (Clienti/FurnizoriBalanceCard) */
.mobile-kpi-carousel :deep(.header-total.positive),
.mobile-kpi-carousel :deep(.header-total.negative),
.mobile-kpi-carousel :deep(.positive),
.mobile-kpi-carousel :deep(.negative) {
color: var(--text-color) !important;
}
/* Clase value--success/danger (SolduriCompactCard) */
.mobile-kpi-carousel :deep(.solduri-compact-card__value--success),
.mobile-kpi-carousel :deep(.solduri-compact-card__value--danger) {
color: var(--text-color) !important;
}
/* Trend colors - neutralizate */
.mobile-kpi-carousel :deep(.trend-up),
.mobile-kpi-carousel :deep(.trend-down) {
color: var(--text-color-secondary) !important;
}
/* Eliminare chenar exterior pe cardurile din carusel (paginile 2+)
pentru a avea același stil ca pagina 1 (solduri grid fără chenar) */
.mobile-kpi-carousel :deep(.metric-card) {
border: none;
background: transparent;
box-shadow: none;
}
.mobile-kpi-carousel :deep(.financial-indicators-card) {
border: none;
background: transparent;
box-shadow: none;
}
.mobile-kpi-carousel .mobile-budget-card {
border: none;
background: transparent;
box-shadow: none;
}
/* Uniformizare dimensiuni fonturi în cardurile din carusel */
@media (max-width: 768px) {
/* Valorile principale din toate tipurile de carduri */
.mobile-kpi-carousel :deep(.metric-value),
.mobile-kpi-carousel :deep(.treasury-value),
.mobile-kpi-carousel :deep(.header-total),
.mobile-kpi-carousel :deep(.solduri-compact-card__value) {
font-size: 1.5rem !important;
line-height: 1.2;
}
/* Label-uri card */
.mobile-kpi-carousel :deep(.metric-label),
.mobile-kpi-carousel :deep(.treasury-label),
.mobile-kpi-carousel :deep(.header-label) {
font-size: var(--text-xs) !important;
}
}
/* US-2002: Solduri list for mobile first page - 1 card per row */
.solduri-grid-2x2 {
display: flex;