@jjlmoya/utils-finance 1.42.0 → 1.44.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 (62) hide show
  1. package/package.json +1 -1
  2. package/src/category/index.ts +3 -1
  3. package/src/entries.ts +7 -1
  4. package/src/index.ts +1 -0
  5. package/src/tests/locale_completeness.test.ts +2 -2
  6. package/src/tests/tool_validation.test.ts +2 -2
  7. package/src/tool/capitalGainsTaxScenarioCalculator/bibliography.astro +11 -0
  8. package/src/tool/capitalGainsTaxScenarioCalculator/bibliography.ts +12 -0
  9. package/src/tool/capitalGainsTaxScenarioCalculator/capital-gains-tax-scenario-calculator.css +469 -0
  10. package/src/tool/capitalGainsTaxScenarioCalculator/component.astro +328 -0
  11. package/src/tool/capitalGainsTaxScenarioCalculator/entry.ts +26 -0
  12. package/src/tool/capitalGainsTaxScenarioCalculator/i18n/de.ts +3 -0
  13. package/src/tool/capitalGainsTaxScenarioCalculator/i18n/en.ts +181 -0
  14. package/src/tool/capitalGainsTaxScenarioCalculator/i18n/es.ts +3 -0
  15. package/src/tool/capitalGainsTaxScenarioCalculator/i18n/fr.ts +3 -0
  16. package/src/tool/capitalGainsTaxScenarioCalculator/i18n/id.ts +3 -0
  17. package/src/tool/capitalGainsTaxScenarioCalculator/i18n/it.ts +3 -0
  18. package/src/tool/capitalGainsTaxScenarioCalculator/i18n/ja.ts +3 -0
  19. package/src/tool/capitalGainsTaxScenarioCalculator/i18n/ko.ts +3 -0
  20. package/src/tool/capitalGainsTaxScenarioCalculator/i18n/nl.ts +3 -0
  21. package/src/tool/capitalGainsTaxScenarioCalculator/i18n/pl.ts +3 -0
  22. package/src/tool/capitalGainsTaxScenarioCalculator/i18n/pt.ts +3 -0
  23. package/src/tool/capitalGainsTaxScenarioCalculator/i18n/ru.ts +3 -0
  24. package/src/tool/capitalGainsTaxScenarioCalculator/i18n/shared.ts +153 -0
  25. package/src/tool/capitalGainsTaxScenarioCalculator/i18n/sv.ts +3 -0
  26. package/src/tool/capitalGainsTaxScenarioCalculator/i18n/tr.ts +3 -0
  27. package/src/tool/capitalGainsTaxScenarioCalculator/i18n/zh.ts +3 -0
  28. package/src/tool/capitalGainsTaxScenarioCalculator/index.ts +11 -0
  29. package/src/tool/capitalGainsTaxScenarioCalculator/logic.test.ts +71 -0
  30. package/src/tool/capitalGainsTaxScenarioCalculator/logic.ts +137 -0
  31. package/src/tool/capitalGainsTaxScenarioCalculator/seo.astro +11 -0
  32. package/src/tool/capitalGainsTaxScenarioCalculator/ui.ts +40 -0
  33. package/src/tool/capitalGainsTaxScenarioCalculator/validation.ts +34 -0
  34. package/src/tool/insuranceDeductibleBreakEvenCalculator/bibliography.astro +10 -0
  35. package/src/tool/insuranceDeductibleBreakEvenCalculator/bibliography.ts +6 -0
  36. package/src/tool/insuranceDeductibleBreakEvenCalculator/component.astro +172 -0
  37. package/src/tool/insuranceDeductibleBreakEvenCalculator/currency.test.ts +13 -0
  38. package/src/tool/insuranceDeductibleBreakEvenCalculator/currency.ts +26 -0
  39. package/src/tool/insuranceDeductibleBreakEvenCalculator/entry.ts +28 -0
  40. package/src/tool/insuranceDeductibleBreakEvenCalculator/i18n/content-factory.ts +147 -0
  41. package/src/tool/insuranceDeductibleBreakEvenCalculator/i18n/de.ts +2 -0
  42. package/src/tool/insuranceDeductibleBreakEvenCalculator/i18n/en.ts +100 -0
  43. package/src/tool/insuranceDeductibleBreakEvenCalculator/i18n/es.ts +2 -0
  44. package/src/tool/insuranceDeductibleBreakEvenCalculator/i18n/fr.ts +2 -0
  45. package/src/tool/insuranceDeductibleBreakEvenCalculator/i18n/id.ts +2 -0
  46. package/src/tool/insuranceDeductibleBreakEvenCalculator/i18n/it.ts +2 -0
  47. package/src/tool/insuranceDeductibleBreakEvenCalculator/i18n/ja.ts +2 -0
  48. package/src/tool/insuranceDeductibleBreakEvenCalculator/i18n/ko.ts +2 -0
  49. package/src/tool/insuranceDeductibleBreakEvenCalculator/i18n/nl.ts +2 -0
  50. package/src/tool/insuranceDeductibleBreakEvenCalculator/i18n/pl.ts +2 -0
  51. package/src/tool/insuranceDeductibleBreakEvenCalculator/i18n/pt.ts +2 -0
  52. package/src/tool/insuranceDeductibleBreakEvenCalculator/i18n/ru.ts +2 -0
  53. package/src/tool/insuranceDeductibleBreakEvenCalculator/i18n/sv.ts +2 -0
  54. package/src/tool/insuranceDeductibleBreakEvenCalculator/i18n/tr.ts +2 -0
  55. package/src/tool/insuranceDeductibleBreakEvenCalculator/i18n/zh.ts +2 -0
  56. package/src/tool/insuranceDeductibleBreakEvenCalculator/index.ts +11 -0
  57. package/src/tool/insuranceDeductibleBreakEvenCalculator/insurance-deductible-break-even-calculator.css +424 -0
  58. package/src/tool/insuranceDeductibleBreakEvenCalculator/logic.test.ts +40 -0
  59. package/src/tool/insuranceDeductibleBreakEvenCalculator/logic.ts +72 -0
  60. package/src/tool/insuranceDeductibleBreakEvenCalculator/seo.astro +11 -0
  61. package/src/tool/insuranceDeductibleBreakEvenCalculator/ui.ts +33 -0
  62. package/src/tools.ts +3 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jjlmoya/utils-finance",
