mantenimento-app 2.2.7 → 2.2.9

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
@@ -2800,6 +2800,8 @@ const defaultExpenseItems = [
2800
2800
  sliderBar.style.setProperty("--perm-left", `${p1}%`);
2801
2801
  sliderBar.setAttribute("aria-valuenow", String(p1));
2802
2802
  sliderBar.setAttribute("aria-valuetext", `${p1}% / ${p2}%`);
2803
+ const centerBadge = document.getElementById("permDaysCenter");
2804
+ if (centerBadge) centerBadge.textContent = `${p1}% / ${p2}%`;
2803
2805
  }
2804
2806
 
2805
2807
  // Update days bar below slider.
@@ -3640,6 +3642,8 @@ const defaultExpenseItems = [
3640
3642
  });
3641
3643
  }
3642
3644
  if (splitCenterEl) splitCenterEl.textContent = `${normalizedShare1.toFixed(0)}% / ${share2.toFixed(0)}%`;
3645
+ const splitRangeWrapEl = shareEl.closest(".mortgage-split-range-wrap");
3646
+ if (splitRangeWrapEl) splitRangeWrapEl.style.setProperty("--split-left", `${normalizedShare1.toFixed(0)}%`);
3643
3647
  if (splitLeftNameEl) splitLeftNameEl.textContent = c1n();
3644
3648
  if (splitRightNameEl) splitRightNameEl.textContent = c2n();
3645
3649
  if (splitLeftAmountEl) splitLeftAmountEl.textContent = eur(quota1);
