diff --git a/CHANGELOG.md b/CHANGELOG.md index d8b3928..094f2c8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -25,6 +25,12 @@ How to use this file: months, charts and totals, and keeps the tab shown. A month is still compared with the one before it in the year before. +### Changed + +- On a wide screen the month takes two columns, what it is beside where the + gross pay went, and the glossary two; the charts over time keep a size at + which their text reads well, and the web app widens with the report. + ## [0.9.0] - 2026-10-22 ### Added diff --git a/internal/report/report.html.tmpl b/internal/report/report.html.tmpl index 9f2ec51..7660899 100644 --- a/internal/report/report.html.tmpl +++ b/internal/report/report.html.tmpl @@ -215,8 +215,8 @@ td.num, th.num { text-align: right; font-variant-numeric: tabular-nums; white-sp .status.inconsistent::before { content: "!"; } .changes { margin: 0; padding-left: 20px; } .changes > li { padding: 4px 0; } -.changes .why, .month > .why { color: var(--ink-2); font-size: 14px; } -.month > .why { margin: 4px 0 0; max-width: 40em; } +.changes .why, .m-head > .why { color: var(--ink-2); font-size: 14px; } +.m-head > .why { margin: 4px 0 0; max-width: 40em; } .more-changes { margin-top: 4px; } .more-changes > summary { font-size: 14px; color: var(--series-1); } .contract-note { margin-top: 12px; } @@ -228,6 +228,18 @@ footer { margin-top: 32px; font-size: 13px; color: var(--muted); } .embedded .who .sub, .embedded .who .person { margin-top: 0; } .embedded main { padding-top: 8px; padding-bottom: 8px; } .chart.narrow { display: none; } +/* A wide screen holds the month in two columns, what it is beside where + it went, and the glossary in two. */ +@media (min-width: 1000px) { + main { max-width: 1120px; } + section.month:not([hidden]) { display: grid; grid-template-columns: minmax(0, 5fr) minmax(0, 6fr); column-gap: 56px; align-items: start; } + .m-body > h2:first-child { margin-top: 8px; } + /* Charts keep a size where their text reads as on paper. */ + #panel-time > section, #panel-accrued > section { max-width: 860px; } + .glossary { columns: 2; column-gap: 56px; } + .glossary dt { break-after: avoid; } + .glossary dd { break-inside: avoid; } +} @media (max-width: 520px) { .chart.wide { display: none; } .chart.narrow { display: block; } @@ -637,6 +649,7 @@ footer { margin-top: 32px; font-size: 13px; color: var(--muted); } {{range $i, $m := .Months}}
+

{{$m.Label}} {{$m.StatusText}}{{if gt (len $.Months) 1}}{{end}}

{{index $.T "report.net"}}{{$m.Net}}

{{if $m.Gross}}

{{$m.Gross}}

{{end}} @@ -656,7 +669,9 @@ footer { margin-top: 32px; font-size: 13px; color: var(--muted); } {{end}} {{end}} {{end}} +
+
{{if $m.Parts}}

{{index $.T "report.where"}}

{{if $m.Earnings}}
@@ -700,6 +715,7 @@ footer { margin-top: 32px; font-size: 13px; color: var(--muted); }
{{end}}
{{end}} +
{{end}} diff --git a/web/style.css b/web/style.css index a40ad57..d05e03b 100644 --- a/web/style.css +++ b/web/style.css @@ -45,6 +45,8 @@ body { font: 16px/1.5 system-ui, -apple-system, "Segoe UI", Roboto, sans-serif; } .wrap { max-width: 760px; margin: 0 auto; padding: 0 16px; } +/* The report takes two columns on a wide screen: the page widens with it. */ +@media (min-width: 1000px) { .wrap { max-width: 1120px; } } svg { flex: none; } :focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; } .bar { position: sticky; top: 0; z-index: 2; border-bottom: 1px solid var(--line); background: color-mix(in srgb, var(--surface) 88%, transparent); backdrop-filter: saturate(1.4) blur(8px); -webkit-backdrop-filter: saturate(1.4) blur(8px); } diff --git a/web/test/e2e.test.mjs b/web/test/e2e.test.mjs index bee5f71..369b4d6 100644 --- a/web/test/e2e.test.mjs +++ b/web/test/e2e.test.mjs @@ -113,7 +113,9 @@ test('reads payslips in every style and rotation and shows the report', async () ]); const frame = page.frames().find((f) => f !== page.mainFrame()); await frame.waitForSelector('section.month:not([hidden]) .bar'); - await page.waitForFunction(() => parseInt(document.getElementById('report').style.height, 10) > 600); + // The frame grows to its content: shorter on this wide window, where + // the month takes two columns. + await page.waitForFunction(() => parseInt(document.getElementById('report').style.height, 10) > 400); // One payslip at a time: the picker switches, and a segment of the bar // opens its explanation. const shown = () => frame.$$eval('section.month', (ms) => ms.filter((m) => !m.hidden).map((m) => m.dataset.month));