@jjlmoya/utils-finance 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (133) hide show
  1. package/package.json +64 -0
  2. package/src/category/i18n/en.ts +159 -0
  3. package/src/category/i18n/es.ts +159 -0
  4. package/src/category/i18n/fr.ts +159 -0
  5. package/src/category/index.ts +24 -0
  6. package/src/category/seo.astro +15 -0
  7. package/src/components/PreviewNavSidebar.astro +116 -0
  8. package/src/components/PreviewToolbar.astro +143 -0
  9. package/src/data.ts +11 -0
  10. package/src/env.d.ts +5 -0
  11. package/src/index.ts +32 -0
  12. package/src/layouts/PreviewLayout.astro +117 -0
  13. package/src/pages/[locale]/[slug].astro +146 -0
  14. package/src/pages/[locale].astro +251 -0
  15. package/src/pages/index.astro +4 -0
  16. package/src/tests/faq_count.test.ts +19 -0
  17. package/src/tests/locale_completeness.test.ts +39 -0
  18. package/src/tests/mocks/astro_mock.js +2 -0
  19. package/src/tests/no_h1_in_components.test.ts +48 -0
  20. package/src/tests/schemas_fulfillment.test.ts +23 -0
  21. package/src/tests/seo_length.test.ts +23 -0
  22. package/src/tests/title_quality.test.ts +55 -0
  23. package/src/tests/tool_validation.test.ts +17 -0
  24. package/src/tool/compoundInterest/bibliography.astro +14 -0
  25. package/src/tool/compoundInterest/component.astro +697 -0
  26. package/src/tool/compoundInterest/i18n/en.ts +212 -0
  27. package/src/tool/compoundInterest/i18n/es.ts +212 -0
  28. package/src/tool/compoundInterest/i18n/fr.ts +212 -0
  29. package/src/tool/compoundInterest/index.ts +34 -0
  30. package/src/tool/compoundInterest/logic.ts +40 -0
  31. package/src/tool/compoundInterest/seo.astro +14 -0
  32. package/src/tool/compoundInterest/ui.ts +19 -0
  33. package/src/tool/courtFeeCalculator/bibliography.astro +14 -0
  34. package/src/tool/courtFeeCalculator/component.astro +427 -0
  35. package/src/tool/courtFeeCalculator/i18n/en.ts +268 -0
  36. package/src/tool/courtFeeCalculator/i18n/es.ts +268 -0
  37. package/src/tool/courtFeeCalculator/i18n/fr.ts +268 -0
  38. package/src/tool/courtFeeCalculator/index.ts +33 -0
  39. package/src/tool/courtFeeCalculator/logic.ts +86 -0
  40. package/src/tool/courtFeeCalculator/seo.astro +14 -0
  41. package/src/tool/courtFeeCalculator/ui.ts +31 -0
  42. package/src/tool/debtSnowball/bibliography.astro +14 -0
  43. package/src/tool/debtSnowball/component.astro +1052 -0
  44. package/src/tool/debtSnowball/i18n/en.ts +288 -0
  45. package/src/tool/debtSnowball/i18n/es.ts +288 -0
  46. package/src/tool/debtSnowball/i18n/fr.ts +288 -0
  47. package/src/tool/debtSnowball/index.ts +37 -0
  48. package/src/tool/debtSnowball/logic.ts +156 -0
  49. package/src/tool/debtSnowball/seo.astro +14 -0
  50. package/src/tool/debtSnowball/ui.ts +49 -0
  51. package/src/tool/fireCalculator/bibliography.astro +14 -0
  52. package/src/tool/fireCalculator/component.astro +689 -0
  53. package/src/tool/fireCalculator/i18n/en.ts +261 -0
  54. package/src/tool/fireCalculator/i18n/es.ts +261 -0
  55. package/src/tool/fireCalculator/i18n/fr.ts +261 -0
  56. package/src/tool/fireCalculator/index.ts +33 -0
  57. package/src/tool/fireCalculator/logic.ts +108 -0
  58. package/src/tool/fireCalculator/seo.astro +14 -0
  59. package/src/tool/fireCalculator/ui.ts +33 -0
  60. package/src/tool/ibanBicSwiftConverter/bibliography.astro +14 -0
  61. package/src/tool/ibanBicSwiftConverter/component.astro +581 -0
  62. package/src/tool/ibanBicSwiftConverter/i18n/en.ts +167 -0
  63. package/src/tool/ibanBicSwiftConverter/i18n/es.ts +216 -0
  64. package/src/tool/ibanBicSwiftConverter/i18n/fr.ts +167 -0
  65. package/src/tool/ibanBicSwiftConverter/index.ts +33 -0
  66. package/src/tool/ibanBicSwiftConverter/logic.ts +101 -0
  67. package/src/tool/ibanBicSwiftConverter/seo.astro +14 -0
  68. package/src/tool/ibanBicSwiftConverter/ui.ts +17 -0
  69. package/src/tool/inflation/bibliography.astro +14 -0
  70. package/src/tool/inflation/component.astro +400 -0
  71. package/src/tool/inflation/i18n/en.ts +301 -0
  72. package/src/tool/inflation/i18n/es.ts +301 -0
  73. package/src/tool/inflation/i18n/fr.ts +301 -0
  74. package/src/tool/inflation/index.ts +34 -0
  75. package/src/tool/inflation/logic.ts +92 -0
  76. package/src/tool/inflation/seo.astro +14 -0
  77. package/src/tool/inflation/ui.ts +17 -0
  78. package/src/tool/lateInterest/bibliography.astro +14 -0
  79. package/src/tool/lateInterest/component.astro +655 -0
  80. package/src/tool/lateInterest/i18n/en.ts +255 -0
  81. package/src/tool/lateInterest/i18n/es.ts +224 -0
  82. package/src/tool/lateInterest/i18n/fr.ts +224 -0
  83. package/src/tool/lateInterest/index.ts +34 -0
  84. package/src/tool/lateInterest/logic.ts +89 -0
  85. package/src/tool/lateInterest/seo.astro +14 -0
  86. package/src/tool/lateInterest/ui.ts +33 -0
  87. package/src/tool/legalInterestRate/bibliography.astro +14 -0
  88. package/src/tool/legalInterestRate/component.astro +650 -0
  89. package/src/tool/legalInterestRate/i18n/en.ts +159 -0
  90. package/src/tool/legalInterestRate/i18n/es.ts +159 -0
  91. package/src/tool/legalInterestRate/i18n/fr.ts +159 -0
  92. package/src/tool/legalInterestRate/index.ts +33 -0
  93. package/src/tool/legalInterestRate/logic.ts +29 -0
  94. package/src/tool/legalInterestRate/seo.astro +14 -0
  95. package/src/tool/legalInterestRate/ui.ts +23 -0
  96. package/src/tool/lotteryOptimizer/bibliography.astro +14 -0
  97. package/src/tool/lotteryOptimizer/component.astro +863 -0
  98. package/src/tool/lotteryOptimizer/i18n/en.ts +188 -0
  99. package/src/tool/lotteryOptimizer/i18n/es.ts +281 -0
  100. package/src/tool/lotteryOptimizer/i18n/fr.ts +188 -0
  101. package/src/tool/lotteryOptimizer/index.ts +33 -0
  102. package/src/tool/lotteryOptimizer/logic.ts +133 -0
  103. package/src/tool/lotteryOptimizer/seo.astro +14 -0
  104. package/src/tool/lotteryOptimizer/ui.ts +33 -0
  105. package/src/tool/mortgage/bibliography.astro +14 -0
  106. package/src/tool/mortgage/component.astro +1030 -0
  107. package/src/tool/mortgage/i18n/en.ts +227 -0
  108. package/src/tool/mortgage/i18n/es.ts +227 -0
  109. package/src/tool/mortgage/i18n/fr.ts +227 -0
  110. package/src/tool/mortgage/index.ts +34 -0
  111. package/src/tool/mortgage/logic.ts +118 -0
  112. package/src/tool/mortgage/seo.astro +14 -0
  113. package/src/tool/mortgage/ui.ts +35 -0
  114. package/src/tool/percentageCalculator/bibliography.astro +14 -0
  115. package/src/tool/percentageCalculator/component.astro +640 -0
  116. package/src/tool/percentageCalculator/i18n/en.ts +233 -0
  117. package/src/tool/percentageCalculator/i18n/es.ts +233 -0
  118. package/src/tool/percentageCalculator/i18n/fr.ts +233 -0
  119. package/src/tool/percentageCalculator/index.ts +34 -0
  120. package/src/tool/percentageCalculator/logic.ts +48 -0
  121. package/src/tool/percentageCalculator/seo.astro +14 -0
  122. package/src/tool/percentageCalculator/ui.ts +30 -0
  123. package/src/tool/rentIncreaseCalculator/bibliography.astro +14 -0
  124. package/src/tool/rentIncreaseCalculator/component.astro +587 -0
  125. package/src/tool/rentIncreaseCalculator/i18n/en.ts +159 -0
  126. package/src/tool/rentIncreaseCalculator/i18n/es.ts +220 -0
  127. package/src/tool/rentIncreaseCalculator/i18n/fr.ts +159 -0
  128. package/src/tool/rentIncreaseCalculator/index.ts +33 -0
  129. package/src/tool/rentIncreaseCalculator/logic.ts +43 -0
  130. package/src/tool/rentIncreaseCalculator/seo.astro +14 -0
  131. package/src/tool/rentIncreaseCalculator/ui.ts +19 -0
  132. package/src/tools.ts +16 -0
  133. package/src/types.ts +74 -0
