Skip to content

Commit ca3f84f

Browse files
committed
Add trade transit visibility and route upgrades
1 parent c996cc4 commit ca3f84f

8 files changed

Lines changed: 510 additions & 76 deletions

File tree

site/admin/index.html

Lines changed: 25 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,12 @@
1818
})();
1919
</script>
2020
<link rel="icon" href="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 64 64'%3E%3Crect width='64' height='64' rx='10' fill='%2314171a'/%3E%3Cpath d='M8 8h32L8 40z' fill='%23f0c33b'/%3E%3Cpath d='M56 56H24l32-32z' fill='%230d65d9'/%3E%3C/svg%3E">
21-
<link rel="stylesheet" href="../css/base.css?v=20260604-codebase-refactor">
22-
<link rel="stylesheet" href="../css/trade.css?v=20260604-codebase-refactor">
23-
<link rel="stylesheet" href="../css/ledger.css?v=20260604-codebase-refactor">
24-
<link rel="stylesheet" href="../css/simulation.css?v=20260604-codebase-refactor">
25-
<link rel="stylesheet" href="../css/records.css?v=20260604-codebase-refactor">
26-
<link rel="stylesheet" href="../css/responsive.css?v=20260604-codebase-refactor">
21+
<link rel="stylesheet" href="../css/base.css?v=20260604-transit-routes">
22+
<link rel="stylesheet" href="../css/trade.css?v=20260604-transit-routes">
23+
<link rel="stylesheet" href="../css/ledger.css?v=20260604-transit-routes">
24+
<link rel="stylesheet" href="../css/simulation.css?v=20260604-transit-routes">
25+
<link rel="stylesheet" href="../css/records.css?v=20260604-transit-routes">
26+
<link rel="stylesheet" href="../css/responsive.css?v=20260604-transit-routes">
2727
</head>
2828
<body data-app-mode="admin">
2929
<header class="topbar">
@@ -63,24 +63,24 @@ <h1>Global Ledger</h1>
6363
<span id="sourceNote"></span>
6464
</footer>
6565

66-
<script src="../data.js?v=20260604-codebase-refactor"></script>
67-
<script src="../js/engine/fiscal.js?v=20260604-codebase-refactor"></script>
68-
<script src="../js/engine/tradePolicy.js?v=20260604-codebase-refactor"></script>
69-
<script src="../js/engine/trade.js?v=20260604-codebase-refactor"></script>
70-
<script src="../engine.js?v=20260604-codebase-refactor"></script>
71-
<script src="../js/app/config.js?v=20260604-codebase-refactor"></script>
72-
<script src="../js/app/format.js?v=20260604-codebase-refactor"></script>
73-
<script src="../js/app/sync.js?v=20260604-codebase-refactor"></script>
74-
<script src="../js/app/statusTables.js?v=20260604-codebase-refactor"></script>
75-
<script src="../js/app/recordsParser.js?v=20260604-codebase-refactor"></script>
76-
<script src="../js/app/records.js?v=20260604-codebase-refactor"></script>
77-
<script src="../js/app/tradeMapShapes.js?v=20260604-codebase-refactor"></script>
78-
<script src="../js/app/tradeZones.js?v=20260604-codebase-refactor"></script>
79-
<script src="../js/app/tradeRouteMesh.js?v=20260604-codebase-refactor"></script>
80-
<script src="../js/app/tradeLaneSkeleton.js?v=20260604-codebase-refactor"></script>
81-
<script src="../js/app/tradeMap.js?v=20260604-codebase-refactor"></script>
82-
<script src="../js/app/tradeView.js?v=20260604-codebase-refactor"></script>
83-
<script src="../js/app/editorView.js?v=20260604-codebase-refactor"></script>
84-
<script src="../app.js?v=20260604-codebase-refactor"></script>
66+
<script src="../data.js?v=20260604-transit-routes"></script>
67+
<script src="../js/engine/fiscal.js?v=20260604-transit-routes"></script>
68+
<script src="../js/engine/tradePolicy.js?v=20260604-transit-routes"></script>
69+
<script src="../js/engine/trade.js?v=20260604-transit-routes"></script>
70+
<script src="../engine.js?v=20260604-transit-routes"></script>
71+
<script src="../js/app/config.js?v=20260604-transit-routes"></script>
72+
<script src="../js/app/format.js?v=20260604-transit-routes"></script>
73+
<script src="../js/app/sync.js?v=20260604-transit-routes"></script>
74+
<script src="../js/app/statusTables.js?v=20260604-transit-routes"></script>
75+
<script src="../js/app/recordsParser.js?v=20260604-transit-routes"></script>
76+
<script src="../js/app/records.js?v=20260604-transit-routes"></script>
77+
<script src="../js/app/tradeMapShapes.js?v=20260604-transit-routes"></script>
78+
<script src="../js/app/tradeZones.js?v=20260604-transit-routes"></script>
79+
<script src="../js/app/tradeRouteMesh.js?v=20260604-transit-routes"></script>
80+
<script src="../js/app/tradeLaneSkeleton.js?v=20260604-transit-routes"></script>
81+
<script src="../js/app/tradeMap.js?v=20260604-transit-routes"></script>
82+
<script src="../js/app/tradeView.js?v=20260604-transit-routes"></script>
83+
<script src="../js/app/editorView.js?v=20260604-transit-routes"></script>
84+
<script src="../app.js?v=20260604-transit-routes"></script>
8585
</body>
8686
</html>

