Added roads, regional taxation and a reworked budget view

Roads are pre-generated between cities with a greedy geometric spanner and flatten unit movement cost. City improvements now only affect the tiles their region controls, with per-region tax collection and a Cities tab. The budget is a grouped, scrollable table with 25%/year tax and a 10%-of-GDP opening treasury. Also merged the tile info into the city panel, kept conflict and budget expansion state across snapshots, added join notifications, filled border corners, drew battle sides as stacks and made tab overflow scroll.
This commit is contained in:
2026-09-18 07:11:59 +02:00
parent da1d443807
commit 3acd2487df
34 changed files with 1236 additions and 185 deletions
+64 -1
View File
@@ -198,6 +198,24 @@ input:focus, select:focus { border-color: var(--accent); }
pointer-events: none;
}
/* Rounds off the junction where two border edges meet, so the outline has no
notches at the corners. */
.border-corner {
position: absolute;
border-radius: 50%;
pointer-events: none;
}
/* A single pre-generated road link, running from tile centre to tile centre. */
.road-seg {
position: absolute;
background: #8a5a2b;
border-radius: 2px;
box-shadow: 0 0 1px rgba(0, 0, 0, 0.6);
transform-origin: 0 50%;
pointer-events: none;
}
.tile-selection {
position: absolute;
width: var(--hex-w);
@@ -597,7 +615,12 @@ input:focus, select:focus { border-color: var(--accent); }
}
.tab.active { background: rgba(110, 175, 255, 0.22); color: var(--text); }
.tab-page { display: none; }
.tab-page.active { display: block; }
/* The active tab fills the rest of the card and lets its body scroll: without
min-height: 0 the flex item would grow past the card and be clipped by the
card's overflow: hidden, hiding e.g. long diplomacy tables. */
.tab-page.active { display: flex; flex-direction: column; flex: 1 1 auto; min-height: 0; }
.tab-page.active > .modal-sub { flex: 0 0 auto; }
.tab-page.active > .modal-body { flex: 1 1 auto; min-height: 0; }
.row-card {
display: flex;
@@ -664,6 +687,46 @@ input:focus, select:focus { border-color: var(--accent); }
.diplomacy-table td.status { white-space: nowrap; }
.diplomacy-table td.status .aero { margin-left: 8px; padding: 4px 10px; }
/* Budget table: income green, every cost red, alternating rows and the net
total pinned to the last row. */
.budget-table { width: 100%; border-collapse: collapse; }
.budget-table th,
.budget-table td {
padding: 7px 10px;
border-bottom: 1px solid rgba(255, 255, 255, 0.06);
text-align: left;
}
.budget-table th { color: var(--muted); font-weight: 600; }
.budget-table td.numeric,
.budget-table th.numeric { text-align: right; }
.budget-table tbody tr:nth-child(even) { background: rgba(255, 255, 255, 0.045); }
.budget-table tbody tr:hover { background: rgba(110, 175, 255, 0.12); }
.budget-table .budget-value,
.budget-table td.numeric { text-align: right; font-variant-numeric: tabular-nums; }
.budget-table tr.income .budget-value,
.budget-table tr.income-detail .budget-value,
.budget-table td.income { color: #8fe3a8; }
.budget-table tr.budget-group .budget-value,
.budget-table tr.expense .budget-value,
.budget-table tr.expense-detail .budget-value { color: #ff9a9a; }
.budget-table tr.budget-section td {
padding-top: 14px;
color: var(--muted);
font-size: 11px;
letter-spacing: 0.08em;
text-transform: uppercase;
}
.budget-table tr.budget-group .budget-name.clickable { cursor: pointer; }
.budget-table tr.budget-group .budget-name.clickable:hover { color: var(--accent); }
.budget-caret { display: inline-block; width: 12px; color: var(--muted); }
.budget-note { margin-top: 2px; color: var(--muted); font-size: 11px; }
.budget-table tfoot .budget-total td {
padding-top: 10px;
border-top: 2px solid rgba(255, 255, 255, 0.25);
font-weight: 700;
}
.budget-table tfoot .budget-total .budget-value { color: #fff; }
.training-status { padding: 0 18px 16px; }
.training-queue { padding-top: 0; }
.training-queue .queue-empty { padding: 4px 0; }