Pale yellow headers on campaign-end composition tables

Matches the pale yellow (#fdf6d8) already used for analytical table
headers elsewhere in the app. Added an optional header_bg param to
_composition_table (live preview) and passed the same color to
_docx_table (docx) for the Sector/Function/Seniority/Country tables
specifically, leaving the one other _composition_table call site
(Reports tab's compact card) untouched.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
beantownbabeandClaude Sonnet 5 committed 2026-10-02 15:33:41 +02:00
1 parent c5b6483b88
commit 32cea004ed
2 files changed
+8 -7

No files matched your search

+7 -6
View File
@@ -2934,14 +2934,15 @@ def _narrative_section(title, items):
])
def _composition_table(counter, header_left, top_n=None):
def _composition_table(counter, header_left, top_n=None, header_bg=None):
"""No truncation by default, sector/seniority/function are a small, fixed taxonomy
(see project memory's classification categories), and country is uncapped by
composition_stats() for the same reason, so showing everything keeps the table's
own sum matching the cohort total instead of silently dropping tail categories."""
items = counter.most_common(top_n) if hasattr(counter, "most_common") else list(counter)[:top_n]
th_style = {"backgroundColor": header_bg} if header_bg else {}
return dbc.Table([
html.Thead(html.Tr([html.Th(header_left), html.Th("Count")])),
html.Thead(html.Tr([html.Th(header_left, style=th_style), html.Th("Count", style=th_style)])),
html.Tbody([html.Tr([html.Td(k), html.Td(str(v))]) for k, v in items]),
], bordered=True, size="sm", style={"fontSize": "0.8rem"})
@@ -4336,10 +4337,10 @@ def _render_campaign_end_summary():
f"profiled, July-September combined)",
style={"marginTop": "18px", "color": "#1b3a5c"}))
body.append(html.Div([
html.Div(_composition_table(sector, "Sector"), style={"flex": "1", "minWidth": "0"}),
html.Div(_composition_table(function, "Function"), style={"flex": "1", "minWidth": "0"}),
html.Div(_composition_table(seniority, "Seniority"), style={"flex": "1", "minWidth": "0"}),
html.Div(_composition_table(country, "Country"), style={"flex": "1", "minWidth": "0"}),
html.Div(_composition_table(sector, "Sector", header_bg="#fdf6d8"), style={"flex": "1", "minWidth": "0"}),
html.Div(_composition_table(function, "Function", header_bg="#fdf6d8"), style={"flex": "1", "minWidth": "0"}),
html.Div(_composition_table(seniority, "Seniority", header_bg="#fdf6d8"), style={"flex": "1", "minWidth": "0"}),
html.Div(_composition_table(country, "Country", header_bg="#fdf6d8"), style={"flex": "1", "minWidth": "0"}),
], style={"display": "flex", "gap": "0.75rem", "flexWrap": "wrap"}))
for dim_title, dim_text in exec_summary.get("audience_dimensions") or []:
+1 -1
View File
@@ -350,7 +350,7 @@ def build_report_docx(ctx, timeframe_value="all"):
("Seniority", seniority), ("Country", country)]:
doc.add_paragraph(label, style="Heading 2")
rows = [[label, "Count"]] + [[str(k), str(v)] for k, v in counter.most_common()]
_docx_table(doc, rows, font_size=8)
_docx_table(doc, rows, font_size=8, header_bg="FDF6D8")
for dim_title, dim_text in exec_summary.get("audience_dimensions") or []:
p = doc.add_paragraph()