site/app.js

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1837,6 +1837,27 @@
18371837
Engine.recalculateAll(data);
18381838
saveWorkingState(`${byId(importerId)?.name || "Country"} import lane from ${byId(exporterId)?.name || "partner"} returned to auto.`);
18391839
}
1840+
} else if (action === "set-route-investment") {
1841+
const nationId = actionButton.dataset.nationId || state.selectedNation;
1842+
const portInput = document.getElementById(actionButton.dataset.portInputId || "");
1843+
const corridorInput = document.getElementById(actionButton.dataset.corridorInputId || "");
1844+
if (nationId && portInput && corridorInput) {
1845+
rememberVisibleTableScroll();
1846+
const investment = Engine.setRouteInvestment(data, nationId, {
1847+
portAccess: Engine.number(portInput.value, 0),
1848+
transitCorridor: Engine.number(corridorInput.value, 0)
1849+
});
1850+
Engine.recalculateAll(data);
1851+
saveWorkingState(`${byId(nationId)?.name || "Country"} route upgrades set to port ${fmtNumber(investment.portAccess)} and corridor ${fmtNumber(investment.transitCorridor)}.`);
1852+
}
1853+
} else if (action === "clear-route-investment") {
1854+
const nationId = actionButton.dataset.nationId || state.selectedNation;
1855+
if (nationId) {
1856+
rememberVisibleTableScroll();
1857+
Engine.clearRouteInvestment(data, nationId);
1858+
Engine.recalculateAll(data);
1859+
saveWorkingState(`${byId(nationId)?.name || "Country"} route upgrades cleared.`);
1860+
}
18401861
} else if (action === "advance-one") {
18411862
const result = Engine.advanceToYear(data, Number(data.meta.currentYear) + 1);
18421863
saveWorkingState(result.message);

site/css/trade.css

Lines changed: 182 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -645,6 +645,162 @@
645645
color-mix(in srgb, var(--panel) 84%, transparent);
646646
}
647647

