style: humanize reports and translate Streamlit UI to English

Streamlit tabs: translated all Dutch text to English in overton.py,
compass.py (Overton expander + voting discipline), trajectories.py.

Humanization (all 3 report surfaces):
- Removed 60+ em dashes, replaced with periods/commas/colons
- Removed AI vocabulary (crucial, pivotal, underscores, landscape)
- Removed excessive boldface, rule-of-three, -ing padding
- Replaced 'serves as'/'stands as' with 'is'
- Preserved all data, numbers, tables, code blocks exactly
This commit is contained in:
2026-06-14 23:39:34 +02:00
parent 3192a1a2bf
commit a5624f65bc
6 changed files with 182 additions and 182 deletions
+21 -21
View File
@@ -185,28 +185,28 @@ def build_compass_tab(db_path: str, window_size: str) -> None:
with st.expander("Overton Window Context"):
st.markdown(
"Het SVD-kompas visualiseert de dynamiek achter de "
"**verbreding van het Overton-venster** in de Tweede Kamer.\n\n"
"Centristische steun voor rechtse moties steeg van 25% naar 51% na 2024, "
"terwijl steun voor linkse moties gelijk bleef. Het venster verschoof — "
"meer rechtse standpunten werden acceptabel.\n\n"
"Maar: **centristische partijen** (D66, CDA, CU, NSC) zijn op **beide assen naar"
" links** verschoven, terwijl rechtse partijen stabiel bleven. Dit patroon"
' van "acceptatie zonder conversie" betekent dat rechtse partijen mildere'
" moties gingen indienen, en centristen daardoor vaker konden meestemmen — "
"zonder dat ze ideologisch naar rechts opschoven.\n\n"
"[Lees de volledige analyse](../reports/overton_window/overton_window.qmd)\n\n"
"Probeer de **Stemwijzer-quiz** om te zien welke MP bij jouw standpunten past."
"The SVD compass visualizes the dynamics behind the "
"**widening of the Overton window** in the Dutch parliament.\n\n"
"Centrist support for right-wing motions rose from 25% to 51% after 2024, "
"while support for left-wing motions stayed flat. The window widened: "
"more right-wing positions became acceptable.\n\n"
"But **centrist parties** (D66, CDA, CU, NSC) moved **left on both axes** "
"while right-wing parties stayed put. This pattern of "
'"acceptance without conversion" means right-wing parties filed milder '
"motions, and centrists could vote along more often, "
"without shifting ideologically to the right.\n\n"
"[Read the full analysis](../reports/overton_window/overton_window.qmd)\n\n"
"Try the **Stemwijzer quiz** to see which MP matches your positions."
)
st.markdown("---")
st.markdown(
"**Stemdiscipline analyse:** De Rice-index meet hoe eensgezind partijen stemmen "
"tijdens hoofdelijke stemmingen. Een score van 100% betekent dat alle MPs van "
"een partij hetzelfde stemden; 50% wijst op een gelijke splitsing binnen de partij. "
"Partijen met hoge discipline (>95%) zoals PVV en SGP stemmen als een blok, wat "
"wijst op sterke partijdiscipline en homogene membership. Lagere discipline (<85%) "
"bij partijen als PvdA of SP kan duiden op interne factiestrijd, gewetensvragen "
"bij ethische thema's, of een brede ideologische koers die ruimte laat voor "
"afwijkende meningen. De discipline varieert ook per onderwerp — ethische kwesties "
"tonen vaak meer interne verschillen dan economische thema's."
"**Voting discipline analysis:** The Rice index measures how united parties vote "
"during roll-call votes. A score of 100% means all MPs of a party voted the "
"same way; 50% indicates an even split within the party. "
"High-discipline parties (>95%) like PVV and SGP vote as a bloc, indicating "
"strong party discipline and homogeneous membership. Lower discipline (<85%) "
"in parties like PvdA or SP may indicate internal factional struggles, conscience "
"votes on ethical issues, or a broad ideological course that leaves room for "
"dissenting opinions. Discipline also varies by topic: ethical issues "
"tend to show more internal division than economic topics."
)
+33 -33
View File
@@ -15,18 +15,18 @@ logger = logging.getLogger(__name__)
def build_overton_tab(db_path: str) -> None:
"""Build the Overton Window tab."""
st.subheader("Overton Window Analyse")
st.subheader("Overton Window Analysis")
st.markdown(
"Het Overton-venster **verbreedde** na 2024: centristische steun voor rechtse "
"moties steeg van 25% naar 51%, terwijl steun voor linkse moties gelijk bleef. "
"Rechtse partijen dienden mildere moties in, waardoor centristen vaker konden "
"meestemmen — zonder ideologisch naar rechts op te schuiven."
"The Overton window **widened** after 2024: centrist support for right-wing "
"motions rose from 25% to 51%, while support for left-wing motions stayed flat. "
"Right-wing parties filed milder motions, allowing centrists to vote along "
"without shifting ideologically."
)
try:
con = duckdb.connect(db_path, read_only=True)
except Exception:
st.warning("Kan geen verbinding maken met de database.")
st.warning("Cannot connect to the database.")
return
try:
@@ -35,12 +35,12 @@ def build_overton_tab(db_path: str) -> None:
).fetchall()
if not tables:
st.info(
"De right_wing_motions tabel is nog niet beschikbaar. "
"Draai de pipeline om deze te genereren."
"The right_wing_motions table is not yet available. "
"Run the pipeline to generate it."
)
return
except Exception:
st.info("De right_wing_motions tabel is niet beschikbaar.")
st.info("The right_wing_motions table is not available.")
return
try:
@@ -50,7 +50,7 @@ def build_overton_tab(db_path: str) -> None:
_render_motion_browser(con)
_render_explore_further()
except Exception as e:
st.error(f"Fout bij laden van Overton data: {e}")
st.error(f"Error loading Overton data: {e}")
logger.exception("Overton tab error")
finally:
con.close()
@@ -65,7 +65,7 @@ def _render_centrist_support_chart(con: duckdb.DuckDBPyConnection) -> None:
""").fetchdf()
if df.empty:
st.info("Geen centrist support data beschikbaar.")
st.info("No centrist support data available.")
return
fig = go.Figure()
@@ -82,7 +82,7 @@ def _render_centrist_support_chart(con: duckdb.DuckDBPyConnection) -> None:
fig.add_trace(go.Bar(
x=df["year"],
y=df["n_motions"],
name="Aantal moties",
name="Motion count",
yaxis="y2",
marker_color="#90CAF9",
opacity=0.5,
@@ -99,10 +99,10 @@ def _render_centrist_support_chart(con: duckdb.DuckDBPyConnection) -> None:
)
fig.update_layout(
title="Centrist Support voor Rechtse Moties",
xaxis=dict(title="Jaar", dtick=1),
title="Centrist Support for Right-Wing Motions",
xaxis=dict(title="Year", dtick=1),
yaxis=dict(title="Centrist Support", range=[0, 1]),
yaxis2=dict(title="Aantal moties", overlaying="y", side="right"),
yaxis2=dict(title="Motion count", overlaying="y", side="right"),
height=400,
legend=dict(orientation="h", y=1.1),
hovermode="x unified",
@@ -112,7 +112,7 @@ def _render_centrist_support_chart(con: duckdb.DuckDBPyConnection) -> None:
def _render_summary_stats(con: duckdb.DuckDBPyConnection) -> None:
st.subheader("Samenvatting")
st.subheader("Summary")
result = con.execute("""
SELECT
@@ -139,10 +139,10 @@ def _render_summary_stats(con: duckdb.DuckDBPyConnection) -> None:
def _render_migration_gateway(con: duckdb.DuckDBPyConnection) -> None:
st.subheader("Migratie: de gateway-domein")
st.subheader("Migration: the gateway domain")
st.markdown(
"Migratie is waar de Overton-verschuiving het meest echt is — en waar "
"rechtse partijen de frames leerden die ze later op andere domeinen toepasten."
"Migration is where the Overton shift is most genuine, and where "
"right-wing parties learned the frames they later applied to other domains."
)
df = con.execute("""
@@ -165,21 +165,21 @@ def _render_migration_gateway(con: duckdb.DuckDBPyConnection) -> None:
post = df[df["period"] == "Post-2024"].iloc[0]
col1, col2, col3, col4 = st.columns(4)
col1.metric("Pre-2024 CS (migratie)", f"{pre['cs_strict']:.3f}")
col2.metric("Post-2024 CS (migratie)", f"{post['cs_strict']:.3f}")
col1.metric("Pre-2024 CS (migration)", f"{pre['cs_strict']:.3f}")
col2.metric("Post-2024 CS (migration)", f"{post['cs_strict']:.3f}")
col3.metric("Shift", f"{post['cs_strict'] - pre['cs_strict']:+.3f}")
col4.metric("Moties", f"{int(pre['n_motions'] + post['n_motions'])}")
col4.metric("Motions", f"{int(pre['n_motions'] + post['n_motions'])}")
st.caption(
"Ter vergelijking: niet-migratie moties gingen van 0.276 naar 0.481 (+0.205). "
"Migratie steeg meer dan twee keer zo hard (+0.216), terwijl de materiële impact "
"nauwelijks daalde. CDA en ChristenUnie verdubbelden hun migratie-steun "
"(18%40%, 10%30%)."
"For comparison: non-migration motions went from 0.276 to 0.481 (+0.205). "
"Migration rose more than twice as fast (+0.216), while material impact "
"barely declined. CDA and ChristenUnie doubled their migration support "
"(18% to 40%, 10% to 30%)."
)
def _render_motion_browser(con: duckdb.DuckDBPyConnection) -> None:
st.subheader("Rechtse Moties Browser")
st.subheader("Right-Wing Motions Browser")
df = con.execute("""
SELECT r.year, r.title, m.text, r.centrist_support_strict, r.category
@@ -191,21 +191,21 @@ def _render_motion_browser(con: duckdb.DuckDBPyConnection) -> None:
""").fetchdf()
if df.empty:
st.info("Geen rechtse moties gevonden.")
st.info("No right-wing motions found.")
return
df = df.rename(columns={
"year": "Jaar",
"title": "Titel",
"text": "Motietekst",
"year": "Year",
"title": "Title",
"text": "Motion text",
"centrist_support_strict": "Centrist Support",
"category": "Categorie",
"category": "Category",
})
st.dataframe(df, use_container_width=True, height=600)
def _render_explore_further() -> None:
st.subheader("Verder verkennen")
st.subheader("Explore further")
st.markdown(
"- See party positions → Kompas tab\n"
"- See party drift over time → Trajectories tab\n"
+4 -4
View File
@@ -667,10 +667,10 @@ def build_trajectories_tab(db_path: str, window_size: str) -> None:
try:
st.plotly_chart(fig, use_container_width=True)
st.info(
"**Overton-venster verbreed:** na PVV's verkiezingsoverwinning (nov 2023) "
"steeg centristische steun voor rechtse moties van 25% naar 51%, "
"terwijl steun voor linkse moties gelijk bleef. "
"Rechtse partijen matigden hun moties, centristen stemden vaker voor."
"**Overton window widened:** after PVV's election victory (Nov 2023), "
"centrist support for right-wing motions rose from 25% to 51%, "
"while support for left-wing motions stayed flat. "
"Right-wing parties moderated their motions; centrists voted along more often."
)
except Exception as e:
st.error(f"Trajectories rendering failed: {e}")