feat(tour): Welcome-Banner + Tour auf Startseite, Logo-Klick zur Startseite
Drei zusammenhängende UI-Bausteine:
1) Tour-Engine ist jetzt page-agnostisch — sie liest die Stationen aus
``window.GWOE_TOUR_STEPS`` (pro Page hinterlegt), nicht mehr aus einem
eingebauten Konstanten. Tour-Komponente wird per ``{% include %}``
eingehängt; das Page-Template definiert vorher seine eigenen Steps.
Antrag-Detail-Tour wurde entsprechend in das eigene Template gezogen.
2) Startseite (v2/screens/durchsuchen.html): „Du bist neu hier?"-Banner
oben mit zwei Buttons — „🧭 Tour starten" und „Nein, danke". Banner
bleibt sichtbar, bis explizit weggeklickt wird (localStorage-Flag),
oder die Tour gestartet wird. Fünf Stationen für die Startseite:
Marken-Block, Suche, Score-Filter + Sortierung, Antrags-Liste,
linke Navigation.
3) Logo-Klick führt jetzt zur Startseite — sowohl in v2/base.html als
auch in components/appshell.html. ``v2-brand`` und ``v2-brand-sub``
sind in einen ``<a href="/">`` mit Hover-Highlight gewickelt
(``.v2-brand-link``).
Phase 2 (ElevenLabs-Voice) ist der nächste Schritt — bisher läuft das
Audio über die Web Speech API.
This commit is contained in:
parent
1c74cb8801
commit
e31ee1ad07
@ -134,6 +134,16 @@ body.v2 :focus-visible {
|
||||
height: 100vh;
|
||||
}
|
||||
|
||||
.v2-brand-link {
|
||||
display: block;
|
||||
text-decoration: none;
|
||||
color: inherit;
|
||||
}
|
||||
.v2-brand-link:hover .v2-brand,
|
||||
.v2-brand-link:focus-visible .v2-brand {
|
||||
color: var(--ecg-teal);
|
||||
}
|
||||
|
||||
.v2-brand {
|
||||
font-family: var(--font-sans);
|
||||
font-weight: 900;
|
||||
@ -142,6 +152,7 @@ body.v2 :focus-visible {
|
||||
color: var(--ecg-dark);
|
||||
letter-spacing: 0;
|
||||
line-height: 1.05;
|
||||
transition: color 0.12s ease;
|
||||
}
|
||||
|
||||
.v2-brand .grn { color: var(--ecg-green); }
|
||||
|
||||
@ -25,10 +25,12 @@
|
||||
<div class="v2-shell">
|
||||
|
||||
<aside id="v2-sidebar" class="v2-sidebar">
|
||||
<a href="/" class="v2-brand-link" aria-label="GWÖ-Antragsprüfer · Startseite">
|
||||
<div class="v2-brand">
|
||||
GWÖ-<span class="grn">ANTRAGS</span><span class="blu">PRÜFER</span>
|
||||
</div>
|
||||
<div class="v2-brand-sub">Matrix 2.0 · Gemeinden</div>
|
||||
</a>
|
||||
|
||||
<nav aria-label="Hauptnavigation">
|
||||
<div class="v2-nav-group">
|
||||
|
||||
@ -16,10 +16,12 @@
|
||||
|
||||
{# ── Sidebar ──────────────────────────────────────────────────── #}
|
||||
<aside id="v2-sidebar" class="v2-sidebar">
|
||||
<a href="/" class="v2-brand-link" aria-label="GWÖ-Antragsprüfer · Startseite">
|
||||
<div class="v2-brand">
|
||||
GWÖ-<span class="grn">ANTRAGS</span><span class="blu">PRÜFER</span>
|
||||
</div>
|
||||
<div class="v2-brand-sub">Matrix 2.0 · Gemeinden</div>
|
||||
</a>
|
||||
|
||||
<nav aria-label="Hauptnavigation">
|
||||
|
||||
|
||||
@ -9,6 +9,20 @@
|
||||
|
||||
{% block main %}
|
||||
|
||||
{# ── Welcome-Banner: Tour-Einstieg für Erst-Besucher:innen (#185) ── #}
|
||||
<div id="gwoe-welcome-banner" class="v2-kasten outline-blue gwoe-welcome-banner" hidden>
|
||||
<div class="gwoe-welcome-text">
|
||||
<strong>Du bist neu hier?</strong>
|
||||
Soll ich dir die Seite erklären? Eine geführte Tour mit Sprachausgabe — du kannst sie jederzeit abbrechen.
|
||||
</div>
|
||||
<div class="gwoe-welcome-actions">
|
||||
<button type="button" onclick="gwoeTourStart()" class="v2-chip primary"
|
||||
id="gwoe-welcome-start">🧭 Tour starten</button>
|
||||
<button type="button" onclick="gwoeWelcomeDismiss()" class="v2-chip"
|
||||
id="gwoe-welcome-dismiss">Nein, danke</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{# ── Toolbar: Suche ──────────────────────────────────────────────── #}
|
||||
{# BL-Filter läuft jetzt über den globalen Selector in der Topbar. #}
|
||||
<div class="v2-toolbar" id="v2-toolbar" role="toolbar" aria-label="Filter und Suche">
|
||||
@ -69,6 +83,28 @@
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{# ── Tour-Stationen für die Startseite + Engine-Include ──────────── #}
|
||||
<script>
|
||||
window.GWOE_TOUR_STEPS = [
|
||||
{ selector: '.v2-brand-link, .v2-brand',
|
||||
title: 'Willkommen beim GWÖ-Antragsprüfer',
|
||||
text: 'Diese Seite bewertet Anträge aus deutschen Parlamenten nach der Gemeinwohl-Matrix. Was sie auszeichnet: Sie schaut nicht nur, ob ein Antrag „gut klingt", sondern wie sehr er fünf Werten dient — Würde, Solidarität, Nachhaltigkeit, Gerechtigkeit und Demokratie.' },
|
||||
{ selector: '#v2-search-input',
|
||||
title: 'Anträge durchsuchen',
|
||||
text: 'Hier findest du Anträge nach Stichwort, Drucksachen-Nummer oder Antragstellerin. Die Liste filtert sich beim Tippen mit.' },
|
||||
{ selector: '.v2-toolbar:nth-of-type(2), [data-band]',
|
||||
title: 'Filter nach Note',
|
||||
text: 'Mit diesen Knöpfen filterst du nach Gemeinwohl-Note. Acht bis Zehn sind vorbildlich, fünf bis sieben durchwachsen, null bis vier problematisch. Daneben kannst du nach Datum, Score oder Titel sortieren.' },
|
||||
{ selector: '#v2-results .v2-result-row, #v2-results',
|
||||
title: 'Die Antrags-Liste',
|
||||
text: 'Jede Karte zeigt einen Antrag mit seiner Note. Klick auf eine Karte öffnet die ausführliche Bewertung — dort wirst du dort dann auch noch eine eigene Tour finden, die das Detail erklärt.' },
|
||||
{ selector: '.v2-nav-group, #v2-sidebar nav',
|
||||
title: 'Navigation links',
|
||||
text: 'Links findest du weitere Sichten. „Auswertungen" zeigt Aggregate über alle Anträge, „Stimmverhalten" die Konsistenz jeder Fraktion zwischen Wahlprogramm und tatsächlicher Stimme, „Quellen" alle indizierten Wahl- und Grundsatzprogramme — semantisch durchsuchbar.' },
|
||||
];
|
||||
</script>
|
||||
{% include "v3/components/tour.html" %}
|
||||
|
||||
{% endblock %}
|
||||
|
||||
{% block body_scripts %}
|
||||
@ -319,5 +355,57 @@ kbd {
|
||||
padding: 1px 5px;
|
||||
color: var(--ecg-dark);
|
||||
}
|
||||
|
||||
.gwoe-welcome-banner {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 16px;
|
||||
flex-wrap: wrap;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
.gwoe-welcome-banner[hidden] { display: none !important; }
|
||||
.gwoe-welcome-text {
|
||||
flex: 1 1 320px;
|
||||
font-size: 13px;
|
||||
line-height: 1.5;
|
||||
color: var(--ecg-dark);
|
||||
}
|
||||
.gwoe-welcome-actions {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
align-items: center;
|
||||
}
|
||||
.v2-chip.primary {
|
||||
background: var(--ecg-teal);
|
||||
color: #fff;
|
||||
border-color: var(--ecg-teal);
|
||||
}
|
||||
.v2-chip.primary:hover { opacity: 0.92; }
|
||||
</style>
|
||||
|
||||
<script>
|
||||
/* Welcome-Banner sichtbar bis Tour gestartet oder „Nein, danke".
|
||||
localStorage: 'gwoe_welcome_dismissed' = '1' merkt den Schließ-Klick. */
|
||||
(function () {
|
||||
var KEY = 'gwoe_welcome_dismissed';
|
||||
var banner = document.getElementById('gwoe-welcome-banner');
|
||||
if (!banner) return;
|
||||
if (localStorage.getItem(KEY) !== '1') {
|
||||
banner.hidden = false;
|
||||
}
|
||||
window.gwoeWelcomeDismiss = function () {
|
||||
try { localStorage.setItem(KEY, '1'); } catch (_) {}
|
||||
banner.hidden = true;
|
||||
};
|
||||
// Wenn Tour gestartet wird, Banner auch wegblenden + dismissed merken.
|
||||
var origStart = window.gwoeTourStart;
|
||||
if (typeof origStart === 'function') {
|
||||
window.gwoeTourStart = function () {
|
||||
try { localStorage.setItem(KEY, '1'); } catch (_) {}
|
||||
banner.hidden = true;
|
||||
return origStart.apply(this, arguments);
|
||||
};
|
||||
}
|
||||
})();
|
||||
</script>
|
||||
{% endblock %}
|
||||
|
||||
@ -1,16 +1,20 @@
|
||||
{# ─────────────────────────────────────────────────────────────────────
|
||||
Geführte Tour durch das Antrag-Detail (#185).
|
||||
Geführte Tour-Engine (#185).
|
||||
|
||||
Was diese Komponente liefert:
|
||||
- "Tour"-Button rendert in der userrow (siehe antrag_detail.html)
|
||||
- Vier Stationen: Score-Hero, Matrix, Programm-Treue, Stimmverhalten
|
||||
- Spotlight-Overlay (Klick außerhalb → Tour-Ende)
|
||||
- Erklärblase mit Vor / Zurück / Schließen
|
||||
- Audio: Web Speech API (Browser-eingebaute Stimme), de-DE,
|
||||
stoppbar bei Schritt-Wechsel und Schließen.
|
||||
- Spotlight-Overlay + Erklärblase + Vor/Zurück/Schließen + Mute
|
||||
- Audio via Web Speech API (de-DE, möglichst weiblich)
|
||||
- Engine: liest pro Page hinterlegte ``window.GWOE_TOUR_STEPS``
|
||||
(Liste mit ``{selector, title, text}``), zeigt nur Stationen
|
||||
deren Element wirklich da ist.
|
||||
|
||||
Stand: Phase 1 — Browser-TTS. Phase 2 (ElevenLabs) kommt separat
|
||||
und tauscht nur das Audio-Backend; das Tour-Skript bleibt gleich.
|
||||
Pro Page:
|
||||
<script>window.GWOE_TOUR_STEPS = [{selector: '...', title: '...', text: '...'}];</script>
|
||||
{% include "v3/components/tour.html" %}
|
||||
<button onclick="gwoeTourStart()">Tour starten</button>
|
||||
|
||||
Phase 1: Browser-TTS. Phase 2 (ElevenLabs) tauscht nur das
|
||||
Audio-Backend; das Tour-Skript bleibt gleich.
|
||||
───────────────────────────────────────────────────────────────────── #}
|
||||
<div id="gwoe-tour-overlay" class="gwoe-tour-overlay" hidden aria-hidden="true">
|
||||
<div id="gwoe-tour-spotlight" class="gwoe-tour-spotlight"></div>
|
||||
@ -136,31 +140,13 @@
|
||||
|
||||
<script>
|
||||
(function () {
|
||||
// Tour-Skript: 4 Stationen. Selectoren werden zur Laufzeit aufgelöst —
|
||||
// wenn ein Element fehlt (z.B. keine Plenum-Votes), überspringt die
|
||||
// Tour den Schritt automatisch.
|
||||
const STEPS = [
|
||||
{
|
||||
selector: '.v3-bewertung',
|
||||
title: 'Die Gemeinwohl-Note',
|
||||
text: 'Diese große Zahl ist die Gemeinwohl-Note. Null ist destruktiv, Zehn vorbildlich. Sie zeigt, wie sehr der Antrag dem Allgemeinwohl dient. Daneben steht die Empfehlung — Unterstützen, Überarbeiten oder Ablehnen.',
|
||||
},
|
||||
{
|
||||
selector: '.v3-matrix-grid, .v3-matrix, [class*="matrix"]',
|
||||
title: 'Die Gemeinwohl-Matrix',
|
||||
text: 'Dieses Raster prüft fünf Werte: Würde, Solidarität, Nachhaltigkeit, Gerechtigkeit und Demokratie. Pro Wert wird geschaut, wie der Antrag fünf Berührungsgruppen betrifft — von Lieferanten bis zur Gesellschaft als Ganzes. Grün heißt: der Antrag fördert diesen Wert. Rot: er widerspricht ihm.',
|
||||
},
|
||||
{
|
||||
selector: '.v3-fraktionen',
|
||||
title: 'Programm-Treue pro Fraktion',
|
||||
text: 'Hier sehen Sie, wie gut der Antrag zum Wahl- und Parteiprogramm jeder Fraktion passt. Die Zahl rechts ist der Programm-Score von Null bis Zehn. Ein Klick darauf zeigt die Begründung mit Zitaten aus dem Programm.',
|
||||
},
|
||||
{
|
||||
selector: '.v3-vote-section',
|
||||
title: 'Stimmverhalten und Marker',
|
||||
text: 'Hier sehen Sie, wie die Fraktionen tatsächlich abgestimmt haben. Das Warnschild neben einer Fraktion bedeutet Heuchelei: Sie stimmt mit Nein, obwohl der Antrag exakt zu ihrem eigenen Wahlprogramm passt. Das Ausrufezeichen markiert Opportunismus: Ja-Stimme bei einem Antrag, der dem eigenen Programm widerspricht.',
|
||||
},
|
||||
];
|
||||
// Tour-Stationen kommen pro Page via window.GWOE_TOUR_STEPS.
|
||||
// Jeder Eintrag: {selector, title, text}. Selectoren werden zur Laufzeit
|
||||
// aufgelöst — fehlt das Element (z.B. keine Plenum-Votes auf einer
|
||||
// bestimmten Drucksache), überspringt die Tour den Schritt automatisch.
|
||||
function getSteps() {
|
||||
return Array.isArray(window.GWOE_TOUR_STEPS) ? window.GWOE_TOUR_STEPS : [];
|
||||
}
|
||||
|
||||
let _tourIdx = 0;
|
||||
let _resolvedSteps = []; // STEPS gefiltert auf vorhandene Elemente
|
||||
@ -197,7 +183,7 @@
|
||||
|
||||
function resolveSteps() {
|
||||
_resolvedSteps = [];
|
||||
for (const s of STEPS) {
|
||||
for (const s of getSteps()) {
|
||||
// Erstes Match aus comma-separated Selector-Liste.
|
||||
const parts = s.selector.split(',').map(x => x.trim());
|
||||
let el = null;
|
||||
|
||||
@ -548,6 +548,23 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{# Tour-Stationen für Antrag-Detail (Engine im include unten) #}
|
||||
<script>
|
||||
window.GWOE_TOUR_STEPS = [
|
||||
{ selector: '.v3-bewertung',
|
||||
title: 'Die Gemeinwohl-Note',
|
||||
text: 'Diese große Zahl ist die Gemeinwohl-Note. Null ist destruktiv, Zehn vorbildlich. Sie zeigt, wie sehr der Antrag dem Allgemeinwohl dient. Daneben steht die Empfehlung — Unterstützen, Überarbeiten oder Ablehnen.' },
|
||||
{ selector: '.v3-matrix-grid, .v3-matrix, [class*="matrix"]',
|
||||
title: 'Die Gemeinwohl-Matrix',
|
||||
text: 'Dieses Raster prüft fünf Werte: Würde, Solidarität, Nachhaltigkeit, Gerechtigkeit und Demokratie. Pro Wert wird geschaut, wie der Antrag fünf Berührungsgruppen betrifft — von Lieferanten bis zur Gesellschaft als Ganzes. Grün heißt: der Antrag fördert diesen Wert. Rot: er widerspricht ihm.' },
|
||||
{ selector: '.v3-fraktionen',
|
||||
title: 'Programm-Treue pro Fraktion',
|
||||
text: 'Hier sehen Sie, wie gut der Antrag zum Wahl- und Parteiprogramm jeder Fraktion passt. Die Zahl rechts ist der Programm-Score von Null bis Zehn. Ein Klick darauf zeigt die Begründung mit Zitaten aus dem Programm.' },
|
||||
{ selector: '.v3-vote-section',
|
||||
title: 'Stimmverhalten und Marker',
|
||||
text: 'Hier sehen Sie, wie die Fraktionen tatsächlich abgestimmt haben. Das Warnschild neben einer Fraktion bedeutet Heuchelei: Sie stimmt mit Nein, obwohl der Antrag exakt zu ihrem eigenen Wahlprogramm passt. Das Ausrufezeichen markiert Opportunismus: Ja-Stimme bei einem Antrag, der dem eigenen Programm widerspricht.' },
|
||||
];
|
||||
</script>
|
||||
{% include "v3/components/tour.html" %}
|
||||
|
||||
</div>{# .v3-page #}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user