648+
.trade-transit-band,
649+
.route-investment-band {
650+
display: grid;
651+
grid-template-columns: minmax(190px, 0.22fr) minmax(0, 1fr);
652+
gap: 0;
653+
min-width: 0;
654+
border-top: 1px solid var(--line);
655+
background: color-mix(in srgb, var(--panel) 82%, transparent);
656+
}
657+
658+
.trade-transit-title,
659+
.route-investment-title {
660+
display: grid;
661+
align-content: center;
662+
gap: 4px;
663+
min-width: 0;
664+
padding: 12px 16px;
665+
border-right: 1px solid var(--line);
666+
}
667+
668+
.trade-transit-title strong,
669+
.route-investment-title strong {
670+
color: var(--ink);
671+
font-size: 16px;
672+
font-weight: 950;
673+
line-height: 1.1;
674+
overflow-wrap: anywhere;
675+
}
676+
677+
.trade-transit-list {
678+
display: grid;
679+
min-width: 0;
680+
}
681+
682+
.trade-transit-row {
683+
display: grid;
684+
grid-template-columns: minmax(220px, 1fr) minmax(86px, max-content) minmax(210px, 0.7fr);
685+
gap: 14px;
686+
align-items: center;
687+
min-width: 0;
688+
padding: 10px 14px;
689+
border-bottom: 1px solid var(--line);
690+
}
691+
692+
.trade-transit-row > div {
693+
display: grid;
694+
gap: 3px;
695+
min-width: 0;
696+
}
697+
698+
.trade-transit-row strong {
699+
color: var(--ink);
700+
font-size: 13px;
701+
font-weight: 950;
702+
line-height: 1.2;
703+
overflow-wrap: anywhere;
704+
}
705+
706+
.trade-transit-row span,
707+
.trade-transit-empty,
708+
.trade-transit-more {
709+
min-width: 0;
710+
color: var(--muted);
711+
font-size: 11px;
712+
font-weight: 850;
713+
line-height: 1.25;
714+
}
715+
716+
.trade-transit-row > span:first-of-type {
717+
color: var(--ink);
718+
font-size: 13px;
719+
font-weight: 950;
720+
text-align: right;
721+
font-variant-numeric: tabular-nums;
722+
}
723+
724+
.trade-transit-empty,
725+
.trade-transit-more {
726+
padding: 12px 14px;
727+
}
728+
729+
.route-investment-band {
730+
grid-template-columns: minmax(190px, 0.22fr) minmax(260px, 0.34fr) minmax(0, 1fr);
731+
border-bottom: 1px solid var(--line);
732+
background:
733+
linear-gradient(90deg, color-mix(in srgb, var(--nation-color, var(--blue)) 8%, transparent), transparent 44%),
734+
color-mix(in srgb, var(--input-bg) 36%, transparent);
735+
}
736+
737+
.route-investment-readout {
738+
display: grid;
739+
grid-template-columns: repeat(2, minmax(0, 1fr));
740+
min-width: 0;
741+
border-right: 1px solid var(--line);
742+
}
743+
744+
.route-investment-readout div {
745+
display: grid;
746+
align-content: center;
747+
gap: 4px;
748+
min-width: 0;
749+
min-height: 58px;
750+
padding: 10px 14px;
751+
border-right: 1px solid var(--line);
752+
}
753+
754+
.route-investment-readout div:last-child {
755+
border-right: 0;
756+
}
757+
758+
.route-investment-readout span,
759+
.route-investment-controls span {
760+
color: var(--muted);
761+
font-size: 10px;
762+
font-weight: 900;
763+
line-height: 1;
764+
text-transform: uppercase;
765+
}
766+
767+
.route-investment-readout strong {
768+
color: var(--ink);
769+
font-size: 15px;
770+
font-weight: 950;
771+
}
772+
773+
.route-investment-controls {
774+
display: flex;
775+
flex-wrap: wrap;
776+
gap: 8px;
777+
align-items: end;
778+
justify-content: flex-end;
779+
min-width: 0;
780+
padding: 10px 16px;
781+
}
782+
783+
.route-investment-controls label {
784+
display: grid;
785+
gap: 5px;
786+
flex: 1 1 140px;
787+
max-width: 180px;
788+
min-width: 120px;
789+
}
790+
791+
.route-investment-controls input {
792+
min-width: 0;
793+
width: 100%;
794+
min-height: 34px;
795+
border: 1px solid var(--line-strong);
796+
border-radius: 6px;
797+
padding: 6px 8px;
798+
background: var(--input-bg);
799+
color: var(--ink);
800+
font: inherit;
801+
font-weight: 850;
802+
}
803+
648804
.trade-generator-title,
649805
.trade-generator-field,
650806
.trade-generator-share {
@@ -949,10 +1105,36 @@
9491105
}
9501106