@@ -5000,30 +5004,20 @@ const defaultExpenseItems = [
5000
5004
  </div>`;
5001
5005
  }).join("")}</div>`
5002
5006
  : "";
5003
- const separationSectionHtml = m.speseConvivenza > 0
5004
- ? `
5005
- <div class="section">
5006
- <div class="section-title">${tr("sepCostPanelTitle")}</div>
5007
- <table>
5008
- <tbody>
5009
- <tr><td>${tr("sepCostNetTogether")}</td><td class="num"><strong>${eur(m.nettoInsiemeCombinato || 0)}</strong></td></tr>
5010
- <tr><td>${tr("sepCostNetSeparated")}</td><td class="num"><strong>${eur(m.nettoSeparatoTotale || 0)}</strong></td></tr>
5011
- ${m.separationAdjustmentHousingUtilities > 0 ? `<tr><td>${tr("sepCostHousingUtilityAdj")}</td><td class="num">${eur(m.separationAdjustmentHousingUtilities)}</td></tr>` : ""}
5012
- <tr><td>${tr("sepCostDuplication")}</td><td class="num"><strong>${eur(m.costoSeparazioneMensile || 0)}</strong></td></tr>
5013
- <tr><td>${tr("sepCostLossMonthly")}</td><td class="num"><strong>${eur(m.perditaMensile || 0)}</strong></td></tr>
5014
- <tr><td>${tr("sepCostLossAnnually")}</td><td class="num"><strong>${eur(m.perditaAnnua || 0)}</strong></td></tr>
5015
- <tr><td>${msg("sepCostLossSpouse", { spouse: c1NameEsc })}</td><td class="num">${eur(m.perditaSpouse1 || 0)}</td></tr>
5016
- <tr><td>${msg("sepCostLossSpouse", { spouse: c2NameEsc })}</td><td class="num">${eur(m.perditaSpouse2 || 0)}</td></tr>
5017
- </tbody>
5018
- </table>
5019
- </div>`
5007
+ const liveSepPanelSnapshot = String(document.getElementById("sepCostPanel")?.innerHTML || "").trim();
5008
+ const separationSectionHtml = m.speseConvivenza > 0 && liveSepPanelSnapshot
5009
+ ? `<div class="section pdf-screen-section">${liveSepPanelSnapshot}</div>`
5020
5010
  : "";
5011
+ const activeAppScriptSrc = String(document.querySelector('script[src*="app.js"]')?.getAttribute("src") || "");
5012
+ const appVersionFromScript = (activeAppScriptSrc.match(/[?&]v=([^&#]+)/) || [])[1] || String(Date.now());
5013
+ const pdfStylesHref = `styles.css?v=${encodeURIComponent(appVersionFromScript)}`;
5021
5014
 
5022
5015
  const html = `<!DOCTYPE html>
5023
5016
  <html lang="${pdfLang}">
5024
5017
  <head>
5025
5018
  <meta charset="UTF-8"/>
5026
5019
  <title>${tr("pdfReportTitle")} – ${genDate}</title>
5020
+ <link rel="stylesheet" href="${pdfStylesHref}">
5027
5021
  <style>
5028
5022
  @page { size: A4 portrait; margin: 16mm 14mm 14mm 14mm; }
5029
5023
  * { box-sizing: border-box; margin: 0; padding: 0; }
@@ -5214,6 +5208,14 @@ const defaultExpenseItems = [
5214
5208
  .footer { border-top: 1px solid #cde5e0; padding-top: 6px; margin-top: 20px;
5215
5209
  font-size: 7.5pt; color: #888; text-align: center; }
5216
5210
 
5211
+ /* Keep on-screen section visuals (e.g. separation panel) close to app rendering */
5212
+ .pdf-screen-section { break-inside: avoid; }
5213
+ .pdf-screen-section .sep-cost-panel { margin-top: 0; }
5214
+ .pdf-screen-section .sep-cost-title { margin-bottom: 6px; }
5215
+ .pdf-screen-section .sep-cost-hero,
5216
+ .pdf-screen-section .sep-cost-section--grid,
5217
+ .pdf-screen-section .sep-cost-pill-wrap { gap: 8px; }
5218
+
5217
5219
  @media print {
5218
5220
  body { -webkit-print-color-adjust: exact; print-color-adjust: exact; }
5219
5221
  }
@@ -2800,6 +2800,8 @@ const defaultExpenseItems = [
2800
2800
  sliderBar.style.setProperty("--perm-left", `${p1}%`);
2801
2801
  sliderBar.setAttribute("aria-valuenow", String(p1));
2802
2802
  sliderBar.setAttribute("aria-valuetext", `${p1}% / ${p2}%`);
2803
+ const centerBadge = document.getElementById("permDaysCenter");
2804
+ if (centerBadge) centerBadge.textContent = `${p1}% / ${p2}%`;
2803
2805
  }
2804
2806
 
2805
2807
  // Update days bar below slider.
@@ -3640,6 +3642,8 @@ const defaultExpenseItems = [
3640
3642
  });
3641
3643
  }
3642
3644
  if (splitCenterEl) splitCenterEl.textContent = `${normalizedShare1.toFixed(0)}% / ${share2.toFixed(0)}%`;
3645
+ const splitRangeWrapEl = shareEl.closest(".mortgage-split-range-wrap");
3646
+ if (splitRangeWrapEl) splitRangeWrapEl.style.setProperty("--split-left", `${normalizedShare1.toFixed(0)}%`);
3643
3647
  if (splitLeftNameEl) splitLeftNameEl.textContent = c1n();
3644
3648
  if (splitRightNameEl) splitRightNameEl.textContent = c2n();
3645
3649
  if (splitLeftAmountEl) splitLeftAmountEl.textContent = eur(quota1);
@@ -5000,30 +5004,20 @@ const defaultExpenseItems = [
5000
5004
  </div>`;
5001
5005
  }).join("")}</div>`
5002
5006
  : "";
5003
- const separationSectionHtml = m.speseConvivenza > 0
5004
- ? `
5005
- <div class="section">
5006
- <div class="section-title">${tr("sepCostPanelTitle")}</div>
5007
- <table>
5008
- <tbody>
5009
- <tr><td>${tr("sepCostNetTogether")}</td><td class="num"><strong>${eur(m.nettoInsiemeCombinato || 0)}</strong></td></tr>
5010
- <tr><td>${tr("sepCostNetSeparated")}</td><td class="num"><strong>${eur(m.nettoSeparatoTotale || 0)}</strong></td></tr>
5011
- ${m.separationAdjustmentHousingUtilities > 0 ? `<tr><td>${tr("sepCostHousingUtilityAdj")}</td><td class="num">${eur(m.separationAdjustmentHousingUtilities)}</td></tr>` : ""}
5012
- <tr><td>${tr("sepCostDuplication")}</td><td class="num"><strong>${eur(m.costoSeparazioneMensile || 0)}</strong></td></tr>
5013
- <tr><td>${tr("sepCostLossMonthly")}</td><td class="num"><strong>${eur(m.perditaMensile || 0)}</strong></td></tr>
5014
- <tr><td>${tr("sepCostLossAnnually")}</td><td class="num"><strong>${eur(m.perditaAnnua || 0)}</strong></td></tr>
5015
- <tr><td>${msg("sepCostLossSpouse", { spouse: c1NameEsc })}</td><td class="num">${eur(m.perditaSpouse1 || 0)}</td></tr>
5016
- <tr><td>${msg("sepCostLossSpouse", { spouse: c2NameEsc })}</td><td class="num">${eur(m.perditaSpouse2 || 0)}</td></tr>
5017
- </tbody>
5018
- </table>
5019
- </div>`
5007
+ const liveSepPanelSnapshot = String(document.getElementById("sepCostPanel")?.innerHTML || "").trim();
5008
+ const separationSectionHtml = m.speseConvivenza > 0 && liveSepPanelSnapshot
5009
+ ? `<div class="section pdf-screen-section">${liveSepPanelSnapshot}</div>`
5020
5010
  : "";
5011
+ const activeAppScriptSrc = String(document.querySelector('script[src*="app.js"]')?.getAttribute("src") || "");
5012
+ const appVersionFromScript = (activeAppScriptSrc.match(/[?&]v=([^&#]+)/) || [])[1] || String(Date.now());
5013
+ const pdfStylesHref = `styles.css?v=${encodeURIComponent(appVersionFromScript)}`;
5021
5014
 
5022
5015
  const html = `<!DOCTYPE html>
5023
5016
  <html lang="${pdfLang}">
5024
5017
  <head>
5025
5018
  <meta charset="UTF-8"/>
5026
5019
  <title>${tr("pdfReportTitle")} – ${genDate}</title>
5020
+ <link rel="stylesheet" href="${pdfStylesHref}">
5027
5021
  <style>
5028
5022
  @page { size: A4 portrait; margin: 16mm 14mm 14mm 14mm; }
5029
5023
  * { box-sizing: border-box; margin: 0; padding: 0; }
@@ -5214,6 +5208,14 @@ const defaultExpenseItems = [
5214
5208
  .footer { border-top: 1px solid #cde5e0; padding-top: 6px; margin-top: 20px;
5215
5209
  font-size: 7.5pt; color: #888; text-align: center; }
5216
5210
 
5211
+ /* Keep on-screen section visuals (e.g. separation panel) close to app rendering */
5212
+ .pdf-screen-section { break-inside: avoid; }
5213
+ .pdf-screen-section .sep-cost-panel { margin-top: 0; }
5214
+ .pdf-screen-section .sep-cost-title { margin-bottom: 6px; }
5215
+ .pdf-screen-section .sep-cost-hero,
5216
+ .pdf-screen-section .sep-cost-section--grid,
5217
+ .pdf-screen-section .sep-cost-pill-wrap { gap: 8px; }
5218
+
5217
5219
  @media print {
5218
5220
  body { -webkit-print-color-adjust: exact; print-color-adjust: exact; }
5219
5221
  }
@@ -257,6 +257,7 @@
257
257
  <div class="perm-days-bar" id="permSliderBar" role="slider" tabindex="0" aria-valuemin="0" aria-valuemax="100" aria-valuenow="40" aria-label="Permanenza figli presso Coniuge 1 (%)">
258
258
  <div class="perm-days-half perm-days-half--left" id="permDaysLeft" style="width:40%"><span class="perm-days-chip">12 gg</span></div>
259
259
  <div class="perm-days-half perm-days-half--right" id="permDaysRight" style="width:60%"><span class="perm-days-chip">18 gg</span></div>
260
+ <div class="perm-days-center" id="permDaysCenter">40% / 60%</div>
260
261
  <div class="perm-days-thumb" id="permDaysThumb" aria-hidden="true"></div>
261
262
  </div>
262
263
  <input id="perm2" type="number" min="0" max="100" step="1" value="60" aria-label="Permanenza figli presso Coniuge 2 (%)" />
@@ -599,7 +600,7 @@
599
600
  <script src="supabase.min.js"></script>
600
601
  <script src="fabric.min.js"></script>
601
602
  <script src="html2pdf.bundle.min.js"></script>
602
- <script src="app.js?v=2.2.7"></script>
603
+ <script src="app.js?v=2.2.9"></script>
603
604
  </body>
604
605
  </html>
605
606
 
@@ -571,6 +571,11 @@
571
571
  text-align: center;
572
572
  padding: 8px 6px;
573
573
  font-size: 0.9rem;
574
+ border-radius: 12px;
575
+ border-color: #bfd8d2;
576
+ background: linear-gradient(180deg, #ffffff, #f0f8f6);
577
+ font-weight: 800;
578
+ color: #114c45;
574
579
  }
575
580
 
576
581
  .perm-days-bar {
@@ -579,10 +584,14 @@
579
584
  border-radius: 17px;
580
585
  overflow: hidden;
581
586
  margin-top: 0;
582
- box-shadow: inset 0 1px 3px rgba(0,0,0,0.12), 0 2px 6px rgba(0,0,0,0.12);
587
+ box-shadow: inset 0 1px 2px rgba(12, 61, 56, 0.15), 0 2px 6px rgba(0, 0, 0, 0.1);
583
588
  position: relative;
584
589
  cursor: ew-resize;
585
- border: 1px solid #b8cac5;
590
+ border: 1px solid #b9d6cf;
591
+ background:
592
+ radial-gradient(120% 160% at 0% 0%, rgba(229, 247, 242, 0.8), transparent 58%),
593
+ radial-gradient(120% 160% at 100% 0%, rgba(255, 241, 214, 0.8), transparent 58%),
594
+ linear-gradient(180deg, #fafdfc, #eef7f5);
586
595
  user-select: none;
587
596
  touch-action: none;
588
597
  }
@@ -606,35 +615,59 @@
606
615
  align-items: center;
607
616
  justify-content: center;
608
617
  min-width: 74px;
609
- padding: 3px 10px;
618
+ padding: 2px 10px;
610
619
  border-radius: 999px;
611
- background: rgba(255, 255, 255, 0.78);
612
- border: 1px solid rgba(255, 255, 255, 0.95);
613
- box-shadow: 0 1px 4px rgba(0, 0, 0, 0.16);
620
+ background: rgba(255, 255, 255, 0.86);
621
+ border: 1px solid #c6ded8;
622
+ box-shadow: 0 1px 3px rgba(17, 74, 68, 0.12);
614
623
  line-height: 1;
624
+ font-size: 0.78rem;
625
+ font-weight: 900;
615
626
  }
616
627
 
617
628
  .perm-days-half--left {
618
- background: linear-gradient(90deg, #bfe9df, #6ec0b0);
629
+ background: linear-gradient(90deg, #2b9d8e, #6cb9a9);
630
+ justify-content: flex-start;
631
+ padding-left: 8px;
619
632
  }
620
633
 
621
634
  .perm-days-half--right {
622
- background: linear-gradient(90deg, #f2d8ab, #deaa59);
635
+ background: linear-gradient(90deg, #dfb264, #cb8a2d);
623
636
  color: #5d3d11;
637
+ justify-content: flex-end;
638
+ padding-right: 8px;
639
+ }
640
+
641
+ .perm-days-center {
642
+ position: absolute;
643
+ top: 50%;
644
+ left: 50%;
645
+ transform: translate(-50%, -50%);
646
+ font-size: 0.7rem;
647
+ font-weight: 900;
648
+ color: #114c45;
649
+ background: #ffffff;
650
+ border: 1px solid #b8d5ce;
651
+ border-radius: 999px;
652
+ padding: 1px 7px;
653
+ white-space: nowrap;
654
+ pointer-events: none;
655
+ z-index: 3;
624
656
  }
625
657
 
626
658
  .perm-days-thumb {
627
659
  position: absolute;
628
660
  top: 50%;
629
661
  left: var(--perm-left, 40%);
630
- width: 24px;
631
- height: 24px;
662
+ width: 22px;
663
+ height: 22px;
632
664
  border-radius: 50%;
633
665
  transform: translate(-50%, -50%);
634
- border: 3px solid #ffffff;
635
- background: #0f766d;
636
- box-shadow: 0 2px 8px rgba(0, 0, 0, 0.28);
666
+ border: 2px solid #ffffff;
667
+ background: radial-gradient(circle at 35% 30%, #ffffff 0%, #e8f8f5 42%, #177a6f 100%);
668
+ box-shadow: 0 3px 9px rgba(13, 70, 64, 0.35);
637
669
  pointer-events: none;
670
+ z-index: 4;
638
671
  }
639
672
 
640
673
  .perm-days-bar:focus-visible {
@@ -877,13 +910,14 @@
877
910
 
878
911
  .mortgage-split-side {
879
912
  border: 1px solid #c6ded8;
880
- border-radius: 10px;
881
- padding: 7px;
882
- background: rgba(255, 255, 255, 0.84);
913
+ border-radius: 12px;
914
+ padding: 8px;
915
+ background: linear-gradient(180deg, #ffffff, #f3faf8);
883
916
  min-height: 58px;
884
917
  display: grid;
885
918
  align-content: center;
886
- gap: 2px;
919
+ gap: 3px;
920
+ box-shadow: 0 1px 3px rgba(17, 74, 68, 0.08);
887
921
  }
888
922
 
889
923
  .mortgage-split-side-left {
@@ -912,6 +946,7 @@
912
946
  .mortgage-split-range-wrap {
913
947
  position: relative;
914
948
  padding: 14px 0 6px;
949
+ --split-left: 50%;
915
950
  }
916
951
 
917
952
  .mortgage-split-range-wrap input[type="range"] {
@@ -920,9 +955,14 @@
920
955
  width: 100%;
921
956
  height: 8px;
922
957
  border-radius: 999px;
923
- background: linear-gradient(90deg, #2b9d8e 0%, #6cb9a9 46%, #dfb264 54%, #cb8a2d 100%);
958
+ background: linear-gradient(90deg,
959
+ #2b9d8e 0%,
960
+ #6cb9a9 var(--split-left),
961
+ #dfb264 var(--split-left),
962
+ #cb8a2d 100%);
924
963
  outline: none;
925
964
  margin: 0;
965
+ transition: background 0.16s ease;
926
966
  }
927
967
 
928
968
  .mortgage-split-range-wrap input[type="range"]::-webkit-slider-thumb {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mantenimento-app",
3
- "version": "2.2.7",
3
+ "version": "2.2.9",
4
4
  "description": "Frontend + backend architecture for the mantenimento calculator",
5
5
  "type": "commonjs",
6
6
  "main": "backend/calculate-model.js",