/* Main site — self-hosted only, no CDNs (hard rule).
   Montserrat comes from css/fonts.css; the system stack stays as the
   fallback while the font swaps in. */

* {
    box-sizing: border-box;
}

:root {
    /* Type scale, ratio 1.125 at the small end where precision matters,
       opening up for display sizes. Do not add sizes between these. */
    --text-xs: 0.8125rem;
    --text-sm: 0.875rem;
    --text-base: 1rem;
    --text-md: 1.125rem;
    --text-lg: 1.25rem;

    /* Fluid, not stepped: clamp(MIN, FLUID, MAX) — the middle value must
       carry the viewport unit, or the size never actually scales.
       24px at 320px viewport, 40px from 1024px up. At 24px the longest
       word on these pages ("Datenschutzerklärung", measured 288px)
       hyphenates into two lines instead of overflowing. */
    --text-h1: clamp(1.5rem, 1.045rem + 2.27vw, 2.5rem);

    /* Spacing derived from the text size, so rhythm survives a scale change */
    --space-xs: 0.5rem;
    --space-sm: 0.75rem;
    --space-md: 1.5rem;
    --space-lg: 2.5rem;

    /* Brand colors. The inline logo SVG fills from these (with the same
       values as fallback), so a future dark mode or animation only has
       to redefine them — no template or SVG edit. */
    --logo-ink: #16384c;
    --logo-accent: #2c7099;

    /* Links in Markenblau — 5,41:1 auf Weiß, AA erfüllt (gerechnet,
       nicht geschätzt). Bei Änderung neu rechnen. */
    --color-link: #2c7099;

    /* Feste Kopfzeilenhöhe: der Startseiten-Hero rechnet damit
       (100svh − Kopfzeile). Ändert sich die Kopfzeile, nur dieses
       Token anfassen. */
    --kopfzeile-hoehe: 4.5rem;
}

/* Sanftes Scrollen zum Projekt-Anker; der reduced-motion-Block unten
   setzt es global wieder auf auto. */
html {
    scroll-behavior: smooth;
}

/* Off-screen until keyboard focus reaches it — it must stay in the
   accessibility tree, so no display:none. Fixed so it is visible even
   when the page is already scrolled. */
.skip-link {
    position: fixed;
    top: -100%;
    left: var(--space-xs);
    z-index: 10;
    padding: var(--space-xs) var(--space-sm);
    background: #16384c;
    color: #fff;
    text-decoration: none;
}

.skip-link:focus {
    top: var(--space-xs);
}

/* Standard clip pattern: readable by screen readers, invisible on
   screen. display:none/visibility:hidden would remove it from the
   accessibility tree. */
.visually-hidden {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
}

body {
    margin: 0;
    font-family: "Montserrat", system-ui, -apple-system, "Segoe UI", sans-serif;
    color: #2b2b2b;
    min-height: 100vh;
    display: flex;
    flex-direction: column;
}

/* GOV.UK-Fokusmuster: gelbe Fläche + schwarzer Balken, zweischichtig,
   damit der Fokus auf jedem Untergrund sichtbar ist — eine einzelne
   Outline-Farbe kann mit dem Hintergrund verschmelzen. Gilt für Links;
   der Logo-Link unten überschreibt (Fläche hinter einem Bild wirkt
   nicht). */
a:focus-visible {
    outline: 3px solid transparent;
    color: #0b0c0c;
    background-color: #fd0;
    box-shadow: 0 -2px #fd0, 0 4px #0b0c0c;
    text-decoration: none;
}

/* Links bleiben unterstrichen — Farbe allein kennzeichnet keinen Link
   (WCAG 1.4.1); Hover verstärkt die Linie statt sie zu entfernen. */
a {
    color: var(--color-link);
    text-underline-offset: 0.15em;
}

a:hover {
    text-decoration-thickness: 0.15em;
}

/* Bilder nie breiter als ihr Container — Grundlage für mobile-first. */
img {
    max-width: 100%;
    height: auto;
}

/* Bewegung nur für Menschen, die sie nicht abgeschaltet haben
   (WCAG 2.3.3). Pauschal statt pro Animation, damit künftige
   Animationen nicht einzeln daran denken müssen. */
@media (prefers-reduced-motion: reduce) {
    *,
    *::before,
    *::after {
        animation-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.01ms !important;
        scroll-behavior: auto !important;
    }
}

main {
    flex: 1;
    width: 100%;
}

/* Impressum / Datenschutzerklärung — must be reachable from every page
   (§ 5 DDG, Art. 13 DSGVO), so the footer lives in the base template. */
.site-footer {
    display: flex;
    gap: 1.25rem;
    justify-content: center;
    flex-wrap: wrap;
    padding: 1.25rem;
    font-size: var(--text-xs);
}

.site-footer a {
    color: #6b6b6b;
}