3
- "version": "1.42.0",
3
+ "version": "1.44.0",
4
4
  "type": "module",
5
5
  "main": "./src/index.ts",
6
6
  "types": "./src/index.ts",
@@ -21,10 +21,12 @@ import { dividendYield } from '../tool/dividendYield/entry';
21
21
  import { inflationPurchasingPower } from '../tool/inflationPurchasingPower/entry';
22
22
  import { subscriptionCostAnnualizer } from '../tool/subscriptionCostAnnualizer/entry';
23
23
  import { loanToIncomeRatio } from '../tool/loanToIncomeRatio/entry';
24
+ import { capitalGainsTaxScenarioCalculator } from '../tool/capitalGainsTaxScenarioCalculator/entry';
25
+ import { insuranceDeductibleBreakEvenCalculator } from '../tool/insuranceDeductibleBreakEvenCalculator/entry';
24
26
 
25
27
  export const financeCategory: FinanceCategoryEntry = {
26
28
  icon: 'mdi:finance',
27
- tools: [compoundInterest, financialFreedom, savingsRate, profitability, mortgage, inflation, percentageCalculator, lateInterest, ibanBicSwift, rentIncrease, lotteryOptimizer, courtFeeCalculator, legalInterestRate, fireCalculator, debtSnowball, revolvingCardCalculator, pesetaValue, salaryEmployerCost, dividendYield, inflationPurchasingPower, subscriptionCostAnnualizer, loanToIncomeRatio],
29
+ tools: [compoundInterest, financialFreedom, savingsRate, profitability, mortgage, inflation, percentageCalculator, lateInterest, ibanBicSwift, rentIncrease, lotteryOptimizer, courtFeeCalculator, legalInterestRate, fireCalculator, debtSnowball, revolvingCardCalculator, pesetaValue, salaryEmployerCost, dividendYield, inflationPurchasingPower, subscriptionCostAnnualizer, loanToIncomeRatio, capitalGainsTaxScenarioCalculator, insuranceDeductibleBreakEvenCalculator],
28
30
  i18n: {
29
31
  en: () => import('./i18n/en').then((m) => m.content),
30
32
  es: () => import('./i18n/es').then((m) => m.content),
package/src/entries.ts CHANGED
@@ -46,6 +46,10 @@ export { loanToIncomeRatio } from './tool/loanToIncomeRatio/entry';
46
46
  export type { LoanToIncomeRatioLocaleContent } from './tool/loanToIncomeRatio/entry';
47
47
  export { rentalDepositReturn } from './tool/rentalDepositReturn/entry';
48
48
  export type { RentalDepositReturnLocaleContent } from './tool/rentalDepositReturn/entry';
49
+ export { capitalGainsTaxScenarioCalculator } from './tool/capitalGainsTaxScenarioCalculator/entry';
50
+ export type { CapitalGainsTaxScenarioCalculatorLocaleContent } from './tool/capitalGainsTaxScenarioCalculator/entry';
51
+ export { insuranceDeductibleBreakEvenCalculator } from './tool/insuranceDeductibleBreakEvenCalculator/entry';
52
+ export type { InsuranceDeductibleBreakEvenCalculatorLocaleContent } from './tool/insuranceDeductibleBreakEvenCalculator/entry';
49
53
  export { financeCategory } from './category';
50
54
  import { compoundInterest } from './tool/compoundInterest/entry';
51
55
  import { financialFreedom } from './tool/financialFreedom/entry';
@@ -70,4 +74,6 @@ import { inflationPurchasingPower } from './tool/inflationPurchasingPower/entry'
70
74
  import { subscriptionCostAnnualizer } from './tool/subscriptionCostAnnualizer/entry';
71
75
  import { loanToIncomeRatio } from './tool/loanToIncomeRatio/entry';
72
76
  import { rentalDepositReturn } from './tool/rentalDepositReturn/entry';
73
- export const ALL_ENTRIES = [compoundInterest, financialFreedom, savingsRate, profitability, courtFeeCalculator, debtSnowball, fireCalculator, ibanBicSwift, inflation, lateInterest, legalInterestRate, lotteryOptimizer, mortgage, percentageCalculator, rentIncrease, revolvingCardCalculator, pesetaValue, salaryEmployerCost, dividendYield, mortgageExtraPaymentPlanner, inflationPurchasingPower, subscriptionCostAnnualizer, loanToIncomeRatio, rentalDepositReturn];
77
+ import { capitalGainsTaxScenarioCalculator } from './tool/capitalGainsTaxScenarioCalculator/entry';
78
+ import { insuranceDeductibleBreakEvenCalculator } from './tool/insuranceDeductibleBreakEvenCalculator/entry';
79
+ export const ALL_ENTRIES = [compoundInterest, financialFreedom, savingsRate, profitability, courtFeeCalculator, debtSnowball, fireCalculator, ibanBicSwift, inflation, lateInterest, legalInterestRate, lotteryOptimizer, mortgage, percentageCalculator, rentIncrease, revolvingCardCalculator, pesetaValue, salaryEmployerCost, dividendYield, mortgageExtraPaymentPlanner, inflationPurchasingPower, subscriptionCostAnnualizer, loanToIncomeRatio, rentalDepositReturn, capitalGainsTaxScenarioCalculator, insuranceDeductibleBreakEvenCalculator];
package/src/index.ts CHANGED
@@ -36,3 +36,4 @@ export { SALARY_EMPLOYER_COST_TOOL } from './tool/salaryEmployerCost';
36
36
  export { DIVIDEND_YIELD_TOOL } from './tool/dividendYield';
37
37
  export { MORTGAGE_EXTRA_PAYMENT_PLANNER_TOOL } from './tool/mortgageExtraPaymentPlanner';
38
38
  export { LOAN_TO_INCOME_RATIO_TOOL } from './tool/loanToIncomeRatio';
39
+ export { CAPITAL_GAINS_TAX_SCENARIO_CALCULATOR_TOOL } from './tool/capitalGainsTaxScenarioCalculator';
@@ -25,7 +25,7 @@ describe('Locale Completeness Validation', () => {
25
25
  });
26
26
  });