9511107
.trade-generator-band,
1108+
.trade-transit-band,
1109+
.route-investment-band,
9521110
.trade-generator-preview {
9531111
grid-template-columns: 1fr;
9541112
}
9551113

1114+
.trade-transit-title,
1115+
.route-investment-title {
1116+
border-right: 0;
1117+
border-bottom: 1px solid var(--line);
1118+
}
1119+
1120+
.trade-transit-row {
1121+
grid-template-columns: minmax(0, 1fr);
1122+
gap: 5px;
1123+
}
1124+
1125+
.trade-transit-row > span:first-of-type {
1126+
text-align: left;
1127+
}
1128+
1129+
.route-investment-readout {
1130+
border-right: 0;
1131+
border-bottom: 1px solid var(--line);
1132+
}
1133+
1134+
.route-investment-controls {
1135+
justify-content: flex-start;
1136+
}
1137+
9561138
.trade-generator-preview-head {
9571139
border-right: 0;
9581140
border-bottom: 1px solid var(--line);

site/engine.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -784,6 +784,9 @@
784784
clearLanePolicy,
785785
setTransitPolicy,
786786
clearTransitPolicy,
787+
routeInvestmentFor,
788+
setRouteInvestment,
789+
clearRouteInvestment,
787790
recalculateTrade,
788791
tradeTierForFlow
789792
} = tradeFactory({
@@ -928,6 +931,9 @@
928931
clearLanePolicy,
929932
setTransitPolicy,
930933
clearTransitPolicy,
934+
routeInvestmentFor,
935+
setRouteInvestment,
936+
clearRouteInvestment,
931937
tradeTierForFlow,
932938
fiscalModelForNation,
933939
calculateTaxBurdenForNation,

site/index.html

Lines changed: 25 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -28,12 +28,12 @@
2828
})();
2929
</script>
3030
<link rel="icon" href="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 64 64'%3E%3Crect width='64' height='64' rx='10' fill='%2314171a'/%3E%3Cpath d='M8 8h32L8 40z' fill='%23f0c33b'/%3E%3Cpath d='M56 56H24l32-32z' fill='%230d65d9'/%3E%3C/svg%3E">
31-
<link rel="stylesheet" href="css/base.css?v=20260604-codebase-refactor">
32-
<link rel="stylesheet" href="css/trade.css?v=20260604-codebase-refactor">
33-
<link rel="stylesheet" href="css/ledger.css?v=20260604-codebase-refactor">
34-
<link rel="stylesheet" href="css/simulation.css?v=20260604-codebase-refactor">
35-
<link rel="stylesheet" href="css/records.css?v=20260604-codebase-refactor">
36-
<link rel="stylesheet" href="css/responsive.css?v=20260604-codebase-refactor">
31+
<link rel="stylesheet" href="css/base.css?v=20260604-transit-routes">
32+
<link rel="stylesheet" href="css/trade.css?v=20260604-transit-routes">
33+
<link rel="stylesheet" href="css/ledger.css?v=20260604-transit-routes">
34+
<link rel="stylesheet" href="css/simulation.css?v=20260604-transit-routes">
35+
<link rel="stylesheet" href="css/records.css?v=20260604-transit-routes">
36+
<link rel="stylesheet" href="css/responsive.css?v=20260604-transit-routes">
3737
</head>
3838
<body data-app-mode="public">
3939
<header class="topbar">
@@ -75,24 +75,24 @@ <h1>Global Ledger</h1>
7575
</span>
7676
</footer>
7777

