Mitmachen: Ehrenamtsseite mit Stellen-Filter
Neue Seite /mitmachen, die offene Ehrenamtsstellen aus data/mitmachen.json als position-card-Komponente listet, mit clientseitigem Bereichsfilter (position-filter.js, progressive enhancement) und JobPosting-Schema (job_posting_schema(), employmentType VOLUNTEER). Route ergänzt. Enthält zudem kleine person-card__contact-Stilanpassungen (gleiche CSS-Sektion). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HGzc6GhWhmLJt1jC2q1SRZ
This commit is contained in:
@@ -713,6 +713,270 @@
|
||||
text-underline-offset: 0.25em;
|
||||
}
|
||||
|
||||
/* === mitmachen / positions (Ehrenamt-Stellen) === */
|
||||
/* Filter-Stripe (Alle/Fußball/Turnen) — Unterstrich-Tabbar wie group-tabs */
|
||||
.filter-bar {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
margin-bottom: 2rem;
|
||||
}
|
||||
|
||||
.filter-bar__tab {
|
||||
padding: 0.65rem 1.2rem;
|
||||
background: none;
|
||||
border: none;
|
||||
box-shadow: inset 0 -2px 0 var(--clr-glass-border);
|
||||
font-family: var(--ff-body);
|
||||
font-size: var(--fs-500);
|
||||
color: var(--clr-text-muted);
|
||||
cursor: pointer;
|
||||
white-space: nowrap;
|
||||
transition: color var(--transition), box-shadow var(--transition);
|
||||
}
|
||||
|
||||
.filter-bar__tab:first-child {
|
||||
padding-inline-start: 0;
|
||||
}
|
||||
|
||||
.filter-bar__tab:hover {
|
||||
color: var(--clr-text);
|
||||
}
|
||||
|
||||
.filter-bar__tab[aria-pressed="true"] {
|
||||
color: var(--clr-text);
|
||||
box-shadow: inset 0 -2px 0 var(--clr-accent);
|
||||
}
|
||||
|
||||
.filter-bar__tab:focus-visible {
|
||||
outline: 2px solid var(--clr-accent);
|
||||
outline-offset: -2px;
|
||||
}
|
||||
|
||||
.positions__list {
|
||||
display: grid;
|
||||
gap: 1.5rem;
|
||||
}
|
||||
|
||||
.positions__empty {
|
||||
margin: 0;
|
||||
padding: 2.5rem 0;
|
||||
max-width: 60ch;
|
||||
color: var(--clr-text-muted);
|
||||
font-size: var(--fs-500);
|
||||
line-height: var(--lh-body);
|
||||
}
|
||||
|
||||
.positions__empty[hidden] {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.positions__empty a {
|
||||
color: var(--clr-text);
|
||||
text-decoration: underline;
|
||||
text-underline-offset: 0.2em;
|
||||
}
|
||||
|
||||
/* "Warum mithelfen?": geteiltes sponsor-arguments-Raster, hier mit Überschrift
|
||||
(nur auf dieser Seite — Partner-/Sportheim-Variante bleibt ohne Heading unberührt) */
|
||||
#warum-mithelfen > .container {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
#warum-mithelfen .sponsor-arguments__intro {
|
||||
max-width: 60ch;
|
||||
margin: 1rem auto 0;
|
||||
color: var(--clr-text-muted);
|
||||
}
|
||||
|
||||
#warum-mithelfen .sponsor-arguments__grid {
|
||||
margin-top: 2.5rem;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
/* Aufklappbare Stelle (details/summary, FAQ-Mechanik): eingeklappt nur Bereich + Titel */
|
||||
.position-card {
|
||||
background: var(--clr-glass-bg);
|
||||
border: 1px solid var(--clr-glass-border);
|
||||
border-radius: var(--radius-card);
|
||||
overflow: hidden;
|
||||
transition: border-color var(--transition);
|
||||
}
|
||||
|
||||
.position-card[open] {
|
||||
border-color: var(--clr-glass-border-strong, var(--clr-glass-border));
|
||||
}
|
||||
|
||||
/* display:grid o. Ä. würde sonst [hidden]{display:none} überschreiben — explizit halten */
|
||||
.position-card[hidden] {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* Klickzeile: Icon + Bereich/Titel + Chevron */
|
||||
.position-card__head {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 1rem;
|
||||
padding: 1.25rem 1.5rem;
|
||||
cursor: pointer;
|
||||
list-style: none;
|
||||
transition: background var(--transition);
|
||||
}
|
||||
|
||||
.position-card__head::-webkit-details-marker {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.position-card__head:hover {
|
||||
background: rgb(255 255 255 / 0.04);
|
||||
}
|
||||
|
||||
.position-card__head:focus-visible {
|
||||
outline: 2px solid var(--clr-accent);
|
||||
outline-offset: -2px;
|
||||
}
|
||||
|
||||
.position-card__icon {
|
||||
flex-shrink: 0;
|
||||
width: 2.5rem;
|
||||
height: 2.5rem;
|
||||
background: var(--clr-accent);
|
||||
border-radius: 8px;
|
||||
display: grid;
|
||||
place-items: center;
|
||||
font-size: 1.15rem;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.position-card__heading {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.position-card__area {
|
||||
display: block;
|
||||
font-family: var(--ff-body);
|
||||
font-size: var(--fs-300);
|
||||
font-weight: var(--fw-bold);
|
||||
letter-spacing: 0.12em;
|
||||
text-transform: uppercase;
|
||||
color: var(--clr-text-muted);
|
||||
margin: 0 0 0.2rem;
|
||||
}
|
||||
|
||||
.position-card__title {
|
||||
font-family: var(--ff-heading);
|
||||
font-size: var(--fs-675);
|
||||
text-transform: uppercase;
|
||||
line-height: var(--lh-heading);
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.position-card__chevron {
|
||||
flex: none;
|
||||
font-size: 0.9rem;
|
||||
color: var(--clr-text-muted);
|
||||
transition: transform var(--transition), color var(--transition);
|
||||
}
|
||||
|
||||
.position-card[open] .position-card__chevron {
|
||||
transform: rotate(180deg);
|
||||
color: var(--clr-text);
|
||||
}
|
||||
|
||||
/* Aufgeklappter Inhalt: Detailspalte + Ansprechpartner */
|
||||
.position-card__body {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr minmax(0, 16rem);
|
||||
gap: 2.5rem;
|
||||
align-items: start;
|
||||
padding: 0 1.5rem 1.5rem 5rem;
|
||||
animation: faq-reveal 260ms ease;
|
||||
}
|
||||
|
||||
.position-card__main > :first-child {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.position-card__summary {
|
||||
color: var(--clr-text-muted);
|
||||
font-size: var(--fs-500);
|
||||
line-height: var(--lh-body);
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.position-card__tasks {
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
margin: 1.25rem 0 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.625rem;
|
||||
}
|
||||
|
||||
.position-card__tasks li {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
gap: 0.625rem;
|
||||
font-size: var(--fs-500);
|
||||
line-height: var(--lh-body);
|
||||
}
|
||||
|
||||
.position-card__check {
|
||||
flex-shrink: 0;
|
||||
margin-top: 0.2em;
|
||||
font-size: 1rem;
|
||||
color: var(--clr-accent);
|
||||
}
|
||||
|
||||
.position-card__meta {
|
||||
margin: 1.25rem 0 0;
|
||||
display: grid;
|
||||
gap: 0.75rem;
|
||||
}
|
||||
|
||||
.position-card__meta-row {
|
||||
display: grid;
|
||||
gap: 0.2rem;
|
||||
}
|
||||
|
||||
.position-card__meta dt {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
font-size: var(--fs-300);
|
||||
font-weight: var(--fw-bold);
|
||||
letter-spacing: 0.08em;
|
||||
text-transform: uppercase;
|
||||
color: var(--clr-text-muted);
|
||||
}
|
||||
|
||||
.position-card__meta-icon {
|
||||
color: var(--clr-accent);
|
||||
}
|
||||
|
||||
.position-card__meta dd {
|
||||
margin: 0;
|
||||
font-size: var(--fs-500);
|
||||
line-height: var(--lh-body);
|
||||
}
|
||||
|
||||
/* Kompakte Kontakt-Karte: flacheres Foto als im Ansprechpartner-Grid */
|
||||
.position-card__contact .person-card__media img {
|
||||
aspect-ratio: 4 / 3.4;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.position-card__body {
|
||||
grid-template-columns: 1fr;
|
||||
gap: 1.5rem;
|
||||
padding: 0 1.5rem 1.5rem;
|
||||
}
|
||||
|
||||
.position-card__contact {
|
||||
max-width: 18rem;
|
||||
}
|
||||
}
|
||||
|
||||
/* === contact form === */
|
||||
.contact__inner {
|
||||
display: grid;
|
||||
|
||||
1
public/assets/icons/check2.svg
Normal file
1
public/assets/icons/check2.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><path d="M13.854 3.646a.5.5 0 0 1 0 .708l-7 7a.5.5 0 0 1-.708 0l-3.5-3.5a.5.5 0 1 1 .708-.708L6.5 10.293l6.646-6.647a.5.5 0 0 1 .708 0"/></svg>
|
||||
|
After Width: | Height: | Size: 204 B |
3
public/assets/icons/clipboard-check.svg
Normal file
3
public/assets/icons/clipboard-check.svg
Normal file
@@ -0,0 +1,3 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><path fill-rule="evenodd" d="M10.854 7.146a.5.5 0 0 1 0 .708l-3 3a.5.5 0 0 1-.708 0l-1.5-1.5a.5.5 0 1 1 .708-.708L7.5 9.793l2.646-2.647a.5.5 0 0 1 .708 0"/>
|
||||
<path d="M4 1.5H3a2 2 0 0 0-2 2V14a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V3.5a2 2 0 0 0-2-2h-1v1h1a1 1 0 0 1 1 1V14a1 1 0 0 1-1 1H3a1 1 0 0 1-1-1V3.5a1 1 0 0 1 1-1h1z"/>
|
||||
<path d="M9.5 1a.5.5 0 0 1 .5.5v1a.5.5 0 0 1-.5.5h-3a.5.5 0 0 1-.5-.5v-1a.5.5 0 0 1 .5-.5zm-3-1A1.5 1.5 0 0 0 5 1.5v1A1.5 1.5 0 0 0 6.5 4h3A1.5 1.5 0 0 0 11 2.5v-1A1.5 1.5 0 0 0 9.5 0z"/></svg>
|
||||
|
After Width: | Height: | Size: 577 B |
3
public/assets/icons/clock-history.svg
Normal file
3
public/assets/icons/clock-history.svg
Normal file
@@ -0,0 +1,3 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><path d="M8.515 1.019A7 7 0 0 0 8 1V0a8 8 0 0 1 .589.022zm2.004.45a7 7 0 0 0-.985-.299l.219-.976q.576.129 1.126.342zm1.37.71a7 7 0 0 0-.439-.27l.493-.87a8 8 0 0 1 .979.654l-.615.789a7 7 0 0 0-.418-.302zm1.834 1.79a7 7 0 0 0-.653-.796l.724-.69q.406.429.747.91zm.744 1.352a7 7 0 0 0-.214-.468l.893-.45a8 8 0 0 1 .45 1.088l-.95.313a7 7 0 0 0-.179-.483m.53 2.507a7 7 0 0 0-.1-1.025l.985-.17q.1.58.116 1.17zm-.131 1.538q.05-.254.081-.51l.993.123a8 8 0 0 1-.23 1.155l-.964-.267q.069-.247.12-.501m-.952 2.379q.276-.436.486-.908l.914.405q-.24.54-.555 1.038zm-.964 1.205q.183-.183.35-.378l.758.653a8 8 0 0 1-.401.432z"/>
|
||||
<path d="M8 1a7 7 0 1 0 4.95 11.95l.707.707A8.001 8.001 0 1 1 8 0z"/>
|
||||
<path d="M7.5 3a.5.5 0 0 1 .5.5v5.21l3.248 1.856a.5.5 0 0 1-.496.868l-3.5-2A.5.5 0 0 1 7 9V3.5a.5.5 0 0 1 .5-.5"/></svg>
|
||||
|
After Width: | Height: | Size: 867 B |
2
public/assets/icons/cup-hot.svg
Normal file
2
public/assets/icons/cup-hot.svg
Normal file
@@ -0,0 +1,2 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><path fill-rule="evenodd" d="M.5 6a.5.5 0 0 0-.488.608l1.652 7.434A2.5 2.5 0 0 0 4.104 16h5.792a2.5 2.5 0 0 0 2.44-1.958l.131-.59a3 3 0 0 0 1.3-5.854l.221-.99A.5.5 0 0 0 13.5 6zM13 12.5a2 2 0 0 1-.316-.025l.867-3.898A2.001 2.001 0 0 1 13 12.5M2.64 13.825 1.123 7h11.754l-1.517 6.825A1.5 1.5 0 0 1 9.896 15H4.104a1.5 1.5 0 0 1-1.464-1.175"/>
|
||||
<path d="m4.4.8-.003.004-.014.019a4 4 0 0 0-.204.31 2 2 0 0 0-.141.267c-.026.06-.034.092-.037.103v.004a.6.6 0 0 0 .091.248c.075.133.178.272.308.445l.01.012c.118.158.26.347.37.543.112.2.22.455.22.745 0 .188-.065.368-.119.494a3 3 0 0 1-.202.388 5 5 0 0 1-.253.382l-.018.025-.005.008-.002.002A.5.5 0 0 1 3.6 4.2l.003-.004.014-.019a4 4 0 0 0 .204-.31 2 2 0 0 0 .141-.267c.026-.06.034-.092.037-.103a.6.6 0 0 0-.09-.252A4 4 0 0 0 3.6 2.8l-.01-.012a5 5 0 0 1-.37-.543A1.53 1.53 0 0 1 3 1.5c0-.188.065-.368.119-.494.059-.138.134-.274.202-.388a6 6 0 0 1 .253-.382l.025-.035A.5.5 0 0 1 4.4.8m3 0-.003.004-.014.019a4 4 0 0 0-.204.31 2 2 0 0 0-.141.267c-.026.06-.034.092-.037.103v.004a.6.6 0 0 0 .091.248c.075.133.178.272.308.445l.01.012c.118.158.26.347.37.543.112.2.22.455.22.745 0 .188-.065.368-.119.494a3 3 0 0 1-.202.388 5 5 0 0 1-.253.382l-.018.025-.005.008-.002.002A.5.5 0 0 1 6.6 4.2l.003-.004.014-.019a4 4 0 0 0 .204-.31 2 2 0 0 0 .141-.267c.026-.06.034-.092.037-.103a.6.6 0 0 0-.09-.252A4 4 0 0 0 6.6 2.8l-.01-.012a5 5 0 0 1-.37-.543A1.53 1.53 0 0 1 6 1.5c0-.188.065-.368.119-.494.059-.138.134-.274.202-.388a6 6 0 0 1 .253-.382l.025-.035A.5.5 0 0 1 7.4.8m3 0-.003.004-.014.019a4 4 0 0 0-.204.31 2 2 0 0 0-.141.267c-.026.06-.034.092-.037.103v.004a.6.6 0 0 0 .091.248c.075.133.178.272.308.445l.01.012c.118.158.26.347.37.543.112.2.22.455.22.745 0 .188-.065.368-.119.494a3 3 0 0 1-.202.388 5 5 0 0 1-.252.382l-.019.025-.005.008-.002.002A.5.5 0 0 1 9.6 4.2l.003-.004.014-.019a4 4 0 0 0 .204-.31 2 2 0 0 0 .141-.267c.026-.06.034-.092.037-.103a.6.6 0 0 0-.09-.252A4 4 0 0 0 9.6 2.8l-.01-.012a5 5 0 0 1-.37-.543A1.53 1.53 0 0 1 9 1.5c0-.188.065-.368.119-.494.059-.138.134-.274.202-.388a6 6 0 0 1 .253-.382l.025-.035A.5.5 0 0 1 10.4.8"/></svg>
|
||||
|
After Width: | Height: | Size: 2.1 KiB |
1
public/assets/icons/heart.svg
Normal file
1
public/assets/icons/heart.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><path d="m8 2.748-.717-.737C5.6.281 2.514.878 1.4 3.053c-.523 1.023-.641 2.5.314 4.385.92 1.815 2.834 3.989 6.286 6.357 3.452-2.368 5.365-4.542 6.286-6.357.955-1.886.838-3.362.314-4.385C13.486.878 10.4.28 8.717 2.01zM8 15C-7.333 4.868 3.279-3.04 7.824 1.143q.09.083.176.171a3 3 0 0 1 .176-.17C12.72-3.042 23.333 4.867 8 15"/></svg>
|
||||
|
After Width: | Height: | Size: 392 B |
2
public/assets/icons/mortarboard-fill.svg
Normal file
2
public/assets/icons/mortarboard-fill.svg
Normal file
@@ -0,0 +1,2 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><path d="M8.211 2.047a.5.5 0 0 0-.422 0l-7.5 3.5a.5.5 0 0 0 .025.917l7.5 3a.5.5 0 0 0 .372 0L14 7.14V13a1 1 0 0 0-1 1v2h3v-2a1 1 0 0 0-1-1V6.739l.686-.275a.5.5 0 0 0 .025-.917z"/>
|
||||
<path d="M4.176 9.032a.5.5 0 0 0-.656.327l-.5 1.7a.5.5 0 0 0 .294.605l4.5 1.8a.5.5 0 0 0 .372 0l4.5-1.8a.5.5 0 0 0 .294-.605l-.5-1.7a.5.5 0 0 0-.656-.327L8 10.466z"/></svg>
|
||||
|
After Width: | Height: | Size: 415 B |
44
public/assets/js/position-filter.js
Normal file
44
public/assets/js/position-filter.js
Normal file
@@ -0,0 +1,44 @@
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
// Filtert die Stellen-Karten (/mitmachen) nach Bereich. Ohne JS sind alle Karten
|
||||
// sichtbar (Default-Filter "all"), der Empty-State bleibt verborgen — die Tabs
|
||||
// sind reine Progressive Enhancement.
|
||||
function init(bar) {
|
||||
var section = bar.closest('section');
|
||||
if (!section) { return; }
|
||||
|
||||
var buttons = [].slice.call(bar.querySelectorAll('[data-filter]'));
|
||||
var cards = [].slice.call(section.querySelectorAll('.position-card'));
|
||||
var empty = section.querySelector('[data-position-empty]');
|
||||
if (!buttons.length || !cards.length) { return; }
|
||||
|
||||
function apply(filter) {
|
||||
var visible = 0;
|
||||
cards.forEach(function (card) {
|
||||
var match = filter === 'all' || card.getAttribute('data-group') === filter;
|
||||
card.hidden = !match;
|
||||
if (match) { visible++; }
|
||||
});
|
||||
if (empty) { empty.hidden = visible !== 0; }
|
||||
}
|
||||
|
||||
buttons.forEach(function (btn, i) {
|
||||
btn.addEventListener('click', function () {
|
||||
buttons.forEach(function (b) { b.setAttribute('aria-pressed', 'false'); });
|
||||
btn.setAttribute('aria-pressed', 'true');
|
||||
apply(btn.getAttribute('data-filter'));
|
||||
});
|
||||
btn.addEventListener('keydown', function (e) {
|
||||
var next = null;
|
||||
if (e.key === 'ArrowRight') { next = (i + 1) % buttons.length; }
|
||||
if (e.key === 'ArrowLeft') { next = (i - 1 + buttons.length) % buttons.length; }
|
||||
if (e.key === 'Home') { next = 0; }
|
||||
if (e.key === 'End') { next = buttons.length - 1; }
|
||||
if (next !== null) { e.preventDefault(); buttons[next].focus(); }
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
document.querySelectorAll('[data-position-filter]').forEach(init);
|
||||
}());
|
||||
Reference in New Issue
Block a user