27
27
 
28
- it('all 24 tools registered', () => {
29
- expect(ALL_TOOLS.length).toBe(24);
28
+ it('all 26 tools registered', () => {
29
+ expect(ALL_TOOLS.length).toBe(26);
30
30
  });
31
31
  });
@@ -4,8 +4,8 @@ import { financeCategory } from '../data';
4
4
 
5
5
  describe('Tool Validation Suite', () => {
6
6
  describe('Library Registration', () => {
7
- it('should have 24 tools in ALL_TOOLS', () => {
8
- expect(ALL_TOOLS.length).toBe(24);
7
+ it('should have 26 tools in ALL_TOOLS', () => {
8
+ expect(ALL_TOOLS.length).toBe(26);
9
9
  });
10
10
 
11
11
  it('financeCategory should be defined', () => {
@@ -0,0 +1,11 @@
1
+ ---
2
+ import { Bibliography as SharedBibliography } from '@jjlmoya/utils-shared';
3
+ import { capitalGainsTaxScenarioCalculator } from './index';
4
+ import type { KnownLocale } from '../../types';
5
+
6
+ interface Props { locale?: KnownLocale; }
7
+ const { locale = 'en' } = Astro.props;
8
+ const content = await capitalGainsTaxScenarioCalculator.i18n[locale]?.() ?? await capitalGainsTaxScenarioCalculator.i18n.en?.();
9
+ ---
10
+
11
+ {content && <SharedBibliography links={content.bibliography} />}
@@ -0,0 +1,12 @@
1
+ import type { BibliographyEntry } from '../../types';
2
+
3
+ export const bibliography: BibliographyEntry[] = [
4
+ {
5
+ name: 'Agencia Tributaria: Reglas generales de cálculo',
6
+ url: 'https://sede.agenciatributaria.gob.es/Sede/ayuda/manuales-videos-folletos/manuales-practicos/irpf-2025/c11-ganancias-perdidas-patrimoniales/determinacion-importe-ganancias-perdidas-patrimon-generales/derivadas-transmisiones-onerosas-lucrativas/reglas-generales-calculo.html',
7
+ },
8
+ {
9
+ name: 'IRS Publication 551: Basis of Assets',
10
+ url: 'https://www.irs.gov/publications/p551',
11
+ },
12
+ ];
@@ -0,0 +1,469 @@
1
+ .cgt-tool {
2
+ --cgt-ink: #27261f;
3
+ --cgt-muted: #716d61;
4
+ --cgt-paper: #fbf6e9;
5
+ --cgt-surface: #f1e8d5;
6
+ --cgt-edge: #d6c8a8;
7
+ --cgt-accent: #b35d39;
8
+ --cgt-accent-soft: #efd6c5;
9
+ --cgt-cool: #39747a;
10
+ --cgt-gold: #c18a2c;
11
+ --cgt-danger: #a23e46;
12
+ --cgt-shadow: #55463122;
13
+
14
+ color: var(--cgt-ink);
15
+ margin: 0 auto;
16
+ max-width: 74rem;
17
+ width: min(100%, calc(100vw - 2rem));
18
+ }
19
+
20
+ :global(.theme-dark) .cgt-tool,
21
+ :global([data-theme='dark']) .cgt-tool {
22
+ --cgt-ink: #f7f0e4;
23
+ --cgt-muted: #c3b9a8;
24
+ --cgt-paper: #24251f;
25
+ --cgt-surface: #303128;
26
+ --cgt-edge: #555548;
27
+ --cgt-accent: #e28b63;
28
+ --cgt-accent-soft: #5d352a;
29
+ --cgt-cool: #87c8c7;
30
+ --cgt-gold: #e4b55b;
31
+ --cgt-danger: #ef8d8b;
32
+ --cgt-shadow: #0007;
33
+ }
34
+
35
+ .cgt-card {
36
+ background: var(--cgt-paper);
37
+ border: 1px solid var(--cgt-edge);
38
+ border-radius: 1.35rem;
39
+ box-shadow: 0 1rem 2.5rem var(--cgt-shadow);
40
+ overflow: hidden;
41
+ }
42
+
43
+ .cgt-glance {
44
+ align-items: center;
45
+ background: var(--cgt-accent);
46
+ color: var(--cgt-paper);
47
+ display: grid;
48
+ gap: 0.35rem 1rem;
49
+ grid-template-columns: 1.2fr 1fr 1fr;
50
+ padding: 0.85rem 1.35rem;
51
+ }
52
+
53
+ .cgt-glance span {
54
+ font-size: 0.72rem;
55
+ font-weight: 800;
56
+ }
57
+
58
+ .cgt-glance strong {
59
+ display: grid;
60
+ font-size: 1.05rem;
61
+ font-variant-numeric: tabular-nums;
62
+ gap: 0.12rem;
63
+ text-align: right;
64
+ }
65
+
66
+ .cgt-glance strong small {
67
+ font-size: 0.64rem;
68
+ font-weight: 700;
69
+ opacity: 0.82;
70
+ }
71
+
72
+ .cgt-inputs {
73
+ background: var(--cgt-surface);
74
+ border-bottom: 1px solid var(--cgt-edge);
75
+ display: grid;
76
+ gap: 0.9rem;
77
+ grid-template-columns: repeat(4, minmax(0, 1fr));
78
+ padding: 1.35rem;
79
+ }
80
+
81
+ .cgt-field {
82
+ display: grid;
83
+ gap: 0.35rem;
84
+ min-width: 0;
85
+ }
86
+
87
+ .cgt-select-wrap {
88
+ position: relative;
89
+ }
90
+
91
+ .cgt-select-arrow {
92
+ border-bottom: 2px solid var(--cgt-accent);
93
+ border-right: 2px solid var(--cgt-accent);
94
+ height: 0.55rem;
95
+ pointer-events: none;
96
+ position: absolute;
97
+ right: 1rem;
98
+ top: 50%;
99
+ transform: translateY(-70%) rotate(45deg);
100
+ transition: transform 0.2s ease, border-color 0.2s ease;
101
+ width: 0.55rem;
102
+ }
103
+
104
+ .cgt-select-wrap:focus-within .cgt-select-arrow {
105
+ border-color: var(--cgt-cool);
106
+ transform: translateY(-25%) rotate(225deg);
107
+ }
108
+
109
+ .cgt-currency-field select {
110
+ appearance: none;
111
+ background: var(--cgt-paper);
112
+ border: 1px solid var(--cgt-edge);
113
+ border-radius: 0.6rem;
114
+ cursor: pointer;
115
+ color: var(--cgt-ink);
116
+ font: inherit;
117
+ min-height: 2.8rem;
118
+ padding: 0.65rem 2.8rem 0.65rem 0.7rem;
119
+ transition: border-color 0.2s ease, box-shadow 0.2s ease;
120
+ width: 100%;
121
+ color-scheme: light;
122
+ }
123
+
124
+ .cgt-currency-field select:hover {
125
+ border-color: var(--cgt-accent);
126
+ box-shadow: 0 0 0 3px color-mix(in srgb, var(--cgt-accent) 12%, transparent);
127
+ }
128
+
129
+ .cgt-currency-field select option {
130
+ background: var(--cgt-paper);
131
+ color: var(--cgt-ink);
132
+ }
133
+
134
+ :global(.theme-dark) .cgt-currency-field select,
135
+ :global([data-theme='dark']) .cgt-currency-field select {
136
+ color-scheme: dark;
137
+ }
138
+
139
+ .cgt-field label {
140
+ font-size: 0.78rem;
141
+ font-weight: 800;
142
+ line-height: 1.25;
143
+ }
144
+
145
+ .cgt-input-wrap {
146
+ align-items: center;
147
+ display: flex;
148
+ position: relative;
149
+ }
150
+
151
+ .cgt-input-wrap input {
152
+ background: var(--cgt-paper);
153
+ border: 1px solid var(--cgt-edge);
154
+ border-radius: 0.6rem;
155
+ box-sizing: border-box;
156
+ color: var(--cgt-ink);
157
+ font: inherit;
158
+ min-height: 2.8rem;
159
+ padding: 0.65rem 2rem 0.65rem 0.7rem;
160
+ width: 100%;
161
+ }
162
+
163
+ .cgt-input-wrap input:focus-visible,
164
+ .cgt-currency-field select:focus-visible,
165
+ .cgt-button:focus-visible,
166
+ .cgt-method summary:focus-visible {
167
+ outline: 3px solid var(--cgt-accent);
168
+ outline-offset: 2px;
169
+ }
170
+
171
+ .cgt-input-wrap input[aria-invalid="true"] {
172
+ border-color: var(--cgt-danger);
173
+ }
174
+
175
+ .cgt-input-wrap span {
176
+ color: var(--cgt-muted);
177
+ font-size: 0.8rem;
178
+ font-weight: 800;
179
+ pointer-events: none;
180
+ position: absolute;
181
+ right: 0.7rem;
182
+ }
183
+
184
+ .cgt-field small {
185
+ color: var(--cgt-danger);
186
+ font-size: 0.68rem;
187
+ line-height: 1.3;
188
+ }
189
+
190
+ .cgt-actions {
191
+ align-items: center;
192
+ display: flex;
193
+ flex-wrap: wrap;
194
+ gap: 0.7rem;
195
+ padding: 1rem 1.35rem 0;
196
+ }
197
+
198
+ .cgt-button {
199
+ border: 1px solid var(--cgt-accent);
200
+ border-radius: 99rem;
201
+ cursor: pointer;
202
+ font: inherit;
203
+ font-weight: 800;
204
+ min-height: 2.7rem;
205
+ padding: 0.55rem 1rem;
206
+ }
207
+
208
+ .cgt-button-primary {
209
+ background: var(--cgt-accent);
210
+ color: var(--cgt-paper);
211
+ }
212
+
213
+ .cgt-button-secondary {
214
+ background: transparent;
215
+ color: var(--cgt-accent);
216
+ }
217
+
218
+ .cgt-copy-status {
219
+ color: var(--cgt-cool);
220
+ font-size: 0.76rem;
221
+ font-weight: 750;
222
+ }
223
+
224
+ .cgt-output {
225
+ display: grid;
226
+ gap: 1.1rem;
227
+ padding: 1.35rem;
228
+ }
229
+
230
+ .cgt-status {
231
+ align-self: start;
232
+ background: var(--cgt-accent-soft);
233
+ border-radius: 99rem;
234
+ color: var(--cgt-accent);
235
+ display: inline-flex;
236
+ font-size: 0.75rem;
237
+ font-weight: 850;
238
+ justify-self: start;
239
+ padding: 0.42rem 0.75rem;
240
+ }
241
+
242
+ .cgt-tool[data-status="loss"] .cgt-status {
243
+ color: var(--cgt-danger);
244
+ }
245
+
246
+ .cgt-tool[data-status="breakEven"] .cgt-status {
247
+ color: var(--cgt-gold);
248
+ }
249
+
250
+ .cgt-visual {
251
+ background: linear-gradient(145deg, color-mix(in srgb, var(--cgt-accent-soft) 70%, transparent), transparent 62%), var(--cgt-paper);
252
+ border: 1px solid var(--cgt-edge);
253
+ border-radius: 1rem;
254
+ padding: 1.1rem;
255
+ }
256
+
257
+ .cgt-visual-heading,
258
+ .cgt-visual-bars {
259
+ align-items: center;
260
+ display: grid;
261
+ gap: 1rem;
262
+ grid-template-columns: 1fr auto 1fr;
263
+ }
264
+
265
+ .cgt-visual-heading {
266
+ color: var(--cgt-muted);
267
+ font-size: 0.72rem;
268
+ font-weight: 800;
269
+ grid-template-columns: 1fr 1fr;
270
+ text-align: center;
271
+ }
272
+
273
+ .cgt-visual-bars {
274
+ margin-top: 0.8rem;
275
+ }
276
+
277
+ .cgt-bar-side {
278
+ display: grid;
279
+ gap: 0.45rem;
280
+ min-width: 0;
281
+ }
282
+
283
+ .cgt-bar-side strong {
284
+ font-size: 1.1rem;
285
+ font-variant-numeric: tabular-nums;
286
+ text-align: center;
287
+ }
288
+
289
+ .cgt-bar-track {
290
+ background: var(--cgt-surface);
291
+ border-radius: 99rem;
292
+ height: 0.8rem;
293
+ overflow: hidden;
294
+ }
295
+
296
+ .cgt-bar-track i {
297
+ background: var(--cgt-cool);
298
+ border-radius: inherit;
299
+ display: block;
300
+ height: 100%;
301
+ min-width: 0.35rem;
302
+ transition: width 0.25s ease;
303
+ }
304
+
305
+ .cgt-bar-side:last-child .cgt-bar-track i {
306
+ background: var(--cgt-gold);
307
+ }
308
+
309
+ .cgt-visual-rail {
310
+ color: var(--cgt-accent);
311
+ font-size: 1.5rem;
312
+ font-weight: 900;
313
+ }
314
+
315
+ .cgt-scenarios {
316
+ display: grid;
317
+ gap: 0.9rem;
318
+ grid-template-columns: repeat(2, minmax(0, 1fr));
319
+ }
320
+
321
+ .cgt-scenario {
322
+ border: 1px solid var(--cgt-edge);
323
+ border-radius: 0.9rem;
324
+ padding: 1rem;
325
+ }
326
+
327
+ .cgt-scenario h2 {
328
+ font-size: 0.95rem;
329
+ margin: 0 0 0.8rem;
330
+ }
331
+
332
+ .cgt-scenario dl {
333
+ display: grid;
334
+ gap: 0.42rem;
335
+ margin: 0;
336
+ }
337
+
338
+ .cgt-scenario dl div {
339
+ align-items: baseline;
340
+ border-bottom: 1px solid color-mix(in srgb, var(--cgt-edge) 75%, transparent);
341
+ display: flex;
342
+ gap: 0.6rem;
343
+ justify-content: space-between;
344
+ padding-bottom: 0.4rem;
345
+ }
346
+
347
+ .cgt-scenario dt,
348
+ .cgt-scenario dd {
349
+ font-size: 0.76rem;
350
+ margin: 0;
351
+ }
352
+
353
+ .cgt-scenario dt {
354
+ color: var(--cgt-muted);
355
+ }
356
+
357
+ .cgt-scenario dd {
358
+ font-variant-numeric: tabular-nums;
359
+ font-weight: 750;
360
+ text-align: right;
361
+ }
362
+
363
+ .cgt-scenario .cgt-emphasis {
364
+ border-bottom: 0;
365
+ color: var(--cgt-accent);
366
+ font-size: 1.05rem;
367
+ padding-top: 0.35rem;
368
+ }
369
+
370
+ .cgt-scenario .cgt-emphasis dt,
371
+ .cgt-scenario .cgt-emphasis dd {
372
+ color: inherit;
373
+ font-size: 0.9rem;
374
+ font-weight: 850;
375
+ }
376
+
377
+ .cgt-note,
378
+ .cgt-privacy,
379
+ .cgt-method p {
380
+ color: var(--cgt-muted);
381
+ font-size: 0.74rem;
382
+ line-height: 1.5;
383
+ }
384
+
385
+ .cgt-note {
386
+ margin: 0.8rem 0 0;
387
+ }
388
+
389
+ .cgt-comparison {
390
+ align-items: center;
391
+ background: var(--cgt-surface);
392
+ border: 1px solid var(--cgt-edge);
393
+ border-radius: 0.9rem;
394
+ display: grid;
395
+ gap: 0.25rem 0.8rem;
396
+ grid-template-columns: auto 1fr;
397
+ padding: 0.9rem 1rem;
398
+ }
399
+
400
+ .cgt-comparison span,
401
+ .cgt-comparison small {
402
+ color: var(--cgt-muted);
403
+ font-size: 0.72rem;
404
+ }
405
+
406
+ .cgt-comparison strong {
407
+ color: var(--cgt-accent);
408
+ font-size: 1rem;
409
+ }
410
+
411
+ .cgt-comparison small {
412
+ grid-column: 2;
413
+ }
414
+
415
+ .cgt-error-summary {
416
+ background: var(--cgt-accent-soft);
417
+ border-radius: 0.7rem;
418
+ color: var(--cgt-danger);
419
+ font-size: 0.78rem;
420
+ margin: 0;
421
+ padding: 0.7rem 0.85rem;
422
+ }
423
+
424
+ .cgt-privacy {
425
+ border-top: 1px solid var(--cgt-edge);
426
+ margin: 0;
427
+ padding: 0.9rem 1.35rem;
428
+ }
429
+
430
+ .cgt-method {
431
+ border-top: 1px solid var(--cgt-edge);
432
+ padding: 0.9rem 1.35rem 1.15rem;
433
+ }
434
+
435
+ .cgt-method summary {
436
+ cursor: pointer;
437
+ font-size: 0.8rem;
438
+ font-weight: 800;
439
+ }
440
+
441
+ .cgt-method p:last-child {
442
+ margin-bottom: 0;
443
+ }
444
+
445
+ @media (max-width: 900px) {
446
+ .cgt-inputs {
447
+ grid-template-columns: repeat(2, minmax(0, 1fr));
448
+ }
449
+ }
450
+
451
+ @media (max-width: 620px) {
452
+ .cgt-glance,
453
+ .cgt-inputs,
454
+ .cgt-scenarios {
455
+ grid-template-columns: 1fr;
456
+ }
457
+
458
+ .cgt-glance strong {
459
+ text-align: left;
460
+ }
461
+
462
+ .cgt-visual-bars {
463
+ gap: 0.55rem;
464
+ }
465
+
466
+ .cgt-visual-rail {
467
+ font-size: 1.1rem;
468
+ }
469
+ }