@@ -0,0 +1,14 @@
1
+ ---
2
+ import { SEORenderer } from '@jjlmoya/utils-shared';
3
+ import { ibanBicSwift } from './index';
4
+ import type { KnownLocale } from '../../types';
5
+
6
+ interface Props {
7
+ locale?: KnownLocale;
8
+ }
9
+
10
+ const { locale = 'es' } = Astro.props;
11
+ const content = await ibanBicSwift.i18n[locale]?.();
12
+ if (!content) return null;
13
+ ---
14
+ <SEORenderer content={{ locale: locale as string, sections: content.seo }} />
@@ -0,0 +1,17 @@
1
+ export interface IBANBICSwiftUI {
2
+ labelTitle: string;
3
+ labelDescription: string;
4
+ labelInputIBAN: string;
5
+ labelInputPlaceholder: string;
6
+ labelButtonConvert: string;
7
+ labelBIC: string;
8
+ labelCountry: string;
9
+ labelBank: string;
10
+ labelError: string;
11
+ labelCopyButton: string;
12
+ labelCopied: string;
13
+ labelBankNotIdentified: string;
14
+ labelBankOutsideSpain: string;
15
+ labelInvalidIBAN: string;
16
+ labelFormattingOK: string;
17
+ }
@@ -0,0 +1,14 @@
1
+ ---
2
+ import { Bibliography as SharedBibliography } from '@jjlmoya/utils-shared';
3
+ import { inflation } from './index';
4
+ import type { KnownLocale } from '../../types';
5
+
6
+ interface Props {
7
+ locale?: KnownLocale;
8
+ }
9
+
10
+ const { locale = 'es' } = Astro.props;
11
+ const content = await inflation.i18n[locale]?.();
12
+ ---
13
+
14
+ {content && <SharedBibliography links={content.bibliography} />}
@@ -0,0 +1,400 @@
1
+ ---
2
+ import type { InflationUI } from './ui';
3
+ import { InflationCalculator } from './logic';
4
+
5
+ interface Props {
6
+ ui: InflationUI;
7
+ }
8
+
9
+ const { ui } = Astro.props;
10
+
11
+ const availableYears = InflationCalculator.getAvailableYears();
12
+ ---
13
+
14
+ <div class="inflation-container" data-currency-locale={ui.currencyLocale} data-currency-code={ui.currencyCode}>
15
+ <div class="inflation-header">
16
+ <div class="inflation-header-title-group">
17
+ <div class="inflation-header-icon">
18
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M3 3v18h18"></path><path d="m19 9-5 5-4-4-3 3"></path></svg>
19
+ </div>
20
+ <h2 class="inflation-header-title">{ui.labelTitle}</h2>
21
+ </div>
22
+ </div>
23
+
24
+ <div class="inflation-content">
25
+ <p class="inflation-description">
26
+ {ui.labelCalculatedOn}
27
+ </p>
28
+
29
+ <div class="inflation-grid">
30
+ <div class="inflation-panel inflation-panel-left">
31
+ <label class="inflation-label">{ui.labelInitialAmount}</label>
32
+ <div class="inflation-input-wrapper">
33
+ <input
34
+ type="number"
35
+ id="inflation-amount"
36
+ value="1000"
37
+ class="inflation-input"
38
+ />
39
+ <span class="inflation-currency">{ui.currencySymbol}</span>
40
+ </div>
41
+
42
+ <label class="inflation-label" style="margin-top: 1rem;">{ui.labelInitialYear}</label>
43
+ <select id="inflation-year" class="inflation-select">
44
+ {availableYears.map((year) => (
45
+ <option value={year} selected={year === 2000}>
46
+ {year}
47
+ </option>
48
+ ))}
49
+ </select>
50
+ </div>
51
+
52
+ <div class="inflation-arrow">
53
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"><path d="M5 12h14"></path><path d="m12 5 7 7-7 7"></path></svg>
54
+ </div>
55
+
56
+ <div class="inflation-panel inflation-panel-right">
57
+ <label class="inflation-label">{ui.labelFinalAmount}</label>
58
+ <div class="inflation-result-wrapper">
59
+ <div id="inflation-result" class="inflation-result">0 {ui.currencySymbol}</div>
60
+ </div>
61
+
62
+ <div class="inflation-year-badge">{ui.labelFinalYear}</div>
63
+ </div>
64
+ </div>
65
+
66
+ <div class="inflation-stat">
67
+ <div id="inflation-change-percent" class="inflation-stat-badge">
68
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="23 18 13.5 8.5 8.5 13.5 1 6"></polyline><polyline points="17 18 23 18 23 12"></polyline></svg>
69
+ <span>+0 % {ui.labelInflationAccumulated}</span>
70
+ </div>
71
+ </div>
72
+ </div>
73
+ </div>
74
+
75
+ <script>
76
+ import { InflationCalculator } from './logic';
77
+
78
+ const container = document.querySelector('.inflation-container') as HTMLElement;
79
+ const currencyLocale = container.dataset.currencyLocale || 'es-ES';
80
+ const currencyCode = container.dataset.currencyCode || 'EUR';
81
+
82
+ const amountEl = document.getElementById('inflation-amount') as HTMLInputElement;
83
+ const yearEl = document.getElementById('inflation-year') as HTMLSelectElement;
84
+ const resultEl = document.getElementById('inflation-result');
85
+ const percentEl = document.getElementById('inflation-change-percent');
86
+
87
+ const formatMoney = (val: number): string =>
88
+ new Intl.NumberFormat(currencyLocale, {
89
+ style: 'currency',
90
+ currency: currencyCode,
91
+ maximumFractionDigits: 2,
92
+ })
93
+ .format(val)
94
+ .replace(/\u00A0/g, ' ');
95
+
96
+ function updateInflation(): void {
97
+ const val = Number(amountEl.value) || 0;
98
+ const year = Number(yearEl.value);
99
+
100
+ const result = InflationCalculator.calculate(val, year, 2026);
101
+
102
+ if (resultEl) {
103
+ resultEl.innerText = formatMoney(result.finalAmount);
104
+ }
105
+
106
+ if (percentEl && val > 0) {
107
+ const sign = result.percentChange > 0 ? '+' : '';
108
+ const span = percentEl.querySelector('span');
109
+ if (span) {
110
+ span.innerText = `${sign}${result.percentChange} % Inflación Acumulada`;
111
+ }
112
+ }
113
+ }
114
+
115
+ amountEl?.addEventListener('input', updateInflation);
116
+ yearEl?.addEventListener('change', updateInflation);
117
+
118
+ updateInflation();
119
+ </script>
120
+
121
+ <style is:global>
122
+ :root {
123
+ --inflation-color-primary: #f59e0b;
124
+ --inflation-color-primary-dark: #d97706;
125
+ --inflation-color-primary-light: #fcd34d;
126
+ --inflation-color-primary-extra-light: #fef3c7;
127
+ --inflation-color-danger: #ef4444;
128
+ --inflation-color-danger-light: #fee2e2;
129
+ --inflation-color-text-primary: #1f2937;
130
+ --inflation-color-text-secondary: #6b7280;
131
+ --inflation-color-text-light: #9ca3af;
132
+ --inflation-color-bg-primary: #fff;
133
+ --inflation-color-bg-secondary: #f9fafb;
134
+ --inflation-color-border: #e5e7eb;
135
+ }
136
+
137
+ .theme-dark,
138
+ [data-theme='dark'] {
139
+ --inflation-color-primary: #fbbf24;
140
+ --inflation-color-primary-dark: #f59e0b;
141
+ --inflation-color-primary-light: #b45309;
142
+ --inflation-color-primary-extra-light: #78350f;
143
+ --inflation-color-danger: #f87171;
144
+ --inflation-color-danger-light: #7f1d1d;
145
+ --inflation-color-text-primary: #f3f4f6;
146
+ --inflation-color-text-secondary: #d1d5db;
147
+ --inflation-color-text-light: #9ca3af;
148
+ --inflation-color-bg-primary: #1f2937;
149
+ --inflation-color-bg-secondary: #111827;
150
+ --inflation-color-border: #374151;
151
+ }
152
+
153
+ @media (prefers-color-scheme: dark) {
154
+ :root {
155
+ --inflation-color-primary: #fbbf24;
156
+ --inflation-color-primary-dark: #f59e0b;
157
+ --inflation-color-primary-light: #b45309;
158
+ --inflation-color-primary-extra-light: #78350f;
159
+ --inflation-color-danger: #f87171;
160
+ --inflation-color-danger-light: #7f1d1d;
161
+ --inflation-color-text-primary: #f3f4f6;
162
+ --inflation-color-text-secondary: #d1d5db;
163
+ --inflation-color-text-light: #9ca3af;
164
+ --inflation-color-bg-primary: #1f2937;
165
+ --inflation-color-bg-secondary: #111827;
166
+ --inflation-color-border: #374151;
167
+ }
168
+ }
169
+
170
+ .inflation-container {
171
+ background-color: var(--inflation-color-bg-primary);
172
+ border-radius: 1.5rem;
173
+ box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.1);
174
+ border: 1px solid var(--inflation-color-border);
175
+ overflow: hidden;
176
+ }
177
+
178
+ .inflation-header {
179
+ padding: 1.5rem;
180
+ border-bottom: 1px solid var(--inflation-color-border);
181
+ background-color: rgba(245, 158, 11, 0.05);
182
+ }
183
+
184
+ .inflation-header-title-group {
185
+ display: flex;
186
+ align-items: center;
187
+ gap: 0.75rem;
188
+ }
189
+
190
+ .inflation-header-icon {
191
+ width: 2.5rem;
192
+ height: 2.5rem;
193
+ padding: 0.625rem;
194
+ background-color: rgba(245, 158, 11, 0.1);
195
+ border-radius: 0.75rem;
196
+ color: var(--inflation-color-primary);
197
+ flex-shrink: 0;
198
+ }
199
+
200
+ .inflation-header-icon svg {
201
+ width: 100%;
202
+ height: 100%;
203
+ }
204
+
205
+ .inflation-header-title {
206
+ font-size: 1.25rem;
207
+ font-weight: 700;
208
+ color: var(--inflation-color-text-primary);
209
+ margin: 0;
210
+ }
211
+
212
+ .inflation-content {
213
+ padding: 2rem;
214
+ }
215
+
216
+ .inflation-description {
217
+ font-size: 0.875rem;
218
+ color: var(--inflation-color-text-secondary);
219
+ margin: 0 0 2rem;
220
+ text-align: center;
221
+ }
222
+
223
+ .inflation-grid {
224
+ display: flex;
225
+ flex-direction: column;
226
+ gap: 2rem;
227
+ margin-bottom: 2rem;
228
+ }
229
+
230
+ @media (min-width: 768px) {
231
+ .inflation-grid {
232
+ flex-direction: row;
233
+ align-items: center;
234
+ gap: 1.5rem;
235
+ }
236
+ }
237
+
238
+ .inflation-panel {
239
+ flex: 1;
240
+ padding: 2rem;
241
+ border-radius: 1.5rem;
242
+ border: 2px solid var(--inflation-color-border);
243
+ background-color: var(--inflation-color-bg-secondary);
244
+ }
245
+
246
+ .inflation-panel-left {
247
+ border-top: 4px solid var(--inflation-color-border);
248
+ }
249
+
250
+ .inflation-panel-right {
251
+ background-color: rgba(245, 158, 11, 0.05);
252
+ border-color: rgba(245, 158, 11, 0.2);
253
+ border-top: 4px solid var(--inflation-color-primary);
254
+ }
255
+
256
+ .inflation-label {
257
+ display: block;
258
+ font-size: 0.75rem;
259
+ font-weight: 700;
260
+ color: var(--inflation-color-text-light);
261
+ text-transform: uppercase;
262
+ letter-spacing: 0.05em;
263
+ margin-bottom: 0.75rem;
264
+ }
265
+
266
+ .inflation-input-wrapper {
267
+ position: relative;
268
+ display: flex;
269
+ align-items: center;
270
+ }
271
+
272
+ .inflation-input {
273
+ width: 100%;
274
+ padding: 1rem;
275
+ background-color: var(--inflation-color-bg-primary);
276
+ border: 2px solid var(--inflation-color-border);
277
+ border-radius: 0.75rem;
278
+ font-size: 1.875rem;
279
+ font-weight: 700;
280
+ color: var(--inflation-color-text-primary);
281
+ text-align: center;
282
+ transition: all 0.2s ease;
283
+ }
284
+
285
+ .inflation-input:focus {
286
+ border-color: var(--inflation-color-primary);
287
+ outline: none;
288
+ }
289
+
290
+ .inflation-currency {
291
+ position: absolute;
292
+ right: 1rem;
293
+ color: var(--inflation-color-text-light);
294
+ font-size: 0.875rem;
295
+ }
296
+
297
+ .inflation-select {
298
+ width: 100%;
299
+ padding: 0.875rem 1rem;
300
+ background-color: var(--inflation-color-bg-primary);
301
+ border: 2px solid var(--inflation-color-border);
302
+ border-radius: 0.75rem;
303
+ font-size: 1.125rem;
304
+ font-weight: 700;
305
+ color: var(--inflation-color-text-primary);
306
+ cursor: pointer;
307
+ transition: all 0.2s ease;
308
+ }
309
+
310
+ .inflation-select:focus {
311
+ border-color: var(--inflation-color-primary);
312
+ outline: none;
313
+ }
314
+
315
+ .inflation-select:hover {
316
+ border-color: var(--inflation-color-primary);
317
+ }
318
+
319
+ .inflation-arrow {
320
+ display: flex;
321
+ align-items: center;
322
+ justify-content: center;
323
+ color: var(--inflation-color-primary);
324
+ flex-shrink: 0;
325
+ }
326
+
327
+ .inflation-arrow svg {
328
+ width: 2rem;
329
+ height: 2rem;
330
+ }
331
+
332
+ @media (max-width: 767px) {
333
+ .inflation-arrow {
334
+ transform: rotate(90deg);
335
+ margin: 1rem 0;
336
+ }
337
+ }
338
+
339
+ .inflation-result-wrapper {
340
+ display: flex;
341
+ align-items: center;
342
+ justify-content: center;
343
+ min-height: 100px;
344
+ }
345
+
346
+ .inflation-result {
347
+ font-size: 2.25rem;
348
+ font-weight: 700;
349
+ color: var(--inflation-color-primary);
350
+ text-align: center;
351
+ }
352
+
353
+ .inflation-year-badge {
354
+ text-align: center;
355
+ display: inline-block;
356
+ width: 100%;
357
+ padding: 0.5rem 1rem;
358
+ background-color: var(--inflation-color-bg-primary);
359
+ border: 1px solid var(--inflation-color-border);
360
+ border-radius: 0.75rem;
361
+ font-size: 0.875rem;
362
+ font-weight: 700;
363
+ color: var(--inflation-color-text-secondary);
364
+ margin-top: 1rem;
365
+ }
366
+
367
+ .inflation-stat {
368
+ text-align: center;
369
+ animation: fade-in-up 0.7s ease 0.15s both;
370
+ }
371
+
372
+ @keyframes fade-in-up {
373
+ from {
374
+ opacity: 0;
375
+ transform: translateY(1rem);
376
+ }
377
+ to {
378
+ opacity: 1;
379
+ transform: translateY(0);
380
+ }
381
+ }
382
+
383
+ .inflation-stat-badge {
384
+ display: inline-flex;
385
+ align-items: center;
386
+ gap: 0.5rem;
387
+ padding: 0.75rem 1.5rem;
388
+ background-color: var(--inflation-color-danger-light);
389
+ color: var(--inflation-color-danger);
390
+ border-radius: 1.5rem;
391
+ font-weight: 700;
392
+ font-size: 1.125rem;
393
+ border: 1px solid var(--inflation-color-danger);
394
+ }
395
+
396
+ .inflation-stat-badge svg {
397
+ width: 1.25rem;
398
+ height: 1.25rem;
399
+ }
400
+ </style>