.legal {
    /* ~73 characters at this measure in Montserrat — the top of the
       comfortable 45-75 range, so the leading has to be generous. */
    max-width: 42rem;
    width: 100%;
    margin-inline: auto;
    padding: var(--space-md);
    line-height: 1.6;
    /* German compounds are long; on a narrow phone hyphenation prevents
       rivers of whitespace. Needs lang="de" on <html> to work. */
    hyphens: auto;
}

.legal p {
    /* Avoids single-word last lines without touching the other lines */
    text-wrap: pretty;
}

.legal h1 {
    font-size: var(--text-h1);
    font-weight: 800;
    line-height: 1.15;
    letter-spacing: -0.02em;
    /* Even line lengths instead of a long line and one stray word */
    text-wrap: balance;
    margin-bottom: var(--space-md);
}

/* Proximity: a heading belongs to the text below it, so the space above
   must be clearly larger than the space below. */
.legal h2 {
    font-size: var(--text-md);
    line-height: 1.25;
    letter-spacing: -0.01em;
    text-wrap: balance;
    margin-top: var(--space-lg);
    margin-bottom: var(--space-xs);
}

.legal h3 {
    font-size: var(--text-base);
    line-height: 1.3;
    text-wrap: balance;
    margin-top: var(--space-md);
    margin-bottom: var(--space-xs);
}

/* Projekt- und Angebotsseiten: gleiche Lesespalte wie .legal — ein
   Satzspiegel für die ganze Site. Mobile-first: die Spalte ist von
   Haus aus schmal, größere Viewports bekommen nur mehr Rand. */
.projekt,
.angebot,
.startseite {
    max-width: 42rem;
    width: 100%;
    margin-inline: auto;
    padding: var(--space-md);
    line-height: 1.6;
    hyphens: auto;
}

.projekt h1,
.angebot h1,
.startseite h1 {
    font-size: var(--text-h1);
    font-weight: 800;
    line-height: 1.15;
    letter-spacing: -0.02em;
    text-wrap: balance;
    margin-block: 0 var(--space-xs);
}

.projekt h2,
.angebot h2,
.startseite h2 {
    font-size: var(--text-lg);
    line-height: 1.25;
    letter-spacing: -0.01em;
    text-wrap: balance;
    margin-top: var(--space-lg);
    margin-bottom: var(--space-lg);
}

.projekt p,
.angebot p,
.startseite p {
    text-wrap: pretty;
}

.projekt-logo {
    display: block;
    margin-block-end: var(--space-sm);
}

.projekt-logo img {
    max-height: 3rem;
    width: auto;
}

.projekt-claim {
    font-size: var(--text-lg);
    color: #4a4a4a;
    margin-block: 0 var(--space-sm);
}

/* Der erste Viewport gehört dem Hero: Kopfzeile + Spaltenpolster
   abgezogen, Inhalt vertikal zentriert. svh statt dvh — die kleinste
   Viewport-Höhe springt auf Mobilgeräten nicht, wenn die
   Browserleiste ein- und ausfährt. min-height: langer Text wächst,
   statt abgeschnitten zu werden. */
.startseite-hero {
    min-height: calc(100vh - var(--kopfzeile-hoehe) - var(--space-md));
    min-height: calc(100svh - var(--kopfzeile-hoehe) - var(--space-md));
    display: flex;
    flex-direction: column;
    justify-content: center;
}

/* Der Leitsatz ist die Mission in einem Satz — eine Stufe präsenter
   als ein Projekt-Claim, aber klar unterhalb der H1. */
.startseite .leitsatz {
    font-size: var(--text-lg);
    color: #4a4a4a;
    text-wrap: balance;
    margin-block: 0 var(--space-md);
}

.hero-weiter {
    margin-block: var(--space-lg) 0;
}

/* Anker landet nicht klebend an der Oberkante */
#projekte {
    scroll-margin-top: var(--space-md);
}

.projekt-laufzeit {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-sm);
    margin-block: 0;
    font-size: var(--text-sm);
}

.projekt-eigenname {
    font-size: var(--text-sm);
    color: #595959;
    margin-block: var(--space-xs) 0;
}

/* Status trägt seine Information im Text; Farbe und Rahmen sind nur
   Verstärkung. Alle Farben ≥ 4,5:1 auf Weiß. */
.status {
    display: inline-block;
    padding: 0.125rem 0.625rem;
    border: 1px solid currentColor;
    border-radius: 999px;
    font-weight: 600;
}

.status--geplant {
    color: #20566b;
}

.status--laufend {
    color: #1e5c31;
}

.status--abgeschlossen {
    color: #595959;
}

/* Generische Karten: Angebote auf der Projektseite, Projekte auf der
   Startseite. Eine Spalte auf schmalen Screens, Karten nebeneinander
   sobald Platz ist — ohne Media Query. */
