v2 unangetastet — v3 überschreibt nur Sub-Blocks. Neue v2-Blocks
für Override-Punkte: antrag_id_section, score_hero_section,
matrix_section, verbesserungen_section, aktions_section,
comments_section.
v3-Anpassungen:
1. Drucksache-ID: "Antrag im Landtag NRW · Drucksache 18/18246" —
"Drucksache" als Glossar-Hinweis klickbar.
2. Score-Hero: großes Wort-Etikett ("Stark gemeinwohlfördernd" /
"Gemischt" / "Widerspricht dem Gemeinwohl") aus verdict_title oder
abgeleitet. Score-Zahl als kleiner Untertitel mit Glossar-Link.
Akzentfarbe links (grün/blau/rot je nach Score).
3. Matrix: 5 Werte als Diverging-Bars (-5..+5) sofort sichtbar;
volle 5×5-Matrix in <details>. Aggregation = Spalten-Mittel über
die 5 Berührungsgruppen.
4. Verbesserungsvorschläge: <details> default zu, Hint-Text mit Anzahl.
5. Aktions-Links: JSON-Export raus — nur PDF + Permalink.
6. Kommentare: <details> default zu (für Erst-Leser:innen unwichtig).
Glossar-System: 6 Begriffe (Drucksache, Fraktion, GWÖ-Score,
GWÖ-Matrix, Heuchelei-Marker, Opportunismus-Marker) mit Klick/Focus-
Tooltip via Modal. Trigger: Element mit class="v3-glossar"
data-glossar="<key>".
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
303 lines
13 KiB
HTML
303 lines
13 KiB
HTML
{# ─────────────────────────────────────────────────────────────────────
|
||
v3/screens/antrag_detail.html — Bürger:innen-Modus
|
||
|
||
Override-Strategie: extendet v2-Screen, ersetzt nur die Sub-Blocks,
|
||
die in v3 vereinfacht werden. Block-Liste:
|
||
- antrag_id_section — entschärfte Drucksache-Sprache mit Glossar
|
||
- score_hero_section — Wort-Etikett groß, Zahl klein darunter
|
||
- matrix_section — 5 Werte default + <details> für 5×5
|
||
- verbesserungen_section — default kollabiert
|
||
- aktions_section — JSON-Export raus, nur PDF + Permalink
|
||
- comments_section — default kollabiert
|
||
───────────────────────────────────────────────────────────────────── #}
|
||
{% extends "v2/screens/antrag_detail.html" %}
|
||
|
||
{% block head_extra %}
|
||
{{ super() }}
|
||
<link rel="stylesheet" href="/static/v3/v3.css?v={{ app_version|default('1') }}">
|
||
{% endblock %}
|
||
|
||
{# ─── 1. Drucksache-ID: weniger Behörden-Sprache, Glossar-Hinweise ─── #}
|
||
{% block antrag_id_section %}
|
||
<div class="v2-antrag-id v3-antrag-id">
|
||
Antrag im
|
||
{% if antrag.bundesland == "BU" %}Bundestag
|
||
{% elif antrag.bundesland %}Landtag {{ antrag.bundesland }}
|
||
{% else %}Parlament{% endif %}
|
||
{% if antrag.drucksache %}
|
||
· <span class="v3-glossar" data-glossar="drucksache" tabindex="0" role="button"
|
||
aria-label="Glossar: Drucksache">Drucksache</span>
|
||
{{ antrag.drucksache }}
|
||
{% endif %}
|
||
{% if antrag.datum %} · eingebracht {{ antrag.datum }}{% endif %}
|
||
</div>
|
||
{% endblock %}
|
||
|
||
{# ─── 2. Score-Hero: Wort-Etikett groß, Zahl klein ──────────────────── #}
|
||
{% block score_hero_section %}
|
||
{% set s = (antrag.score | default(0)) | float %}
|
||
{% if s >= 7 %}
|
||
{% set v3_label = antrag.verdict_title or "Stark gemeinwohlfördernd" %}
|
||
{% set v3_class = "good" %}
|
||
{% elif s >= 4 %}
|
||
{% set v3_label = antrag.verdict_title or "Gemischt" %}
|
||
{% set v3_class = "mid" %}
|
||
{% else %}
|
||
{% set v3_label = antrag.verdict_title or "Widerspricht dem Gemeinwohl" %}
|
||
{% set v3_class = "low" %}
|
||
{% endif %}
|
||
|
||
<div class="v3-score-hero {{ v3_class }}"
|
||
role="region" aria-label="Bewertung: {{ v3_label }} ({{ '%.1f'|format(s) }} von 10)">
|
||
<div class="v3-score-label">{{ v3_label }}</div>
|
||
{% if antrag.verdict_body %}
|
||
<div class="v3-score-body">{{ antrag.verdict_body }}</div>
|
||
{% endif %}
|
||
<div class="v3-score-meta">
|
||
<span class="v3-glossar" data-glossar="gwoe-score" tabindex="0" role="button"
|
||
aria-label="Glossar: GWÖ-Score">Gemeinwohl-Score</span>:
|
||
<strong>{{ "%.1f"|format(s) }} von 10</strong>
|
||
</div>
|
||
</div>
|
||
{% endblock %}
|
||
|
||
{# ─── 3. Matrix: 5 Werte default, volle 5×5 in <details> ─────────────── #}
|
||
{% block matrix_section %}
|
||
{% if antrag.matrix %}
|
||
<h3 class="v2-h3">Beitrag zu den 5 Gemeinwohl-Werten</h3>
|
||
|
||
{# Pro Wert (Spalte 1..5) Durchschnitt aus den 5 Berührungsgruppen-Zellen.
|
||
Skala bleibt -5..+5 wie in der DB. #}
|
||
{% set v3_werte = [
|
||
("1", "Menschenwürde"),
|
||
("2", "Solidarität"),
|
||
("3", "Ökologische Nachhaltigkeit"),
|
||
("4", "Soziale Gerechtigkeit"),
|
||
("5", "Transparenz & Demokratie"),
|
||
] %}
|
||
<div class="v3-werte-list">
|
||
{% for col, label in v3_werte %}
|
||
{% set ns = namespace(sum=0, cnt=0) %}
|
||
{% for row in ["A","B","C","D","E"] %}
|
||
{% set cell = antrag.matrix[row ~ col] | default(none) %}
|
||
{% if cell %}
|
||
{% set ns.sum = ns.sum + (cell.rating | int) %}
|
||
{% set ns.cnt = ns.cnt + 1 %}
|
||
{% endif %}
|
||
{% endfor %}
|
||
{% set avg = (ns.sum / ns.cnt) if ns.cnt else 0 %}
|
||
{% set pct = ((avg + 5) / 10 * 100) %}
|
||
<div class="v3-wert-row">
|
||
<div class="v3-wert-label">{{ label }}</div>
|
||
<div class="v3-wert-bar" aria-hidden="true">
|
||
<div class="v3-wert-track">
|
||
<div class="v3-wert-mid"></div>
|
||
<div class="v3-wert-fill {% if avg >= 1 %}pos{% elif avg <= -1 %}neg{% else %}neu{% endif %}"
|
||
style="left: {{ 'calc(50% - ' ~ ((-avg / 5 * 50)) ~ '%)' if avg < 0 else '50%' }};
|
||
width: {{ ((avg if avg > 0 else -avg) / 5 * 50) }}%;"></div>
|
||
</div>
|
||
</div>
|
||
<div class="v3-wert-num"
|
||
title="Durchschnitt der 5 Berührungsgruppen — Skala −5 bis +5">
|
||
{% if avg > 0 %}+{% endif %}{{ "%.1f"|format(avg) }}
|
||
</div>
|
||
</div>
|
||
{% endfor %}
|
||
</div>
|
||
|
||
<details class="v3-matrix-details">
|
||
<summary>
|
||
Volle <span class="v3-glossar" data-glossar="gwoe-matrix" tabindex="0" role="button"
|
||
aria-label="Glossar: GWÖ-Matrix">GWÖ-Matrix 2.0</span>
|
||
· 25 Felder (5 Werte × 5 Berührungsgruppen)
|
||
</summary>
|
||
<div style="margin-top:8px;">
|
||
{% from "v2/components/matrix_mini.html" import matrix_mini %}
|
||
{{ matrix_mini(antrag.matrix) }}
|
||
</div>
|
||
</details>
|
||
{% endif %}
|
||
{% endblock %}
|
||
|
||
{# ─── 4. Verbesserungsvorschläge: default kollabiert ──────────────────── #}
|
||
{% block verbesserungen_section %}
|
||
{% if antrag.verbesserungen %}
|
||
<details class="v3-collapsible">
|
||
<summary>
|
||
<h3 class="v2-h3">Verbesserungsvorschläge</h3>
|
||
<span class="v3-collapsible-hint">{{ antrag.verbesserungen | length }} Vorschlag{{ "" if antrag.verbesserungen | length == 1 else "e" }} · klicken zum Aufklappen</span>
|
||
</summary>
|
||
<div style="margin-top:12px;">
|
||
{% for v in antrag.verbesserungen %}
|
||
<div style="margin-bottom:16px;">
|
||
{% if antrag.verbesserungen | length > 1 %}
|
||
<div style="font-family:var(--font-mono);font-size:11px;color:var(--ecg-dark);opacity:0.65;margin-bottom:4px;">
|
||
Vorschlag {{ loop.index }} von {{ antrag.verbesserungen | length }}
|
||
</div>
|
||
{% endif %}
|
||
{% from "v2/components/redline.html" import redline %}
|
||
{% if v.segments %}
|
||
{{ redline(original=v.original | default(""), segments=v.segments) }}
|
||
{% else %}
|
||
{{ redline(original=v.original | default(""), vorschlag=v.vorschlag | default("")) }}
|
||
{% endif %}
|
||
{% if v.begruendung %}
|
||
<p style="font-size:12px;color:var(--ecg-dark);opacity:0.75;margin:4px 0 0;font-family:var(--font-mono);">
|
||
{{ v.begruendung }}
|
||
</p>
|
||
{% endif %}
|
||
</div>
|
||
{% endfor %}
|
||
</div>
|
||
</details>
|
||
{% endif %}
|
||
{% endblock %}
|
||
|
||
{# ─── 5. Aktions-Links: nur PDF + Permalink ──────────────────────────── #}
|
||
{% block aktions_section %}
|
||
<div class="v3-aktions">
|
||
<a href="/api/assessment/pdf?drucksache={{ antrag.drucksache | urlencode }}">
|
||
PDF-Bericht
|
||
</a>
|
||
<a href="/antrag/{{ antrag.drucksache }}">
|
||
Permalink
|
||
</a>
|
||
</div>
|
||
{% endblock %}
|
||
|
||
{# ─── 6. Kommentare: default kollabiert ──────────────────────────────── #}
|
||
{% block comments_section %}
|
||
<details class="v3-collapsible v3-comments">
|
||
<summary>
|
||
<h3 class="v2-h3">Kommentare</h3>
|
||
<span class="v3-collapsible-hint">klicken zum Aufklappen · Anmeldung erforderlich</span>
|
||
</summary>
|
||
<div style="margin-top:16px;">
|
||
<div id="v2-comments-list" style="margin-bottom:20px;">
|
||
<span style="font-family:var(--font-mono);font-size:12px;color:var(--ecg-dark);opacity:0.5;">Lade…</span>
|
||
</div>
|
||
|
||
<div id="v2-comment-form" style="display:none;">
|
||
<div style="font-family:var(--font-mono);font-size:10px;text-transform:uppercase;letter-spacing:0.07em;color:var(--ecg-dark);opacity:0.6;margin-bottom:8px;">Kommentar hinzufügen</div>
|
||
<textarea id="v2-comment-input"
|
||
rows="3"
|
||
placeholder="Kommentar…"
|
||
style="width:100%;box-sizing:border-box;padding:8px 10px;border:1px solid var(--hairline);border-radius:4px;font-family:var(--font-sans);font-size:13px;background:var(--surface);color:var(--ecg-dark);resize:vertical;margin-bottom:8px;outline:none;"></textarea>
|
||
<div style="display:flex;gap:8px;align-items:center;flex-wrap:wrap;">
|
||
<select id="v2-comment-visibility"
|
||
style="padding:5px 8px;border:1px solid var(--hairline);border-radius:4px;font-family:var(--font-mono);font-size:11px;background:var(--surface);color:var(--ecg-dark);">
|
||
<option value="all">Öffentlich</option>
|
||
<option value="authenticated">Nur Angemeldete</option>
|
||
<option value="private">Nur ich</option>
|
||
</select>
|
||
<button onclick="v2DetailAddComment('{{ antrag.drucksache | e }}')"
|
||
style="padding:5px 14px;border:none;border-radius:4px;background:var(--ecg-blue);color:#fff;cursor:pointer;font-family:var(--font-mono);font-size:11px;font-weight:700;">
|
||
Absenden
|
||
</button>
|
||
</div>
|
||
</div>
|
||
|
||
<div id="v2-comment-login-hint" style="display:none;">
|
||
<button onclick="v2AuthModalOpen()"
|
||
style="padding:5px 12px;border:1px solid var(--hairline);border-radius:4px;background:none;cursor:pointer;font-family:var(--font-mono);font-size:11px;color:var(--ecg-blue);">
|
||
Anmelden um zu kommentieren
|
||
</button>
|
||
</div>
|
||
</div>
|
||
</details>
|
||
{% endblock %}
|
||
|
||
{# ─── Topbar-Pill + Toggle + Glossar-Tooltips (JS) ───────────────────── #}
|
||
{% block body_scripts %}
|
||
{{ super() }}
|
||
<script>
|
||
/* Topbar: Beta-Pill + Toggle zurueck zu Profi-Modus */
|
||
(function () {
|
||
var bar = document.querySelector('.v2-topbar');
|
||
if (!bar) return;
|
||
var pill = document.createElement('span');
|
||
pill.className = 'v3-beta-badge';
|
||
pill.textContent = 'Bürger:innen-Modus · Beta';
|
||
pill.title = 'Vereinfachte Ansicht für Erst-Leser:innen.';
|
||
var toggle = document.createElement('a');
|
||
toggle.className = 'v3-modus-toggle';
|
||
toggle.href = '/antrag/' + encodeURIComponent({{ antrag.drucksache | tojson }});
|
||
toggle.textContent = '→ Profi-Modus';
|
||
toggle.title = 'Volle GWÖ-Detailansicht (v2) öffnen';
|
||
bar.appendChild(pill);
|
||
bar.appendChild(toggle);
|
||
})();
|
||
|
||
/* Glossar-Tooltips: Klick/Focus öffnet Pop-up mit Alltags-Definition. */
|
||
window._v3Glossar = {
|
||
"drucksache": {
|
||
titel: "Drucksache",
|
||
text: "Eine Drucksache ist die offizielle Nummer eines Antrags im Parlament. Format: <Wahlperiode>/<laufende Nummer>. Beispiel: '18/18246' = 18. Wahlperiode, Nummer 18246. Über diese Nummer findest du den Antrag in den Parlamentsakten."
|
||
},
|
||
"fraktion": {
|
||
titel: "Fraktion",
|
||
text: "Eine Fraktion ist die Gruppe der Abgeordneten einer Partei im Parlament. Sie ist nicht dasselbe wie die Partei selbst — die Partei ist die Organisation außerhalb, die Fraktion sind die gewählten Abgeordneten innerhalb."
|
||
},
|
||
"gwoe-score": {
|
||
titel: "Gemeinwohl-Score (0–10)",
|
||
text: "Der GWÖ-Score bewertet, wie stark der Antrag dem Gemeinwohl dient — auf einer Skala von 0 bis 10. Höher = besser für die Allgemeinheit. Der Wert ist ein gewichteter Durchschnitt aus 25 Bewertungs-Feldern (5 Werte × 5 Berührungsgruppen). Mehr unter /methodik."
|
||
},
|
||
"gwoe-matrix": {
|
||
titel: "GWÖ-Matrix 2.0",
|
||
text: "Die Gemeinwohl-Matrix ist ein Bewertungsraster mit 25 Feldern: 5 Werte (Menschenwürde, Solidarität, Nachhaltigkeit, Gerechtigkeit, Transparenz) × 5 Berührungsgruppen (Lieferant:innen, Finanzen, Verwaltung, Bürger:innen, Gesellschaft & Natur). Jedes Feld bekommt eine Bewertung von −5 (stark widersprechend) bis +5 (stark fördernd)."
|
||
},
|
||
"heuchelei": {
|
||
titel: "Heuchelei-Marker (⚠)",
|
||
text: "Wird angezeigt, wenn eine Fraktion mit Nein gestimmt hat, obwohl der Antrag inhaltlich gut zu ihrem eigenen Wahlprogramm passt (Wahlprogramm-Score ≥ 7 von 10). Der Marker macht die Lücke zwischen Wahlversprechen und Abstimmungsverhalten sichtbar."
|
||
},
|
||
"opportunismus": {
|
||
titel: "Opportunismus-Marker (!)",
|
||
text: "Wird angezeigt, wenn eine Fraktion mit Ja gestimmt hat, obwohl der Antrag schlecht zum eigenen Wahlprogramm passt (Wahlprogramm-Score < 3 von 10). Mögliches Anzeichen für taktisches Stimmverhalten."
|
||
}
|
||
};
|
||
|
||
window.v3OpenGlossar = function (key) {
|
||
var data = window._v3Glossar[key];
|
||
if (!data) return;
|
||
var modal = document.getElementById('v3-glossar-modal');
|
||
if (!modal) return;
|
||
document.getElementById('v3-glossar-title').textContent = data.titel;
|
||
document.getElementById('v3-glossar-body').textContent = data.text;
|
||
modal.style.display = 'flex';
|
||
};
|
||
|
||
document.addEventListener('click', function (e) {
|
||
var t = e.target.closest('.v3-glossar');
|
||
if (t) {
|
||
e.preventDefault();
|
||
window.v3OpenGlossar(t.dataset.glossar);
|
||
}
|
||
});
|
||
document.addEventListener('keydown', function (e) {
|
||
if ((e.key === 'Enter' || e.key === ' ') && document.activeElement && document.activeElement.classList.contains('v3-glossar')) {
|
||
e.preventDefault();
|
||
window.v3OpenGlossar(document.activeElement.dataset.glossar);
|
||
}
|
||
if (e.key === 'Escape') {
|
||
var m = document.getElementById('v3-glossar-modal');
|
||
if (m && m.style.display === 'flex') { m.style.display = 'none'; }
|
||
}
|
||
});
|
||
</script>
|
||
|
||
{# Glossar-Modal #}
|
||
<div id="v3-glossar-modal" class="v3-glossar-modal" role="dialog" aria-modal="true"
|
||
aria-labelledby="v3-glossar-title"
|
||
onclick="if(event.target===this)this.style.display='none'">
|
||
<div class="v3-glossar-card">
|
||
<div class="v3-glossar-head">
|
||
<strong id="v3-glossar-title"></strong>
|
||
<button class="v3-glossar-close"
|
||
onclick="document.getElementById('v3-glossar-modal').style.display='none'"
|
||
aria-label="Schließen">×</button>
|
||
</div>
|
||
<p id="v3-glossar-body"></p>
|
||
</div>
|
||
</div>
|
||
{% endblock %}
|