78-
<script src="data.js?v=20260604-codebase-refactor"></script>
79-
<script src="js/engine/fiscal.js?v=20260604-codebase-refactor"></script>
80-
<script src="js/engine/tradePolicy.js?v=20260604-codebase-refactor"></script>
81-
<script src="js/engine/trade.js?v=20260604-codebase-refactor"></script>
82-
<script src="engine.js?v=20260604-codebase-refactor"></script>
83-
<script src="js/app/config.js?v=20260604-codebase-refactor"></script>
84-
<script src="js/app/format.js?v=20260604-codebase-refactor"></script>
85-
<script src="js/app/sync.js?v=20260604-codebase-refactor"></script>
86-
<script src="js/app/statusTables.js?v=20260604-codebase-refactor"></script>
87-
<script src="js/app/recordsParser.js?v=20260604-codebase-refactor"></script>
88-
<script src="js/app/records.js?v=20260604-codebase-refactor"></script>
89-
<script src="js/app/tradeMapShapes.js?v=20260604-codebase-refactor"></script>
90-
<script src="js/app/tradeZones.js?v=20260604-codebase-refactor"></script>
91-
<script src="js/app/tradeRouteMesh.js?v=20260604-codebase-refactor"></script>
92-
<script src="js/app/tradeLaneSkeleton.js?v=20260604-codebase-refactor"></script>
93-
<script src="js/app/tradeMap.js?v=20260604-codebase-refactor"></script>
94-
<script src="js/app/tradeView.js?v=20260604-codebase-refactor"></script>
95-
<script src="js/app/editorView.js?v=20260604-codebase-refactor"></script>
96-
<script src="app.js?v=20260604-codebase-refactor"></script>
78+
<script src="data.js?v=20260604-transit-routes"></script>
79+
<script src="js/engine/fiscal.js?v=20260604-transit-routes"></script>
80+
<script src="js/engine/tradePolicy.js?v=20260604-transit-routes"></script>
81+
<script src="js/engine/trade.js?v=20260604-transit-routes"></script>
82+
<script src="engine.js?v=20260604-transit-routes"></script>
83+
<script src="js/app/config.js?v=20260604-transit-routes"></script>
84+
<script src="js/app/format.js?v=20260604-transit-routes"></script>
85+
<script src="js/app/sync.js?v=20260604-transit-routes"></script>
86+
<script src="js/app/statusTables.js?v=20260604-transit-routes"></script>
87+
<script src="js/app/recordsParser.js?v=20260604-transit-routes"></script>
88+
<script src="js/app/records.js?v=20260604-transit-routes"></script>
89+
<script src="js/app/tradeMapShapes.js?v=20260604-transit-routes"></script>
90+
<script src="js/app/tradeZones.js?v=20260604-transit-routes"></script>
91+
<script src="js/app/tradeRouteMesh.js?v=20260604-transit-routes"></script>
92+
<script src="js/app/tradeLaneSkeleton.js?v=20260604-transit-routes"></script>
93+
<script src="js/app/tradeMap.js?v=20260604-transit-routes"></script>
94+
<script src="js/app/tradeView.js?v=20260604-transit-routes"></script>
95+
<script src="js/app/editorView.js?v=20260604-transit-routes"></script>
96+
<script src="app.js?v=20260604-transit-routes"></script>
9797
</body>
9898
</html>

site/js/app/config.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,9 @@
3535
"clear-import-anchor",
3636
"preview-trade-generator",
3737
"apply-trade-generator",
38-
"clear-trade-generator-preview"
38+
"clear-trade-generator-preview",
39+
"set-route-investment",
40+
"clear-route-investment"
3941
],
4042
datasets: [
4143
{ key: "national", label: "National" },

0 commit comments

Comments
 (0)