.karten-liste {
    list-style: none;
    margin: 0;
    padding: 0;
    display: grid;
    gap: var(--space-sm);
    grid-template-columns: repeat(auto-fill, minmax(16rem, 1fr));
}

.karte {
    display: flex;
    flex-direction: column;
    border: 1px solid #d5d5d5;
    border-radius: 0.375rem;
    padding: var(--space-lg);
    background: #fff;
    /* Dezenter Lift auf Hover/Fokus — der reduced-motion-Block oben
       neutralisiert die Transition für alle, die das abgestellt haben. */
    transition: transform 0.15s ease, box-shadow 0.15s ease;
}

.karte:hover,
.karte:focus-within {
    transform: translateY(-2px);
    box-shadow: 0 4px 12px rgb(22 56 76 / 0.12);
}

/* Projektlogo (oder Vereinslogo als Fallback): feste Zeile, damit
   Karten mit und ohne eigenes Logo gleich hoch beginnen. */
.karte-logo {
    display: flex;
    align-items: center;
    height: 2.5rem;
    margin-block-end: var(--space-xs);
}

.karte-logo img,
.karte-logo svg {
    max-height: 100%;
    height: 100%;
    width: auto;
    max-width: 100%;
}

.karte h3 {
    font-size: var(--text-base);
    margin-block: 0 var(--space-xs);
}

/* Die ganze Karte wäre gern klickbar, aber der Link bleibt der Titel:
   ein flächiger Link läse sich im Screenreader als ein langer
   Linktext. Der Titel-Link bekommt stattdessen ein großzügiges
   Touch-Ziel. */
.karte h3 a {
    display: inline-block;
    padding-block: 0.25rem;
}

.karte-text,
.angebot-zeiten {
    font-size: var(--text-sm);
    color: #4a4a4a;
    margin-block: 0;
}

/* margin-top: auto drückt die Statuszeile in jeder Karte nach unten —
   unterschiedlich lange Claims, gleiche Unterkante. */
.karte-meta {
    margin-block: auto 0;
    padding-block-start: var(--space-lg);
    font-size: var(--text-xs);
}

.mittelgeber-liste {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-sm) var(--space-md);
    align-items: center;
}

.mittelgeber-liste li {
    display: flex;
    align-items: center;
    gap: var(--space-sm);
}

/* Förderlogos: eine ruhige Zeile, kein Grau-Filter — die Logos der
   Geber werden nicht verfremdet. */
.mittelgeber-liste img {
    max-height: 2.5rem;
    width: auto;
}

/* <address> ist semantisch, nicht typografisch — die Kursive der
   Browser-Voreinstellung ist hier nur Rauschen. */
.projekt-kontakt address {
    font-style: normal;
}

.personen-liste {
    list-style: none;
    margin: 0;
    padding: 0;
    display: grid;
    gap: var(--space-sm);
    grid-template-columns: repeat(auto-fill, minmax(16rem, 1fr));
}

.person-karte {
    display: flex;
    align-items: flex-start;
    gap: var(--space-sm);
    border: 1px solid #d5d5d5;
    border-radius: 0.375rem;
    padding: var(--space-sm);
}

.person-karte p {
    margin-block: 0 0.125rem;
}

.person-karte address p:has(a) {
    font-size: var(--text-sm);
}

.person-foto {
    /* Feste Kante + object-fit statt Verzerrung, rund als Porträt. */
    width: 4rem;
    height: 4rem;
    border-radius: 50%;
    object-fit: cover;
    flex-shrink: 0;
}

.person-name {
    font-weight: 600;
}

.person-pronomen {
    font-weight: 400;
    font-size: var(--text-sm);
    color: #595959;
}

/* Zwei Klassen, damit die Regel .person-karte p (0,1,1) beim Margin
   nicht gewinnt. */
.person-karte .person-rolle {
    font-size: var(--text-sm);
    color: #4a4a4a;
    /* Luft zwischen Rolle und den Kontaktzeilen darunter */
    margin-block-end: 0.375rem;
}

.angebot-fakten {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-xs) var(--space-lg);
    margin-block: var(--space-md);
    padding: var(--space-sm) var(--space-md);
    border-inline-start: 4px solid var(--logo-accent);
    background: #f4f7f9;
}

.angebot-fakten dt {
    font-size: var(--text-sm);
    font-weight: 600;
    color: #4a4a4a;
}

.angebot-fakten dd {
    margin: 0;
}

.zurueck {
    font-size: var(--text-sm);
    display: inline-block;
    padding-block: 0.25rem;
}

.zurueck::before {
    content: "‹ ";
}

.site-header {
    block-size: var(--kopfzeile-hoehe);
    display: flex;
    align-items: center;
}

.site-logo {
    display: block;
    max-width: 10.6rem;
    padding-inline: 1.25rem;
    width: 100%;
}

.site-logo:focus-visible {
    background-color: transparent;
    box-shadow: none;
    outline: 3px solid #fd0;
    outline-offset: 2px;
}
