feat: collapse results into progressive-disclosure panels
Wrap Recommendations (scenario tabs + cards), Budget, and Timeline in <details> accordions. Recommendations stays open by default; Budget and Timeline collapse closed so the post-quiz page doesn't dump everything at once. The panel becomes the white-paint container — inner .budget-meter, .timeline, and .scenario-tabs drop their own box treatment to avoid a nested-card look. revealSections() now staggers the panel wrappers instead of the inner containers, and added en/de strings for the panel headers. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
82
src/App.vue
82
src/App.vue
@@ -458,20 +458,47 @@
|
||||
<div style="font-size:11px;color:var(--muted);margin-top:12px;text-align:center;line-height:1.7" data-i18n="privacy_note">🔒 Your data is never sold. Unsubscribe anytime. GDPR compliant.</div>
|
||||
</div>
|
||||
|
||||
<!-- RECOMMENDATIONS + SCENARIO TABS -->
|
||||
<!-- RECOMMENDATIONS + SCENARIO TABS — collapsible panels -->
|
||||
<div id="recs-anchor"></div>
|
||||
<div id="budget-meter-container" class="reveal-section"></div>
|
||||
<div class="scenario-tabs reveal-section" id="scenario-tabs">
|
||||
<button class="s-tab" id="stab-1" data-s="1" @click="showScenario(1)"><span data-i18n="tab_s1">💀 Total</span></button>
|
||||
<button class="s-tab" id="stab-2" data-s="2" @click="showScenario(2)"><span data-i18n="tab_s2">⚠️ Partial</span></button>
|
||||
<button class="s-tab" id="stab-3" data-s="3" @click="showScenario(3)"><span data-i18n="tab_s3">📈 Inflation</span></button>
|
||||
<button class="s-tab" id="stab-4" data-s="4" @click="showScenario(4)"><span data-i18n="tab_s4">🌿 Food</span></button>
|
||||
</div>
|
||||
<div class="rec-cards reveal-section" id="rec-cards-container"></div>
|
||||
<div class="timeline reveal-section" id="timeline-container">
|
||||
<div class="tl-title" data-i18n="timeline_title">⏱ Your Action Timeline</div>
|
||||
<div class="tl-items" id="timeline-items"></div>
|
||||
</div>
|
||||
|
||||
<details class="result-panel reveal-section" id="panel-recs" open>
|
||||
<summary class="result-panel-header">
|
||||
<span class="rp-title" data-i18n="panel_recs">📋 Your Recommendations</span>
|
||||
<span class="rp-hint" data-i18n="panel_recs_hint">Tap a scenario to compare</span>
|
||||
<span class="rp-chevron" aria-hidden="true">▾</span>
|
||||
</summary>
|
||||
<div class="result-panel-body">
|
||||
<div class="scenario-tabs" id="scenario-tabs">
|
||||
<button class="s-tab" id="stab-1" data-s="1" @click="showScenario(1)"><span data-i18n="tab_s1">💀 Total</span></button>
|
||||
<button class="s-tab" id="stab-2" data-s="2" @click="showScenario(2)"><span data-i18n="tab_s2">⚠️ Partial</span></button>
|
||||
<button class="s-tab" id="stab-3" data-s="3" @click="showScenario(3)"><span data-i18n="tab_s3">📈 Inflation</span></button>
|
||||
<button class="s-tab" id="stab-4" data-s="4" @click="showScenario(4)"><span data-i18n="tab_s4">🌿 Food</span></button>
|
||||
</div>
|
||||
<div class="rec-cards" id="rec-cards-container"></div>
|
||||
</div>
|
||||
</details>
|
||||
|
||||
<details class="result-panel reveal-section" id="panel-budget">
|
||||
<summary class="result-panel-header">
|
||||
<span class="rp-title" data-i18n="panel_budget">💰 Budget Plan</span>
|
||||
<span class="rp-chevron" aria-hidden="true">▾</span>
|
||||
</summary>
|
||||
<div class="result-panel-body">
|
||||
<div id="budget-meter-container"></div>
|
||||
</div>
|
||||
</details>
|
||||
|
||||
<details class="result-panel reveal-section" id="panel-timeline">
|
||||
<summary class="result-panel-header">
|
||||
<span class="rp-title" data-i18n="panel_timeline">⏱ Action Timeline</span>
|
||||
<span class="rp-chevron" aria-hidden="true">▾</span>
|
||||
</summary>
|
||||
<div class="result-panel-body">
|
||||
<div class="timeline" id="timeline-container">
|
||||
<div class="tl-items" id="timeline-items"></div>
|
||||
</div>
|
||||
</div>
|
||||
</details>
|
||||
|
||||
<button class="restart-btn" @click="restartQuiz" data-i18n="restart_btn">↩ Retake Assessment</button>
|
||||
</section>
|
||||
@@ -525,6 +552,10 @@ const T = {
|
||||
tab_s3: "📈 Hyper-\ninflation",
|
||||
tab_s4: "🌿 Food\nShortage",
|
||||
timeline_title: "⏱ Your Action Timeline",
|
||||
panel_recs: "📋 Your Recommendations",
|
||||
panel_recs_hint: "Tap a scenario to compare",
|
||||
panel_budget: "💰 Budget Plan",
|
||||
panel_timeline: "⏱ Action Timeline",
|
||||
restart_btn: "↩ Retake Assessment",
|
||||
about_title: "Why Deepstock?",
|
||||
about_text: "Built by preparedness researchers and city-dwelling practitioners. Every recommendation is sourced, tested, and city-apartment-compatible.",
|
||||
@@ -620,6 +651,10 @@ const T = {
|
||||
tab_s3: "📈 Hyper-\ninflation",
|
||||
tab_s4: "🌿 Lebens-\nmittelkrise",
|
||||
timeline_title: "⏱ Dein Aktionsplan",
|
||||
panel_recs: "📋 Deine Empfehlungen",
|
||||
panel_recs_hint: "Szenario antippen zum Vergleichen",
|
||||
panel_budget: "💰 Budgetplan",
|
||||
panel_timeline: "⏱ Aktionsplan",
|
||||
restart_btn: "↩ Neu starten",
|
||||
about_title: "Warum Kammergut?",
|
||||
about_text: "Entwickelt von Vorsorge-Forschern und Stadtbewohnern. Jede Empfehlung ist recherchiert, getestet und für Stadtwohnungen geeignet.",
|
||||
@@ -1510,19 +1545,18 @@ function getFallbackNarrativeText() {
|
||||
}
|
||||
|
||||
function revealSections() {
|
||||
const sections = [
|
||||
{ id:'scenario-tabs', display:'flex' },
|
||||
{ id:'budget-meter-container', display:'block' },
|
||||
{ id:'rec-cards-container', display:'block' },
|
||||
{ id:'timeline-container', display:'block' },
|
||||
{ id:'capture-form-wrap', display:'block' },
|
||||
// Capture form first, then the three collapsible result panels (recs is open
|
||||
// by default, budget + timeline collapsed for progressive disclosure).
|
||||
const ids = [
|
||||
'capture-form-wrap',
|
||||
'panel-recs',
|
||||
'panel-budget',
|
||||
'panel-timeline',
|
||||
]
|
||||
sections.forEach((s, i) => {
|
||||
ids.forEach((id, i) => {
|
||||
setTimeout(() => {
|
||||
const el = document.getElementById(s.id)
|
||||
if (!el) return
|
||||
el.style.display = s.display
|
||||
el.classList.add('revealed')
|
||||
const el = document.getElementById(id)
|
||||
if (el) el.classList.add('revealed')
|
||||
}, i * 200)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -553,6 +553,82 @@ input[type=range]::-webkit-slider-thumb { -webkit-appearance: none; width: 22px;
|
||||
.tl-action { font-size: 14px; color: var(--bright); line-height: 1.5; }
|
||||
.tl-cost { font-family: var(--font-mono); font-size: 12px; color: var(--green-bright); margin-top: 4px; }
|
||||
|
||||
/* ── RESULT PANELS — collapsible accordions for progressive disclosure.
|
||||
Recommendations open by default; Budget and Timeline collapsed so the
|
||||
results page doesn't overwhelm. The panel itself becomes the white-paint
|
||||
card; inner sections (.budget-meter, .timeline, .scenario-tabs) drop their
|
||||
own box treatment so the panel frame is the only container. */
|
||||
.result-panel {
|
||||
background: #FAFAFA;
|
||||
border: 1px solid rgba(0,0,0,0.06);
|
||||
border-radius: var(--radius-lg);
|
||||
margin-bottom: 14px;
|
||||
overflow: hidden;
|
||||
box-shadow: 0 7px 10.6px rgba(0,0,0,0.12), inset 0 1px 0 rgba(255,255,255,0.7);
|
||||
}
|
||||
.result-panel-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
padding: 16px 18px;
|
||||
cursor: pointer;
|
||||
list-style: none;
|
||||
user-select: none;
|
||||
-webkit-tap-highlight-color: transparent;
|
||||
transition: background 0.15s ease;
|
||||
}
|
||||
.result-panel-header::-webkit-details-marker { display: none; }
|
||||
.result-panel-header:hover { background: rgba(0,0,0,0.02); }
|
||||
.rp-title {
|
||||
font-family: var(--font-display);
|
||||
font-weight: 700;
|
||||
font-size: 17px;
|
||||
color: var(--text);
|
||||
flex: 1;
|
||||
letter-spacing: 0.01em;
|
||||
line-height: 1.3;
|
||||
}
|
||||
.rp-hint {
|
||||
font-size: 10px;
|
||||
color: var(--text-dim);
|
||||
font-family: var(--font-mono);
|
||||
letter-spacing: 0.08em;
|
||||
text-transform: uppercase;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
@media (max-width: 480px) {
|
||||
.rp-hint { display: none; }
|
||||
}
|
||||
.rp-chevron {
|
||||
font-size: 14px;
|
||||
color: var(--text-dim);
|
||||
transition: transform 0.2s ease;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.result-panel[open] .rp-chevron { transform: rotate(180deg); }
|
||||
.result-panel-body {
|
||||
padding: 0 18px 18px;
|
||||
}
|
||||
/* Strip box treatment from inner cards when wrapped in a panel — the panel
|
||||
is now the visible container. */
|
||||
.result-panel-body .budget-meter,
|
||||
.result-panel-body .timeline {
|
||||
background: transparent;
|
||||
border: none;
|
||||
border-radius: 0;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
box-shadow: none;
|
||||
animation: none;
|
||||
}
|
||||
.result-panel-body .scenario-tabs {
|
||||
margin-bottom: 16px;
|
||||
animation: none;
|
||||
}
|
||||
.result-panel-body .rec-cards { animation: none; }
|
||||
/* Drop the redundant inner timeline title — the panel header replaces it. */
|
||||
.result-panel-body .tl-title { display: none; }
|
||||
|
||||
/* Results email capture */
|
||||
.results-email {
|
||||
background: linear-gradient(135deg, var(--red-dim), #141210);
|
||||
@@ -693,6 +769,13 @@ body.paint-green .qpb-logo {
|
||||
text-decoration: none;
|
||||
}
|
||||
.quiz-progress-bar .progress-wrap { flex: 1; max-width: none; margin: 0; }
|
||||
/* Desktop — cap the progress bar at the form width (540px) so it reads
|
||||
tighter and lines up with the question card below. Auto margins on the
|
||||
flex item absorb leftover horizontal space symmetrically, centring the
|
||||
bar between the logo (left) and lang-toggle (right). */
|
||||
@media (min-width: 768px) {
|
||||
.quiz-progress-bar .progress-wrap { max-width: 540px; margin: 0 auto; }
|
||||
}
|
||||
.quiz-progress-bar .lang-toggle { flex-shrink: 0; }
|
||||
@media (max-width: 767px) {
|
||||
.quiz-progress-bar .lang-toggle { display: none; }
|
||||
|
||||
Reference in New Issue
Block a user