gwoe-antragspruefer/app/templates/v3/screens/antrag_detail.html
Dotty Dotter 2f700adbb8 ui(antrag-detail): Programm-Treue-Box auf 1/3 der Höhe verkleinert
Pro Fraktion bisher ~137px (Head + Wahlprogramm-Reihe + Parteiprogramm-
Reihe in drei vertikalen Blöcken). Nutzer wollte deutlich kompakter.

Layout: Fraktion-Name + Antragsteller-/Regierungs-Pillen + zwei
Programm-Pillen (WP / PP) jetzt in EINER flex-row. Pro Programm-Pille
ein klickbares <details> mit Mini-Score-Chip; beim Aufklappen fließt
der Body (Begründung + Zitate) dank ``flex-basis: 100%`` unter die
Zeile in voller Breite.

Höhe collapsed: ~40-45px pro Fraktion (von vorher ~137px). Begründung
in der ausgeklappten Box bekommt zusätzlich einen ``Wahlprogramm:``-/
``Parteiprogramm:``-Präfix, da der Programm-Typ aus der Pille nicht
mehr im Body explizit auftaucht.

Doppelte v3-prog-text-Regel im CSS entfernt (war vergessenes Cruft).
2026-05-09 01:18:27 +02:00

580 lines
27 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

{# ─────────────────────────────────────────────────────────────────────
v3/screens/antrag_detail.html — Bürger:innen-Modus, single column
Override-Strategie: extendet v2/screens/antrag_detail.html und
ersetzt nur `block main` komplett. body_scripts erbt via super(), so
dass alle v2-JS-Handler (vote, merkliste, share, comments, history,
matrix-modal) ohne Code-Duplikation weiterlaufen — sie hängen sich an
DOM-IDs (v2-vote-up, v2-merkliste-btn, v2-comments-list, …), die wir
in der neuen Layout-Reihenfolge wiederverwenden.
Reihenfolge (single column):
1. Metadaten/Titel
2. Zusammenfassung
3. Bewertung (Score xl + Empfehlung daneben + Begründung darunter)
4. Merken / Bewertung treffend
5. Matrix 5×5
6. Programm-Treue (default-closed Klappmechanismus pro Programm)
7. Verbesserungsvorschläge (volle Breite, nicht kollabiert)
8. Abstimmungsergebnis
9. Rest: PDF/Teilen/Neu/Historie + Stärken/Schwächen + Konsistenz +
Marker-Legende + News + Kommentare
───────────────────────────────────────────────────────────────────── #}
{% extends "v2/screens/antrag_detail.html" %}
{% from "v2/components/score_hero.html" import score_hero %}
{% from "v2/components/matrix_mini.html" import matrix_mini %}
{% from "v2/components/quote_card.html" import quote_card %}
{% from "v2/components/redline.html" import redline %}
{% block head_extra %}
{{ super() }}
<link rel="stylesheet" href="/static/v3/v3.css?v={{ app_version|default('1') }}">
{% endblock %}
{% block main %}
{% if error is defined and error %}
<div class="v2-kasten" style="border-color:var(--redline-contra);margin-top:32px;">
<h3 style="color:var(--redline-contra);">Antrag nicht gefunden</h3>
<p>{{ error }}</p>
<p><a href="/">← Zurück zur Übersicht</a></p>
</div>
{% elif antrag is defined and antrag %}
<div class="v3-page">
<p class="v3-back">
<a href="/">← Zurück zur Übersicht</a>
</p>
{# 1 ── Metadaten + Titel ─────────────────────────────────────────── #}
<section class="v3-section v3-meta">
<div class="v3-antrag-id">
{{ antrag.bundesland | default("") }}
{% if antrag.drucksache %} · Drs. {{ antrag.drucksache }}{% endif %}
{% if antrag.typ %} · {{ antrag.typ }}{% endif %}
{% if antrag.wahlperiode %} · {{ antrag.wahlperiode }}. Wahlperiode{% endif %}
{% if antrag.datum %} · eingebracht {{ antrag.datum }}{% endif %}
</div>
<h1 class="v3-title">{{ antrag.title | default("Antrag") }}</h1>
{% if antrag.parteien or antrag.analysiert %}
<div class="v3-byline">
{% if antrag.parteien %}Eingebracht von {{ antrag.parteien | join(", ") }}{% endif %}
{% if antrag.analysiert %} — Analyse {{ antrag.analysiert }}{% endif %}
{% if antrag.modell %}, {{ antrag.modell }}{% endif %}
{% if antrag.zitate_count %} · {{ antrag.zitate_count }} Zitat{{ "e" if antrag.zitate_count != 1 else "" }} verifiziert{% endif %}
</div>
{% endif %}
{% if antrag.themen %}
<div class="v3-themen">
{% for t in antrag.themen %}<span class="v3-theme-chip">{{ t }}</span>{% endfor %}
</div>
{% endif %}
</section>
{# Merken + Bewertung treffend — direkt unter den Metadaten ──────── #}
<section class="v3-section v3-userrow">
<button id="v2-merkliste-btn" onclick="v2DetailMerklisteToggle()" class="v3-action-btn">
<span id="v2-merkliste-star"></span>
<span id="v2-merkliste-label">Merken</span>
</button>
<div class="v3-userrow-vote">
<span class="v3-userrow-label">Bewertung treffend?</span>
<div id="v2-vote-overall" class="v3-vote-buttons">
<button id="v2-vote-up" onclick="v2DetailCastVote('{{ antrag.drucksache | e }}','up')" class="v3-action-btn">
👍 <span id="v2-vote-up-count">0</span>
</button>
<button id="v2-vote-down" onclick="v2DetailCastVote('{{ antrag.drucksache | e }}','down')" class="v3-action-btn">
👎 <span id="v2-vote-down-count">0</span>
</button>
</div>
</div>
</section>
{# 2 ── Zusammenfassung + Kernpunkte ─────────────────────────────── #}
{% if antrag.zusammenfassung or antrag.kernpunkte %}
<section class="v3-section">
<h3 class="v3-h3">Zusammenfassung</h3>
{% if antrag.zusammenfassung %}
<p class="v3-prose">{{ antrag.zusammenfassung }}</p>
{% endif %}
{% if antrag.kernpunkte %}
<div class="v3-kernpunkte">
<div class="v3-kernpunkte-label">Kernforderungen</div>
<ul class="v3-kernpunkte-list">
{% for kp in antrag.kernpunkte %}<li>{{ kp }}</li>{% endfor %}
</ul>
</div>
{% endif %}
</section>
{% endif %}
{# 3 ── Bewertung ─────────────────────────────────────────────────── #}
<section class="v3-section v3-bewertung">
{% set s = (antrag.score | default(0)) | float %}
<div class="v3-bewertung-head">
<div class="v3-score-num
{% if s >= 7 %}good{% elif s >= 4 %}mid{% else %}low{% endif %}">
{{ "%.1f"|format(s) }}<span class="v3-score-slash">/10</span>
</div>
{% if antrag.verdict_title %}
<div class="v3-empfehlung-wrap">
<div class="v3-empfehlung
{% if s >= 7 %}good{% elif s >= 4 %}mid{% else %}low{% endif %}">
{{ antrag.verdict_title }}
</div>
{% if antrag.konfidenz %}
<span class="v3-konfidenz v3-konfidenz-{{ antrag.konfidenz | lower }}"
title="Wie sicher ist die Bewertung des LLM? — wissenschaftlicher Begriff: Konfidenz.">
Bewertungs-Sicherheit: {{ antrag.konfidenz }}
</span>
{% endif %}
</div>
{% endif %}
</div>
{% if antrag.verdict_body %}
<p class="v3-bewertung-body">{{ antrag.verdict_body }}</p>
{% endif %}
</section>
{# 3b ── Stärkster + Schwächster Wert (nach Bewertung, vor User-Aktionen) #}
{% if antrag.staerkster_wert or antrag.staerken or antrag.schwaechster_wert or antrag.schwaechen %}
<section class="v3-section v3-werte-grid">
{% if antrag.staerkster_wert and antrag.staerkster_wert.text %}
<div class="v2-kasten outline-green">
<h4>Stärkster Wert{% if antrag.staerkster_wert.titel %} — {{ antrag.staerkster_wert.titel }}{% endif %}</h4>
<p>{{ antrag.staerkster_wert.text }}</p>
</div>
{% elif antrag.staerken %}
<div class="v2-kasten outline-green">
<h4>Stärken</h4>
<ul>{% for s in antrag.staerken %}<li>{{ s }}</li>{% endfor %}</ul>
</div>
{% endif %}
{% if antrag.schwaechster_wert and antrag.schwaechster_wert.text %}
<div class="v2-kasten outline-blue">
<h4>Schwächster Wert{% if antrag.schwaechster_wert.titel %} — {{ antrag.schwaechster_wert.titel }}{% endif %}</h4>
<p>{{ antrag.schwaechster_wert.text }}</p>
</div>
{% elif antrag.schwaechen %}
<div class="v2-kasten outline-blue">
<h4>Schwächen</h4>
<ul>{% for s in antrag.schwaechen %}<li>{{ s }}</li>{% endfor %}</ul>
</div>
{% endif %}
</section>
{% endif %}
{# 5 ── Matrix 5×5 (volle Profi-Variante, mit Klick-Modal) ────────── #}
{% if antrag.matrix %}
<section class="v3-section">
<h3 class="v3-h3">Matrix 2.0 · 25 Felder</h3>
{% if antrag.schwerpunkt %}
<div class="v3-schwerpunkt">
<span class="v3-schwerpunkt-label">Schwerpunkt-Felder:</span>
{% for f in antrag.schwerpunkt %}<span class="v3-schwerpunkt-chip">{{ f }}</span>{% endfor %}
</div>
{% endif %}
{{ matrix_mini(antrag.matrix) }}
</section>
{% endif %}
{# Geltungs-Kontext — Regierung + Programmgeltung zur Antragszeit.
Macht transparent, gegen welche Programme die LLM-Bewertung gemessen
wurde. Daten kommen aus app/legislaturen.py + app/programme.py. #}
{% if geltung_kontext and (geltung_kontext.regierung or geltung_kontext.legislatur or geltung_kontext.programme) %}
<section class="v3-section v3-geltung">
<h3 class="v3-h3">Bewertungs-Kontext</h3>
<div class="v3-geltung-meta">
{% if geltung_kontext.legislatur %}
<div>
<span class="v3-geltung-label">Wahlperiode:</span>
{{ geltung_kontext.legislatur.wp }}.&nbsp;Wahlperiode
({{ geltung_kontext.legislatur.konstituierung }}{% if geltung_kontext.legislatur.ende %} bis {{ geltung_kontext.legislatur.ende }}{% else %} laufend{% endif %})
</div>
{% endif %}
{% if geltung_kontext.regierung %}
<div>
<span class="v3-geltung-label">Regierung zur Antragszeit:</span>
{{ geltung_kontext.regierung.name }} ({{ geltung_kontext.regierung.parteien | join("+") }}),
vereidigt {{ geltung_kontext.regierung.von }}{% if geltung_kontext.regierung.bis %}, abgelöst {{ geltung_kontext.regierung.bis }}{% endif %}
</div>
{% endif %}
{% if geltung_kontext.programme %}
<div>
<span class="v3-geltung-label">Bewertet gegen die folgenden Wahlprogramme:</span>
<ul class="v3-geltung-list">
{% for p in geltung_kontext.programme %}
<li>
<strong>{{ p.partei }}:</strong>
{% if p.pdf %}
<a href="/static/referenzen/{{ p.pdf }}" target="_blank" rel="noopener" class="v3-geltung-pdf">{{ p.titel }}</a>
{% else %}
{{ p.titel }}
{% endif %}
<span class="v3-geltung-gueltig">— gültig seit {{ p.gueltig_ab }}{% if p.gueltig_bis %} bis {{ p.gueltig_bis }}{% endif %}{% if p.seiten %}, {{ p.seiten }} S.{% endif %}</span>
</li>
{% endfor %}
</ul>
</div>
{% endif %}
{% if antrag.analysiert or antrag.modell %}
<div class="v3-geltung-snapshot">
Diese Bewertung wurde
{% if antrag.analysiert %}am <strong>{{ antrag.analysiert }}</strong>{% endif %}
{% if antrag.modell %} mit <strong>{{ antrag.modell }}</strong>{% endif %}
gegen den oben genannten Programm-Stand erzeugt.
</div>
{% endif %}
</div>
</section>
{% endif %}
{# 6 ── Programm-Treue — wird komplett ausgeblendet wenn ALLE
Fraktionen ohne Programm sind (typisch bei Bundestags-Antraegen,
wo aktuell keine Programme indiziert sind), sonst werden nur
die einzelnen Fraktionen ohne Programm gefiltert. #}
{% if antrag.fraktions_scores %}
{% set _missing_set = (antrag.fehlende_programme or []) | map('lower') | list %}
{% set _all_missing = antrag.fehlende_programme and (antrag.fraktions_scores | length == antrag.fehlende_programme | length) %}
{% if _all_missing %}
<section class="v3-section">
<h3 class="v3-h3">Programm-Treue pro Fraktion</h3>
<div class="v3-disclaimer">
<strong>Programm-Treue nicht verfügbar.</strong>
Für dieses Parlament ({{ antrag.bundesland }}) sind aktuell keine Wahl- und
Parteiprogramme indiziert. Eine inhaltliche Bewertung gegen die einzelnen
Programme ist damit nicht möglich; die Programm-Treue-Sektion wird nicht
angezeigt, um halluzinierte Scores zu vermeiden.
</div>
</section>
{% else %}
<section class="v3-section">
<h3 class="v3-h3">Programm-Treue pro Fraktion</h3>
{% if antrag.fehlende_programme %}
<div class="v3-disclaimer">
<strong>Hinweis:</strong> Für folgende Parteien lag kein Wahl-/Parteiprogramm vor — sie werden hier nicht aufgeführt:
{{ antrag.fehlende_programme | join(", ") }}.
</div>
{% endif %}
<div class="v3-fraktionen">
{% for fs in antrag.fraktions_scores %}
{% if fs.fraktion | lower not in _missing_set %}
<div class="v3-fraktion">
<div class="v3-fraktion-row">
<span class="v3-fraktion-name">{{ fs.fraktion }}</span>
{% if fs.ist_antragsteller %}<span class="v3-pill v3-pill-antrag">Antragsteller:in</span>{% endif %}
{% if fs.ist_regierung %}<span class="v3-pill v3-pill-reg">Regierungsfraktion</span>{% endif %}
<span class="v3-fraktion-spacer"></span>
{% for prog_key, prog_label, prog_short in [("wahlprogramm","Wahlprogramm","WP"),("parteiprogramm","Parteiprogramm","PP")] %}
{% set p = fs[prog_key] %}
{% set p_score = p.score | float %}
<details class="v3-prog">
<summary class="v3-prog-pill" title="{{ prog_label }}">
<span class="v3-prog-pill-label">{{ prog_short }}</span>
<span class="v3-prog-score
{% if p_score >= 7 %}good{% elif p_score >= 4 %}mid{% else %}low{% endif %}">{{ "%.0f"|format(p_score) }}/10</span>
</summary>
<div class="v3-prog-body">
{% if p.begruendung %}<p class="v3-prog-text"><strong>{{ prog_label }}:</strong> {{ p.begruendung }}</p>{% endif %}
{% if p.zitate %}
<div class="v3-prog-zitate">
{% for z in p.zitate %}
{{ quote_card(z.text, z.source, True, False, z.pdf_href) }}
{% endfor %}
</div>
{% else %}
<p class="v3-prog-no-zitate">
Keine wörtlich passenden Stellen im {{ prog_label }} gefunden.
Die Bewertung beruht auf inhaltlicher Auslegung — entweder benennt das Programm
das konkrete Thema nicht explizit, oder es bleibt zu allgemein, um wörtlich
zugeordnet zu werden.
</p>
{% endif %}
</div>
</details>
{% endfor %}
</div>
</div>
{% endif %}{# fraktion nicht in fehlende_programme #}
{% endfor %}
</div>
</section>
{% endif %}{# _all_missing-else #}
{% endif %}{# fraktions_scores #}
{# 7 ── Verbesserungsvorschläge — volle Breite, nicht kollabiert ───── #}
{% if antrag.verbesserungen %}
<section class="v3-section v3-verbesserungen">
<h3 class="v3-h3">Verbesserungsvorschläge</h3>
{% for v in antrag.verbesserungen %}
<div class="v3-verbesserung">
{% if antrag.verbesserungen | length > 1 %}
<div class="v3-verbesserung-num">Vorschlag {{ loop.index }} von {{ antrag.verbesserungen | length }}</div>
{% endif %}
{% 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 class="v3-verbesserung-begr">{{ v.begruendung }}</p>
{% endif %}
</div>
{% endfor %}
</section>
{% elif antrag.redline and antrag.redline.segments %}
<section class="v3-section v3-verbesserungen">
<h3 class="v3-h3">Verbesserungsvorschlag</h3>
{{ redline(segments=antrag.redline.segments) }}
</section>
{% endif %}
{# 8 ── Abstimmungsergebnis (Plenum + namentlich) ──────────────────── #}
{% if antrag.plenum_votes %}
<section class="v3-section v3-vote-section">
<h3 class="v3-h3">Abstimmungsergebnis</h3>
{# Konsistenz-Hinweis: GWÖ-Empfehlung vs tatsaechlicher Beschluss #}
{% set _state = consistency_state(antrag.verdict_title, antrag.plenum_votes) %}
{% set _decisive = decisive_outcome(antrag.plenum_votes) %}
{% if _state %}
<div class="v3-konsistenz {{ _state }}">
<strong>{% if _state == 'conflict' %}Mehrheit gegen GWÖ-Empfehlung{% else %}Mehrheit deckt sich mit GWÖ-Empfehlung{% endif %}</strong>
— Empfohlen: <em>{{ antrag.verdict_title }}</em>; Beschluss: <em>{{ _decisive | capitalize }}</em>.
</div>
{% endif %}
{% set ergebnis_color = {
"angenommen":"#2da44e","abgelehnt":"#cf222e","überwiesen":"#0969da",
"zurückgezogen":"#8250df","bestätigt":"#2da44e","sammel":"#0969da",
} %}
{% for v in antrag.plenum_votes %}
<div class="v3-vote-card">
<div class="v3-vote-card-head">
<span class="v3-vote-ergebnis" style="color:{{ ergebnis_color.get(v.ergebnis, '#6e7781') }};">
{{ v.ergebnis | capitalize }}{% if v.einstimmig %} · einstimmig{% endif %}
</span>
{% if v.quelle_url %}
<a href="{{ v.quelle_url }}" target="_blank" rel="noopener" class="v3-vote-quelle"
title="Plenarprotokoll im neuen Tab öffnen">
{{ v.quelle_protokoll }} ↗
</a>
{% else %}
<span class="v3-vote-quelle">{{ v.quelle_protokoll }}</span>
{% endif %}
</div>
{% if v.fraktionen_ja or v.fraktionen_nein or v.fraktionen_enthaltung %}
{% set _n_ja = v.fraktionen_ja | length %}
{% set _n_nein = v.fraktionen_nein | length %}
{% set _n_enth = v.fraktionen_enthaltung | length %}
{% set _n_total = _n_ja + _n_nein + _n_enth %}
{% if _n_total > 0 %}
<div class="v3-vote-bar"
title="Fraktions-Mehrheit: {{ _n_ja }} Ja · {{ _n_nein }} Nein · {{ _n_enth }} Enth.">
{% if _n_ja %}<div class="v3-vote-bar-ja" style="width:{{ (100 * _n_ja / _n_total) }}%;"></div>{% endif %}
{% if _n_enth %}<div class="v3-vote-bar-enth" style="width:{{ (100 * _n_enth / _n_total) }}%;"></div>{% endif %}
{% if _n_nein %}<div class="v3-vote-bar-nein" style="width:{{ (100 * _n_nein / _n_total) }}%;"></div>{% endif %}
</div>
<div class="v3-vote-bar-caption">
{{ _n_ja }}/{{ _n_total }} Fraktionen Ja · {{ _n_nein }} Nein · {{ _n_enth }} Enth.
</div>
{% endif %}
<div class="v3-vote-pills">
{% if v.fraktionen_ja %}
<div><span class="v3-vote-side ja">Ja:</span>
{% for f in v.fraktionen_ja %}
{% set _opp = opportunismus_score(f, antrag.fraktions_scores) %}
<span class="v3-vote-pill ja">{{ f }}{% if _opp is not none %}<span class="v3-marker opp" tabindex="0" role="button" title="Wahlprogramm-Konflikt — Diese Fraktion stimmte mit Ja, obwohl der Antrag schlecht zum eigenen Wahlprogramm passt (Wahlprogramm-Score {{ '%.0f' | format(_opp) }}/10). Wissenschaftliche Klassifikation: Opportunismus-Indikator.">!</span>{% endif %}</span>
{% endfor %}
</div>
{% endif %}
{% if v.fraktionen_nein %}
<div><span class="v3-vote-side nein">Nein:</span>
{% for f in v.fraktionen_nein %}
{% set _wp = heuchelei_score(f, antrag.fraktions_scores) %}
<span class="v3-vote-pill nein">{{ f }}{% if _wp is not none %}<span class="v3-marker heuchelei" tabindex="0" role="button" title="Wahlprogramm-Konflikt — Diese Fraktion stimmte mit Nein, obwohl der Antrag inhaltlich gut zum eigenen Wahlprogramm passt (Wahlprogramm-Score {{ '%.0f' | format(_wp) }}/10). Wissenschaftliche Klassifikation: Heuchelei-Indikator."></span>{% endif %}</span>
{% endfor %}
</div>
{% endif %}
{% if v.fraktionen_enthaltung %}
<div><span class="v3-vote-side enth">Enth.:</span>
{% for f in v.fraktionen_enthaltung %}<span class="v3-vote-pill enth">{{ f }}</span>{% endfor %}
</div>
{% endif %}
</div>
{% endif %}
</div>
{% endfor %}
<div class="v3-vote-source">Quelle: Plenarprotokoll · automatisch extrahiert</div>
</section>
{% endif %}
{% if antrag.abstimmungsverhalten %}
{% set aw = antrag.abstimmungsverhalten %}
<section class="v3-section">
<h3 class="v3-h3">Namentliche Abstimmung</h3>
<div class="v3-namentlich">
<div>{{ aw.protokoll | default("") }}{% if aw.datum %} · {{ aw.datum }}{% endif %}</div>
{% if aw.abstimmung %}
<div>{{ aw.abstimmung.ja | default(0) }} Ja · {{ aw.abstimmung.nein | default(0) }} Nein · {{ aw.abstimmung.enthaltung | default(0) }} Enthaltung</div>
{% endif %}
</div>
</section>
{% endif %}
{# ════════════════ 9 ── REST-Block ════════════════════════════════════ #}
<section class="v3-rest">
{# Ähnliche Anträge — per JS via /api/assessment/similar geladen #}
<div class="v3-rest-block v3-similar" id="v3-similar-box" data-drucksache="{{ antrag.drucksache | e }}">
<h3 class="v3-h3">Ähnliche Anträge</h3>
<div id="v3-similar-list">
<span class="v3-loading">Lade …</span>
</div>
</div>
{# Teilen — nur fuer angemeldete User; initAuth() blendet via #v2-share-block ein. #}
<div id="v2-share-block" class="v3-rest-block v3-rest-divider-top" style="display:none;">
<h3 class="v3-h3">Teilen</h3>
<div class="v3-share-buttons">
<button onclick="v2DetailShareCopy()" class="v3-action-btn">📋 Kopieren</button>
<button onclick="v2DetailShare('threads')" class="v3-action-btn">Threads</button>
<button onclick="v2DetailShareMastodon()" class="v3-action-btn">Mastodon</button>
<button onclick="v2DetailShare('linkedin')" class="v3-action-btn">LinkedIn</button>
<button onclick="v2DetailShareInstagram()" class="v3-action-btn">📷 Instagram</button>
<button onclick="v2DetailShareEmail()" class="v3-action-btn">📧 E-Mail</button>
<button onclick="v2DetailShareScorecard()" class="v3-action-btn">📊 Scorecard ansehen</button>
<button onclick="v2DetailShareImage()" class="v3-action-btn" title="Stockphoto-Suche bei Magnific zum Antragsthema">🖼 Stock-Bild</button>
</div>
</div>
{# Aktions-Links: PDF, Original, JSON, Permalink — unter Teilen #}
<div class="v3-rest-aktions v3-rest-divider-top">
<a href="/api/assessment/pdf?drucksache={{ antrag.drucksache | urlencode }}">PDF-Bericht</a>
{% if antrag.link %}
<a href="{{ antrag.link }}" target="_blank" rel="noopener">Original-Antrag (Landtag)</a>
{% endif %}
<a href="/api/assessment?drucksache={{ antrag.drucksache | urlencode }}">JSON-Export</a>
<a href="/antrag/{{ antrag.drucksache }}"
onclick="v3CopyPermalink(event, this)"
data-copied-label="Permalink kopiert ✓">Permalink kopieren</a>
</div>
{# News-Box (per JS gefuellt) — eine Nachricht, max 9 Zeilen #}
<div id="ad-news-box" class="v3-news-box" style="display:none;">
<h3 class="v3-h3">Aktuelle News passend zu diesem Antrag</h3>
<p class="v3-news-meta">Embedding-Match aus den letzten 90 Tagen. Quelle: Tagesschau-API + Bundestag-RSS.</p>
<div id="ad-news-list">
<div class="v3-loading">Lade …</div>
</div>
</div>
{# Neu analysieren #}
<div class="v3-rest-block">
<button id="v2-reanalyze-btn" onclick="v2DetailReAnalyze(this)" class="v3-action-btn v3-action-muted">
Neu analysieren
</button>
</div>
{# 9d Bewertungs-Historie #}
<div class="v3-rest-block">
<h3 class="v3-h3">Bewertungs-Historie</h3>
<div id="v2-history-list">
<span class="v3-loading">Lade…</span>
</div>
</div>
{# 9i Kommentare #}
<div class="v3-rest-block v3-comments">
<h3 class="v3-h3">Kommentare</h3>
<div id="v2-comments-list">
<span class="v3-loading">Lade…</span>
</div>
<div id="v2-comment-form" style="display:none;">
<div class="v3-comment-label">Kommentar hinzufügen</div>
<textarea id="v2-comment-input" rows="3" placeholder="Kommentar…" class="v3-comment-textarea"></textarea>
<div class="v3-comment-controls">
<select id="v2-comment-visibility" class="v3-comment-vis">
<option value="all">Öffentlich</option>
<option value="authenticated">Nur Angemeldete</option>
<option value="private">Nur ich</option>
</select>
<button onclick="v2DetailAddComment('{{ antrag.drucksache | e }}')" class="v3-action-btn primary">Absenden</button>
</div>
</div>
<div id="v2-comment-login-hint" style="display:none;">
<button onclick="v2AuthModalOpen()" class="v3-action-btn">Anmelden um zu kommentieren</button>
</div>
</div>
</section>{# v3-rest #}
{# ════════════════ Modals ═════════════════════════════════════════════ #}
{# Matrix-Feld-Info-Modal — gleiche IDs wie v2, JS aus super() greift #}
<div id="v2-matrix-field-modal"
role="dialog" aria-modal="true" aria-label="Matrix-Feld Erklärung"
class="v3-modal"
onclick="if(event.target===this)this.style.display='none'">
<div class="v3-modal-card">
<div class="v3-modal-head">
<strong id="v2-matrix-field-title" class="v3-modal-title"></strong>
<span id="v2-matrix-field-rating" class="v3-modal-rating"></span>
<button onclick="document.getElementById('v2-matrix-field-modal').style.display='none'"
class="v3-modal-close" aria-label="Schließen">×</button>
</div>
<div id="v2-matrix-field-antrag" class="v3-modal-section" style="display:none;">
<div class="v3-modal-sublabel">Bewertung in diesem Antrag</div>
<div id="v2-matrix-field-label" class="v3-modal-itemlabel"></div>
<div id="v2-matrix-field-aspect" class="v3-modal-itemtext"></div>
</div>
<div class="v3-modal-section v3-modal-section--bordered">
<div class="v3-modal-sublabel">Was misst dieses Feld?</div>
<p id="v2-matrix-field-text" class="v3-modal-itemtext"></p>
</div>
</div>
</div>
</div>{# .v3-page #}
{% endif %}{# antrag #}
{% endblock %}
{% block body_scripts %}
{{ super() }}
<script>
/* Ähnliche Anträge: /api/assessment/similar?drucksache=…&top_k=5 */
(async function () {
var box = document.getElementById('v3-similar-box');
if (!box) return;
var drs = box.dataset.drucksache;
var list = document.getElementById('v3-similar-list');
try {
var resp = await fetch('/api/assessment/similar?drucksache=' + encodeURIComponent(drs) + '&top_k=5');
var data = await resp.json();
var items = (data && data.results) || data || [];
if (!Array.isArray(items) || items.length === 0) {
list.innerHTML = '<span class="v3-loading">Keine ähnlichen Anträge gefunden.</span>';
return;
}
list.innerHTML = items.map(function (it) {
var sim = (it.similarity != null) ? Math.round(it.similarity * 100) + '%' : '';
var bl = it.bundesland || '';
var drs = it.drucksache || '';
var title = it.title || '';
var score = (it.gwoe_score != null) ? it.gwoe_score.toFixed(1) : '';
return '<a href="/v3/antrag/' + encodeURIComponent(drs) + '" class="v3-similar-item">'
+ '<div class="v3-similar-meta">' + bl + (drs ? ' · Drs. ' + drs : '') + (sim ? ' · ' + sim + ' ähnlich' : '') + '</div>'
+ '<div class="v3-similar-title">' + title + '</div>'
+ (score ? '<div class="v3-similar-score">Score ' + score + '/10</div>' : '')
+ '</a>';
}).join('');
} catch (e) {
list.innerHTML = '<span class="v3-loading">Konnte ähnliche Anträge nicht laden.</span>';
}
})();
</script>
{% endblock %}