mantenimento-app 2.4.6 → 2.4.8

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.
package/app.js CHANGED
@@ -4918,8 +4918,10 @@ const defaultExpenseItems = [
4918
4918
  [tr("pdfAmountPerChild"), eur((Math.max(m.assegnoDa1a2, m.assegnoDa2a1)) / m.figli), "warn"]
4919
4919
  ];
4920
4920
 
4921
- if (benefitsInline) {
4922
- items.push([tr("calcCompBenefitsLabel"), benefitsInline, "warn"]);
4921
+ const kpiBenefitLines = getCompensativeBenefitRows(m, c1n(), c2n())
4922
+ .map((row) => `${escapeHtml(row.label)}: ${eur(row.amount)}`);
4923
+ if (kpiBenefitLines.length) {
4924
+ items.push([tr("calcCompBenefitsLabel"), kpiBenefitLines.join("<br />"), "warn", true]);
4923
4925
  }
4924
4926
 
4925
4927
  if (m.incomeMode === "cu") {
@@ -4932,13 +4934,20 @@ const defaultExpenseItems = [
4932
4934
  );
4933
4935
  }
4934
4936
 
4935
- items.forEach(([label, value, cls]) => {
4937
+ items.forEach(([label, value, cls, isHtml = false]) => {
4936
4938
  const el = document.createElement("div");
4937
4939
  el.className = "kpi-item";
4938
- if (label === tr("calcCompBenefitsLabel")) {
4940
+ const isBenefitsRow = label === tr("calcCompBenefitsLabel");
4941
+ if (isBenefitsRow) {
4939
4942
  el.classList.add("kpi-item--longtext");
4940
4943
  }
4941
- el.innerHTML = `<span>${label}</span><strong class="${cls}">${value}</strong>`;
4944
+ const safeLabel = escapeHtml(String(label || ""));
4945
+ const safeValue = isHtml ? String(value || "") : escapeHtml(String(value || ""));
4946
+ if (isBenefitsRow) {
4947
+ el.innerHTML = `<span>${safeLabel}</span><p class="kpi-longtext-value ${cls}">${safeValue}</p>`;
4948
+ } else {
4949
+ el.innerHTML = `<span>${safeLabel}</span><strong class="${cls}">${safeValue}</strong>`;
4950
+ }
4942
4951
  kpi.appendChild(el);
4943
4952
  });
4944
4953
  }
@@ -4918,8 +4918,10 @@ const defaultExpenseItems = [
4918
4918
  [tr("pdfAmountPerChild"), eur((Math.max(m.assegnoDa1a2, m.assegnoDa2a1)) / m.figli), "warn"]
4919
4919
  ];
4920
4920
 
4921
- if (benefitsInline) {
4922
- items.push([tr("calcCompBenefitsLabel"), benefitsInline, "warn"]);
4921
+ const kpiBenefitLines = getCompensativeBenefitRows(m, c1n(), c2n())
4922
+ .map((row) => `${escapeHtml(row.label)}: ${eur(row.amount)}`);
4923
+ if (kpiBenefitLines.length) {
4924
+ items.push([tr("calcCompBenefitsLabel"), kpiBenefitLines.join("<br />"), "warn", true]);
4923
4925
  }
4924
4926
 
4925
4927
  if (m.incomeMode === "cu") {
@@ -4932,13 +4934,20 @@ const defaultExpenseItems = [
4932
4934
  );
4933
4935
  }
4934
4936
 
4935
- items.forEach(([label, value, cls]) => {
4937
+ items.forEach(([label, value, cls, isHtml = false]) => {
4936
4938
  const el = document.createElement("div");
4937
4939
  el.className = "kpi-item";
4938
- if (label === tr("calcCompBenefitsLabel")) {
4940
+ const isBenefitsRow = label === tr("calcCompBenefitsLabel");
4941
+ if (isBenefitsRow) {
4939
4942
  el.classList.add("kpi-item--longtext");
4940
4943
  }
4941
- el.innerHTML = `<span>${label}</span><strong class="${cls}">${value}</strong>`;
4944
+ const safeLabel = escapeHtml(String(label || ""));
4945
+ const safeValue = isHtml ? String(value || "") : escapeHtml(String(value || ""));
4946
+ if (isBenefitsRow) {
4947
+ el.innerHTML = `<span>${safeLabel}</span><p class="kpi-longtext-value ${cls}">${safeValue}</p>`;
4948
+ } else {
4949
+ el.innerHTML = `<span>${safeLabel}</span><strong class="${cls}">${safeValue}</strong>`;
4950
+ }
4942
4951
  kpi.appendChild(el);
4943
4952
  });
4944
4953
  }
@@ -88,7 +88,7 @@
88
88
  ]
89
89
  }
90
90
  </script>
91
- <link rel="stylesheet" href="styles.css?v=2.4.6" />
91
+ <link rel="stylesheet" href="styles.css?v=2.4.8" />
92
92
  </head>
93
93
  <body>
94
94
  <div class="wrap">
@@ -630,7 +630,7 @@
630
630
  <script src="supabase.min.js"></script>
631
631
  <script src="fabric.min.js"></script>
632
632
  <script src="html2pdf.bundle.min.js"></script>
633
- <script src="app.js?v=2.4.6"></script>
633
+ <script src="app.js?v=2.4.8"></script>
634
634
  </body>
635
635
  </html>
636
636
 
@@ -1000,7 +1000,7 @@
1000
1000
  linear-gradient(180deg, #fafffe, #f2f8f7);
1001
1001
  padding: 14px;
1002
1002
  display: grid;
1003
- grid-template-columns: minmax(0, 1fr) minmax(180px, 2fr) minmax(0, 1fr);
1003
+ grid-template-columns: minmax(170px, 0.9fr) minmax(380px, 2.9fr) minmax(170px, 0.9fr);
1004
1004
  gap: 10px;
1005
1005
  align-items: center;
1006
1006
  box-shadow: 0 10px 18px rgba(27, 141, 127, 0.12), inset 0 1px 0 rgba(255, 255, 255, 0.65);
@@ -1036,10 +1036,12 @@
1036
1036
  border-radius: 14px;
1037
1037
  padding: 12px;
1038
1038
  background: linear-gradient(135deg, #ffffff 0%, #f5fbf9 100%);
1039
- min-height: 62px;
1039
+ min-height: 74px;
1040
1040
  display: grid;
1041
1041
  align-content: center;
1042
+ justify-items: center;
1042
1043
  gap: 4px;
1044
+ text-align: center;
1043
1045
  box-shadow: 0 2px 6px rgba(27, 141, 127, 0.08), inset 0 1px 2px rgba(255, 255, 255, 0.7);
1044
1046
  transition: all 0.28s cubic-bezier(0.34, 1.56, 0.64, 1);
1045
1047
  position: relative;
@@ -1081,7 +1083,7 @@
1081
1083
 
1082
1084
  .mortgage-split-side-right {
1083
1085
  box-shadow: 0 2px 6px rgba(27, 141, 127, 0.08), inset 0 1px 2px rgba(255, 255, 255, 0.7), inset -3px 0 0 #d89a35;
1084
- text-align: right;
1086
+ text-align: center;
1085
1087
  background: linear-gradient(135deg, #fef9f1 0%, #fdf5e8 100%);
1086
1088
  }
1087
1089
 
@@ -1091,16 +1093,17 @@
1091
1093
  }
1092
1094
 
1093
1095
  .mortgage-split-name {
1094
- font-size: 0.73rem;
1096
+ font-size: 0.92rem;
1095
1097
  font-weight: 800;
1096
1098
  color: #1a3a36;
1097
1099
  overflow-wrap: anywhere;
1098
- letter-spacing: 0.3px;
1100
+ letter-spacing: 0.2px;
1099
1101
  text-shadow: 0 1px 2px rgba(255, 255, 255, 0.5);
1102
+ text-align: center;
1100
1103
  }
1101
1104
 
1102
1105
  .mortgage-split-amount {
1103
- font-size: 0.95rem;
1106
+ font-size: 1.28rem;
1104
1107
  font-weight: 900;
1105
1108
  color: #0b4440;
1106
1109
  letter-spacing: 0.3px;
@@ -1109,6 +1112,7 @@
1109
1112
  -webkit-text-fill-color: transparent;
1110
1113
  background-clip: text;
1111
1114
  filter: drop-shadow(0 1px 2px rgba(27, 141, 127, 0.2));
1115
+ text-align: center;
1112
1116
  }
1113
1117
 
1114
1118
  .mortgage-split-side-right .mortgage-split-amount {
@@ -1120,36 +1124,40 @@
1120
1124
 
1121
1125
  .mortgage-split-range-wrap {
1122
1126
  position: relative;
1123
- padding: 20px 0 8px;
1127
+ padding: 30px 0 8px;
1124
1128
  --split-left: 50%;
1125
1129
  }
1126
1130
 
1127
1131
  .mortgage-split-range-controls {
1128
1132
  display: grid;
1129
- grid-template-columns: 34px minmax(0, 1fr) 34px;
1130
- gap: 7px;
1133
+ grid-template-columns: 42px minmax(0, 1fr) 42px;
1134
+ gap: 8px;
1131
1135
  align-items: center;
1132
1136
  }
1133
1137
 
1134
1138
  .mortgage-split-nudge {
1135
- height: 32px;
1136
- width: 32px;
1139
+ height: 38px;
1140
+ width: 38px;
1141
+ padding: 0;
1142
+ display: inline-flex;
1143
+ align-items: center;
1144
+ justify-content: center;
1137
1145
  border-radius: 50%;
1138
- border: 1.5px solid rgba(27, 141, 127, 0.24);
1139
- background: linear-gradient(180deg, #ffffff, #edf8f5);
1140
- color: #11655b;
1141
- font-size: 13px;
1146
+ border: 1.5px solid rgba(27, 141, 127, 0.3);
1147
+ background: radial-gradient(circle at 30% 30%, #ffffff 0%, #ecfaf6 44%, #dff4ef 100%);
1148
+ color: #0f6056;
1149
+ font-size: 17px;
1142
1150
  font-weight: 900;
1143
1151
  line-height: 1;
1144
1152
  cursor: pointer;
1145
- box-shadow: 0 2px 8px rgba(17, 93, 84, 0.18), inset 0 1px 0 rgba(255, 255, 255, 0.85);
1153
+ box-shadow: 0 4px 10px rgba(17, 93, 84, 0.2), inset 0 1px 0 rgba(255, 255, 255, 0.9);
1146
1154
  transition: transform 0.18s ease, box-shadow 0.18s ease, border-color 0.18s ease;
1147
1155
  }
1148
1156
 
1149
1157
  .mortgage-split-nudge:hover {
1150
- transform: translateY(-1px) scale(1.04);
1151
- border-color: rgba(27, 141, 127, 0.38);
1152
- box-shadow: 0 4px 12px rgba(17, 93, 84, 0.22), inset 0 1px 0 rgba(255, 255, 255, 0.9);
1158
+ transform: translateY(-1px) scale(1.06);
1159
+ border-color: rgba(27, 141, 127, 0.44);
1160
+ box-shadow: 0 7px 16px rgba(17, 93, 84, 0.24), inset 0 1px 0 rgba(255, 255, 255, 0.92);
1153
1161
  }
1154
1162
 
1155
1163
  .mortgage-split-nudge:active {
@@ -1227,21 +1235,23 @@
1227
1235
 
1228
1236
  .mortgage-split-center {
1229
1237
  position: absolute;
1230
- top: 2px;
1238
+ top: -14px;
1231
1239
  left: var(--split-left);
1232
1240
  transform: translateX(-50%);
1233
- font-size: 0.73rem;
1241
+ font-size: 0.92rem;
1234
1242
  font-weight: 900;
1235
1243
  color: #0f544d;
1236
1244
  background: linear-gradient(135deg, #ffffff, #f5fbf9);
1237
1245
  border: 1.5px solid rgba(27, 141, 127, 0.2);
1238
1246
  border-radius: 999px;
1239
- padding: 2px 9px;
1247
+ padding: 4px 11px;
1240
1248
  white-space: nowrap;
1241
1249
  box-shadow: 0 2px 6px rgba(27, 141, 127, 0.15), inset 0 1px 2px rgba(255, 255, 255, 0.6);
1242
1250
  transition: all 0.2s ease;
1243
1251
  letter-spacing: 0.2px;
1244
1252
  animation: split-center-breathe 2.6s ease-in-out infinite;
1253
+ z-index: 3;
1254
+ pointer-events: none;
1245
1255
  }
1246
1256
 
1247
1257
  @keyframes first-home-aurora {
@@ -1256,17 +1266,23 @@
1256
1266
 
1257
1267
  #primaCasaMutuoSplitInfo {
1258
1268
  margin-top: 7px;
1259
- font-size: 0.79rem;
1269
+ font-size: 0.95rem;
1260
1270
  font-weight: 700;
1261
1271
  color: #174e47;
1262
1272
  background: linear-gradient(90deg, rgba(22, 163, 150, 0.12), rgba(216, 154, 53, 0.12));
1263
1273
  border: 1px solid rgba(22, 163, 150, 0.14);
1264
1274
  border-radius: 999px;
1265
- padding: 4px 10px;
1275
+ padding: 7px 12px;
1266
1276
  display: inline-flex;
1267
1277
  align-items: center;
1268
1278
  gap: 4px;
1269
1279
  }
1280
+
1281
+ .first-home-split-field > .label-row {
1282
+ font-size: 1.1rem;
1283
+ font-weight: 800;
1284
+ color: #114b44;
1285
+ }
1270
1286
 
1271
1287
  .label-row {
1272
1288
  display: inline-flex;
@@ -2542,19 +2558,33 @@
2542
2558
  }
2543
2559
 
2544
2560
  .kpi-item--longtext {
2561
+ flex-direction: column;
2545
2562
  align-items: flex-start;
2563
+ gap: 5px;
2546
2564
  }
2547
2565
 
2548
- .kpi-item--longtext strong {
2566
+ .kpi-item--longtext span {
2567
+ width: 100%;
2568
+ flex: none;
2569
+ }
2570
+
2571
+ .kpi-longtext-value {
2572
+ margin: 0;
2573
+ width: 100%;
2549
2574
  white-space: normal;
2550
2575
  text-align: left;
2551
- font-size: 0.88rem;
2552
- line-height: 1.32;
2576
+ font-size: 0.95rem;
2577
+ font-weight: 700;
2578
+ line-height: 1.42;
2553
2579
  overflow-wrap: anywhere;
2554
2580
  word-break: break-word;
2555
- flex: 1;
2581
+ color: #9a5a00;
2556
2582
  }
2557
2583
 
2584
+ .kpi-longtext-value.ok { color: #0c6c52; }
2585
+ .kpi-longtext-value.warn { color: #9a5a00; }
2586
+ .kpi-longtext-value.bad { color: #b53c2f; }
2587
+
2558
2588
  .spieg-details {
2559
2589
  border: 1px solid #bed9d4;
2560
2590
  border-radius: 12px;
@@ -2743,7 +2773,7 @@
2743
2773
  padding: 7px;
2744
2774
  }
2745
2775
 
2746
- .kpi-item strong { font-size: 1.05rem; font-weight: 700; white-space: nowrap; }
2776
+ .kpi-item:not(.kpi-item--longtext) strong { font-size: 1.05rem; font-weight: 700; white-space: nowrap; }
2747
2777
 
2748
2778
  .result-pill {
2749
2779
  border-radius: 14px;
@@ -3539,13 +3569,13 @@
3539
3569
  }
3540
3570
 
3541
3571
  .mortgage-split-range-controls {
3542
- grid-template-columns: 30px minmax(0, 1fr) 30px;
3572
+ grid-template-columns: 34px minmax(0, 1fr) 34px;
3543
3573
  }
3544
3574
 
3545
3575
  .mortgage-split-nudge {
3546
- height: 28px;
3547
- width: 28px;
3548
- font-size: 12px;
3576
+ height: 32px;
3577
+ width: 32px;
3578
+ font-size: 14px;
3549
3579
  }
3550
3580
  .spieg-grid {
3551
3581
  grid-template-columns: 1fr;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mantenimento-app",
3
- "version": "2.4.6",
3
+ "version": "2.4.8",
4
4
  "description": "Frontend + backend architecture for the mantenimento calculator",
5
5
  "type": "commonjs",
6
6
  "main": "backend/calculate-model.js",