diff --git a/docs/assets/personal-workspace/steward-reports/masthead/after-desktop.png b/docs/assets/personal-workspace/steward-reports/masthead/after-desktop.png new file mode 100644 index 0000000000..12e2f482ab Binary files /dev/null and b/docs/assets/personal-workspace/steward-reports/masthead/after-desktop.png differ diff --git a/docs/assets/personal-workspace/steward-reports/masthead/after-narrow.png b/docs/assets/personal-workspace/steward-reports/masthead/after-narrow.png new file mode 100644 index 0000000000..28c29c76b6 Binary files /dev/null and b/docs/assets/personal-workspace/steward-reports/masthead/after-narrow.png differ diff --git a/docs/assets/personal-workspace/steward-reports/masthead/before-desktop.png b/docs/assets/personal-workspace/steward-reports/masthead/before-desktop.png new file mode 100644 index 0000000000..792a1dfcdc Binary files /dev/null and b/docs/assets/personal-workspace/steward-reports/masthead/before-desktop.png differ diff --git a/loopx/capabilities/periodic_report/private_generation.py b/loopx/capabilities/periodic_report/private_generation.py index d83c78bbe4..30d4546964 100644 --- a/loopx/capabilities/periodic_report/private_generation.py +++ b/loopx/capabilities/periodic_report/private_generation.py @@ -254,6 +254,10 @@ def validate_private_generation(folder: Path) -> dict[str, Any]: # Rendering can improve after a window was frozen. Reconstruct only the # exact prior presentation; never rewrite or regenerate it. # Both candidates still require full bundle, source and body equality. + checked = build_periodic_report_generation_bundle(document=bundle["document"], artifacts=[ + render_periodic_report_markdown(bundle["document"]), + render_periodic_report_html(bundle["document"], _legacy_masthead=True)]) + if checked != bundle: checked = build_periodic_report_generation_bundle(document=bundle["document"], artifacts=[ render_periodic_report_markdown(bundle["document"], _legacy_layout=True), render_periodic_report_html(bundle["document"], _legacy_layout=True)]) diff --git a/loopx/presentation/renderers/periodic_report_html.py b/loopx/presentation/renderers/periodic_report_html.py index 60510e3b28..416e218c86 100644 --- a/loopx/presentation/renderers/periodic_report_html.py +++ b/loopx/presentation/renderers/periodic_report_html.py @@ -458,7 +458,7 @@ def _render_source_references(references: Mapping[str, int], labels: Mapping[str .shell { width: min(1220px, calc(100% - 40px)); margin: 0 auto; padding: 40px 0 80px; } .masthead { border-top: 8px solid var(--ink); border-bottom: 1.5px solid var(--ink); padding: 27px 0 26px; } -.mast-grid { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 28px; +.mast-grid { display: grid; grid-template-columns: minmax(0, 1fr) minmax(240px, 360px); gap: 28px; align-items: end; } .eyebrow { margin: 0 0 8px; color: var(--muted); font: 650 10px/1.4 var(--mono); letter-spacing: .1em; text-transform: uppercase; } @@ -663,13 +663,20 @@ def _render_source_references(references: Mapping[str, int], labels: Mapping[str def render_periodic_report_html(document: Mapping[str, Any], *, _legacy_source_links: bool = False, - _legacy_layout: bool = False) -> dict[str, Any]: + _legacy_layout: bool = False, + _legacy_masthead: bool = False) -> dict[str, Any]: """Render one dense, self-contained report without changing its semantics.""" if document.get("schema_version") != DOCUMENT_SCHEMA: raise ValueError(f"document must use {DOCUMENT_SCHEMA}") validate_periodic_report_editorial(document) _legacy_layout = _legacy_layout or _legacy_source_links + css = _CSS + if _legacy_masthead or _legacy_layout: + # Exact read-only reconstruction of already frozen presentations. + css = css.replace( + "grid-template-columns: minmax(0, 1fr) minmax(240px, 360px)", + "grid-template-columns: minmax(0, 1fr) auto", 1) references = {} if _legacy_layout else _source_references(document) sections = _items(document.get("sections")) primary_sections = [ @@ -757,7 +764,7 @@ def render_periodic_report_html(document: Mapping[str, Any], *, _legacy_source_l '" - f"