/* ============================================================
   AWO Bonn/Rhein-Sieg — shared stylesheet
   Tokens + base + header/nav + split + footer (common to every page).
   Each page adds its page-specific CSS in an inline <style>.
   ============================================================ */
/* Fira Sans — the site font. Four cuts: Regular 400, Medium 500, Bold 700, Italic 400.
   Served from this plugin, never from a font CDN: fetching it from Google would send the
   visitor's IP there without consent, which is what was removed for data protection.

   Two files per cut. The first covers Latin, the second Latin Extended, which is what carries
   the Turkish letters; a browser only fetches the second when the page needs those characters.
   Arabic is not part of this family - /ar/ still falls back and needs a font of its own. */
@font-face{font-family:"Fira Sans";src:url("fonts/FiraSans-Regular-latin.woff2") format("woff2");font-weight:400;font-style:normal;font-display:swap;unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}
@font-face{font-family:"Fira Sans";src:url("fonts/FiraSans-Regular-latin-ext.woff2") format("woff2");font-weight:400;font-style:normal;font-display:swap;unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}
@font-face{font-family:"Fira Sans";src:url("fonts/FiraSans-Medium-latin.woff2") format("woff2");font-weight:500;font-style:normal;font-display:swap;unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}
@font-face{font-family:"Fira Sans";src:url("fonts/FiraSans-Medium-latin-ext.woff2") format("woff2");font-weight:500;font-style:normal;font-display:swap;unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}
@font-face{font-family:"Fira Sans";src:url("fonts/FiraSans-Bold-latin.woff2") format("woff2");font-weight:700;font-style:normal;font-display:swap;unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}
@font-face{font-family:"Fira Sans";src:url("fonts/FiraSans-Bold-latin-ext.woff2") format("woff2");font-weight:700;font-style:normal;font-display:swap;unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}
@font-face{font-family:"Fira Sans";src:url("fonts/FiraSans-Italic-latin.woff2") format("woff2");font-weight:400;font-style:italic;font-display:swap;unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}
@font-face{font-family:"Fira Sans";src:url("fonts/FiraSans-Italic-latin-ext.woff2") format("woff2");font-weight:400;font-style:italic;font-display:swap;unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}

:root{
  --red:#E2001A; --ink:#171717; --ink2:#313131; --dark:#343A40;
  --gray:#707070; --border:#DBDADA; --light:#F6F6F6; --white:#FFFFFF;
  /* Fira Sans is the site font; the fallbacks only show while it loads. */
  --font:"Fira Sans","Open Sans",Arial,system-ui,sans-serif;
  /* Spacing — measured from the design (1920px artboard, capture scale 1.516x) and
     rescaled to the 1200px container (factor 0.79). Original design values in parentheses. */
  --container:1092px;     /* design: content ~1456px on the 1920 canvas = 75.8% -> 75.8% of 1440 */
  --grid-gap:30px;        /* news/tiles (design ~30px, measured 30) */
  --grid-gap-wide:28px;   /* location cards (design ~36px) */
  --section-gap:105px;    /* uniform whitespace between content sections (~115px visual, XD range 96-136) */
  --fs-h1:46px;           /* page title — XD Typografie sheet: 46 desktop / 32 mobile */
  --fs-h2:36px;           /* section headings — XD Typografie sheet: 36 desktop / 24 mobile */
  --content-col:65.85%;   /* single content column: prose, dividers and inline images all end on the
                             same vertical (XD measured 115..594.5 of 115..844 = 719px of the container) */
}
*{box-sizing:border-box}
html,body{margin:0}
/* The mega-menu dropdowns are absolutely positioned and, while hidden, their box can
   reach past the right edge at some widths (~1024px), adding a phantom horizontal
   scrollbar. Clip the horizontal axis only — the dropdowns still open downwards.
   `clip` (not `hidden`) avoids turning the root into a scroll container. */
html,body{overflow-x:clip}
body{font-family:var(--font); color:var(--ink); background:#fff; font-size:var(--fs-lead); line-height:var(--lh-lead)}  /* XD content copy 18/27; chrome sets its own sizes */
/* `height:auto` is not cosmetic. WordPress prints the intrinsic size as width/height
   attributes on every the_post_thumbnail() image, and those attributes act as
   presentational hints for the CSS width and height. A rule that sets only the width
   therefore leaves the height pinned to the attribute, which both defeats aspect-ratio
   (it is ignored once both axes are definite) and stretches the image. Releasing the
   height here lets each component decide the box, either with aspect-ratio or with an
   explicit height. */
img{display:block; max-width:100%; height:auto}
a{color:inherit; text-decoration:none}
.container{max-width:var(--container); margin:0 auto; padding:0}  /* content aligns at the container edge (matches XD); side padding only on narrow screens */
@media(max-width:1140px){ .container{padding:0 24px} }
@media(max-width:860px){
  /* Mobile scale measured on the XD phone artboards: narrower gutters and smaller headings. */
  :root{--content-col:100%; --fs-h1:32px; --fs-h2:24px; --fs-lead:16px; --lh-lead:24px}
  .container{padding:0 16px}
}
/* Content buttons are pills (25px radius from the design); the top bar makes them square
   (override below). Design height 47px -> ~37px (x0.79); padding tuned for that height. */
/* Button text: bold, design 18px -> 14px (x0.79), centred */
/* `font:inherit; border:0` so a <button> carrying .btn renders exactly like an <a> does: the
   language switcher trigger is a button (it opens a menu rather than navigating). */
.btn{display:inline-block; font-weight:700; border-radius:25px; padding:.85rem 1.9rem; font-size:14px; line-height:1.2; text-align:center; cursor:pointer; transition:background-color .15s,color .15s; font-family:inherit; border:0}
.btn--red{background:var(--red); color:#fff}
.btn--dark{background:var(--ink); color:#fff}
.btn--ghost{background:#fff; color:var(--ink)}  /* white pill, no border, bold 14px centred text */
/* XD button system: two content variants (white and red), identical sizing; both invert
   to black on hover and keyboard focus so the interaction is consistent site-wide. */
.btn--red:hover,.btn--red:focus-visible,
.btn--ghost:hover,.btn--ghost:focus-visible{background:var(--ink); color:#fff}
.link-arrow{color:var(--red); font-weight:700; font-size:.85rem}
/* The arrow link answers the pointer and the keyboard: it underlines and steps a little in the
   direction it points. Underline rather than a change of opacity or colour, because those two
   lower the contrast of a link that already sits at 4.9:1 on white and on red; an underline adds
   an affordance without touching it. The step is dropped for reduced motion, and the same rule
   covers every arrow on the site -- hero, news cards, facility cards, tiles and search results -- so
   they behave alike. The tile variant is a span inside a linked tile, hence the parent selector. */
/* At rest it carries no underline. Stated on the class rather than left to the `a` rule above,
   because in the editor canvas Bootstrap underlines every link at the same specificity and wins on
   load order -- the arrow would sit permanently underlined in the preview, which is the opposite of
   the point. The front end never loads Bootstrap, so there it changes nothing. */
a.link-arrow, .tile a .link-arrow, .card a .link-arrow{display:inline-block; transition:transform .15s; text-decoration:none}
a.link-arrow:hover,a.link-arrow:focus-visible,
a:hover .link-arrow,a:focus-visible .link-arrow{text-decoration:underline; text-underline-offset:3px}
a.link-arrow:hover,a:hover .link-arrow{transform:translateX(3px)}
[dir="rtl"] a.link-arrow:hover,[dir="rtl"] a:hover .link-arrow{transform:translateX(-3px)}
@media (prefers-reduced-motion:reduce){
  a.link-arrow,.tile a .link-arrow,.card a .link-arrow{transition:none}
  a.link-arrow:hover,a:hover .link-arrow,
  [dir="rtl"] a.link-arrow:hover,[dir="rtl"] a:hover .link-arrow{transform:none}
}
/* Long German compounds hyphenate (with a -) instead of overflowing on narrow screens;
   needs the document's lang="de". overflow-wrap is the fallback if no hyphenation. */
h1,h2,h3{font-weight:700; color:var(--ink); margin:0; -webkit-hyphens:auto; hyphens:auto; overflow-wrap:break-word}

/* ---------- Rhythm around a standard heading block ----------
   The reset above is right for the designed sections, which the XD spaces per section rather
   than per heading. It leaves the core heading block with nothing: a heading dropped between
   two paragraphs got the paragraph's own 18px and read as one more line of text.

   Scoped to standard pages and News entries by body class, which is where the editorial team
   writes free prose. Einrichtungen and Angebote are deliberately left out -- they lay their
   content out with their own section blocks, and a default margin would fight that design.

   More above than below, so the heading belongs to the text it introduces instead of floating
   between two blocks. The numbers come from the design rather than being picked: 25px below is
   the heading-to-content gap the section headings already use, and the space above is the same
   rhythm doubled. Note the bottom margin collapses with the following paragraph's own, which is
   why the pair reads 45/25 rather than 45/43. */
body.page :is(h1,h2,h3).wp-block-heading,
body.single-news :is(h1,h2,h3).wp-block-heading{margin-top:45px; margin-bottom:25px}
body.page h3.wp-block-heading,
body.single-news h3.wp-block-heading{margin-top:34px; margin-bottom:18px}
/* A heading that opens its container brings no space of its own: the container already spaces it. */
body.page :is(h1,h2,h3).wp-block-heading:first-child,
body.single-news :is(h1,h2,h3).wp-block-heading:first-child{margin-top:0}

/* ---------- Core blocks written straight onto the canvas ----------
   The AWO blocks carry the design's column on their own section. A core block does not, and the
   canvas template renders it exactly as the editor saved it, so a plain paragraph or heading ran
   the full width of the window -- text from edge to edge, with the footer correctly inset below
   it. These are offered to the editorial team on pages, News and Angebote, so they have to hold
   the same column as everything around them.

   The core blocks are listed one by one rather than matched on the wp-block- prefix. That prefix
   also covers our own blocks and the theme's, and some of them are full-bleed by design: matching
   it took the red band off the home page hero, which spans the window on purpose. A design block
   is not a stray core block, and the selector has to be able to tell them apart. */
main > .wp-block-paragraph,
main > .wp-block-heading,
main > .wp-block-list,
main > .wp-block-image,
main > .wp-block-quote,
main > .wp-block-table,
main > .wp-block-buttons,
main > .wp-block-columns,
main > .wp-block-separator{max-width:var(--container); margin-left:auto; margin-right:auto}
@media(max-width:1140px){
  main > .wp-block-paragraph, main > .wp-block-heading, main > .wp-block-list, main > .wp-block-image,
  main > .wp-block-quote, main > .wp-block-table, main > .wp-block-buttons, main > .wp-block-columns,
  main > .wp-block-separator{padding-left:24px; padding-right:24px}
}
@media(max-width:860px){
  main > .wp-block-paragraph, main > .wp-block-heading, main > .wp-block-list, main > .wp-block-image,
  main > .wp-block-quote, main > .wp-block-table, main > .wp-block-buttons, main > .wp-block-columns,
  main > .wp-block-separator{padding-left:16px; padding-right:16px}
}

section{padding:47px 0}  /* gap between sections ~94px (design 119.24 x0.79) */
/* Section headings: bold, design 50px/62px -> 40px/49px (x0.79), color #000 */
/* Section heading H2 (News, Jobs, Ehrenamt...): design 42/44 x0.79 -> 33/35, #171717 */
.section-h{font-size:var(--fs-h2); line-height:1.05; color:var(--ink); margin-bottom:25px}  /* gap heading->content design 31.34 x0.79 */
/* Large variant (Was wir machen): design 50/62 x0.79 -> 40/49, #000 */
.section-h--lg{font-size:40px; line-height:49px; color:#000}
.center{text-align:center; margin-top:75px}  /* gap cards->Alle News: design 94.96px x0.79 */
.center .btn{min-width:210px; padding-top:.62rem; padding-bottom:.62rem}  /* wide CTA pill */

/* ---------- Header ---------- */
/* Own stacking context above the logo row, so the language dropdown (absolutely
   positioned inside the bar) paints over the header instead of behind the logo. */
.topbar{font-size:1rem; position:relative; z-index:20}
/* No vertical padding: the buttons run to the top edge (XD); the text links center. */
.topbar__inner{display:flex; justify-content:flex-end; align-items:stretch; gap:1.25rem; padding:0}
.topbar a:not(.btn){color:var(--ink); font-weight:700; align-self:center}  /* XD: service links bold */
.topbar a:not(.btn):hover{text-decoration:underline}
.topbar .btn:hover{text-decoration:none}
/* Spenden + Sprache wählen: touching rectangles (two-tone bar), matching the design */
.topbar .btn{border-radius:0; padding:.5rem 1.1rem; display:flex; align-items:center}
.topbar .lang{margin-left:-1.25rem}  /* design: Spenden and Sprache wählen touch, no seam */
/* Sprache wählen dropdown — design: black box flush to the button (no gap, no border,
   no shadow), white text, red hover. Width = the button's. */
.lang{position:relative}
.lang-menu{position:absolute; right:0; top:100%; min-width:100%; background:var(--ink); z-index:60;
  opacity:0; visibility:hidden; transition:opacity .15s}
/* Opens on hover (pointer) and on click/keyboard via .is-open (set by mobile-nav.js),
   so the switcher works without a mouse. */
.lang:hover .lang-menu,.lang.is-open .lang-menu{opacity:1; visibility:visible}
/* `.topbar a:not(.btn)` paints the text dark and wins on specificity, so match that
   specificity here to keep the text white on the black box. */
.topbar .lang-menu a{display:block; padding:.42rem 1.1rem; color:#fff; font-weight:700; white-space:nowrap}
.topbar .lang-menu a:hover{background:var(--red); color:#fff; text-decoration:none}
.header{display:flex; align-items:center; justify-content:space-between; padding:.8rem 0 4rem; position:relative}  /* white space below the nav (airy header from the design) */
/* Inner pages (News, Angebote, ...) carry a red rule under the header ("Rote Trennlinie");
   the homepage does not — it opens straight into the hero. Pages opt in with body.inner. */
body.inner header{border-bottom:5px solid var(--red)}  /* design annotation: red 5px rule ("Rote Trennlinie") */
.logo{display:flex; align-items:center; gap:.7rem}
.logo img{height:50px; width:auto}
/* Main navigation with dropdown (mega-menu) */
.mainnav{display:flex; gap:1.8rem; font-weight:700; font-size:1.25rem; list-style:none; margin:0; padding:0}
.mainnav > li{position:relative}
.mainnav > li > a{display:inline-block; padding:.5rem 0}
.mainnav > li:hover > a,.mainnav > li.is-active > a{color:var(--red)}
/* Fill and text sampled from the design render: box #F6F6F6 (not white), text
   #343A40 (not #171717), top rule #BEBFC0 and a soft shadow below. */
.submenu{position:absolute; top:100%; left:-14px; min-width:248px; background:var(--light);
  border-top:1px solid #BEBFC0; box-shadow:0 10px 28px rgba(0,0,0,.13); z-index:50; padding:.3rem 0;
  opacity:0; visibility:hidden; transform:translateY(6px); transition:.15s}
/* The last item sits at the content edge: if its dropdown opened to the right it would
   spill past the container and cover the accessibility icon. The design shows it
   right-aligned with the item. */
.mainnav > li:last-child .submenu{left:auto; right:0}
.mainnav > li:hover .submenu{opacity:1; visibility:visible; transform:translateY(0)}
/* Submenu body measured on the design render: cap height 6px against the 7px of the
   main nav (render at 0.5x) -> ~0.86 of the main nav body. The spec sheet notes "18pt"
   at both levels, but the pixels say otherwise. */
.submenu a{display:block; padding:.62rem 1.1rem; font-weight:600; font-size:17px; color:var(--dark); white-space:nowrap}
.submenu a + a{border-top:1px solid var(--border)}
.submenu a:hover,.submenu a.is-active{background:var(--red); color:#fff}
/* Accessibility (Barrierefreiheit) icon from the design. */
/* Pinned to the right edge of the viewport (bleed zone, ~10px from the edge, design "10"),
   not to the 1200 content edge (where "Presse" ends). The min() caps it below 1200px. */
.a11y{position:absolute; right:min(10px, calc((var(--container) - 100vw)/2 + 10px)); top:calc(100% - 54px);
  z-index:10; width:40px; height:40px; border:0; font-size:0;  /* XD ~40×40, floating fully in the white header zone, above the red rule */
  background:url(img/a11y.webp) center/contain no-repeat}

/* ---------- Split (Jobs / Ehrenamt / Kontakt) ----------
   Wide image + red box overlaid and vertically centred. Design: img 961x568,
   box 615x462 -> x0.79: img 65.8%/449px, box 42.1%/365px (overlap ~92px). */
.split{position:relative; min-height:468px}                          /* design image 568 x0.824 */
.split__img{width:61%}                                               /* design 888 / content 1456 */
.split__img img{width:100%; height:468px; object-fit:cover; display:block}  /* design 568 x0.824 */
.split__box{position:absolute; right:0; top:50%; transform:translateY(-50%); width:42.2%; min-height:381px;  /* design box 615x462 x0.824 */
  background:var(--red); color:#fff; padding:50px 78px; display:flex; flex-direction:column; justify-content:center}  /* design side padding ~98 x0.79 */
.split__box h2{color:#fff; font-size:var(--fs-h2); line-height:1.05; margin-bottom:1rem}   /* design 42/44 x0.79 */
.split__box p{font-size:14px; line-height:21px; font-weight:400; opacity:.95; margin:0 0 2.2rem}  /* more air text->button, per the updated XD */
/* Ehrenamt = mirrored: image on the right, box on the left */
.split--rev .split__img{margin-left:auto}
.split--rev .split__box{right:auto; left:0}
/* XD annotation on the photo credit placeholder: font-size 10px, #000 */
.credit{font-size:14px; color:#000; margin-top:.3rem}
/* Kontakt teaser: shared split styling; content stays per page (differs) */
.kontakt .split__box{justify-content:center}
.kontakt .split__box h2{color:#fff}
.kontakt .split__box p{color:#fff; margin:.15rem 0}
.kontakt .split__box p.kontakt__name{font-weight:700}  /* beats .split__box p above; here and not in content.css, which the Jugendwerk page does not load */
/* Phone and mail are links: same treatment as the footer's red bar, which is the other
   place white text on red carries them. The underline is what marks them as links where
   colour cannot (WCAG 1.4.1). */
.kontakt .split__box a{color:inherit; text-decoration:underline; text-underline-offset:2px}
.kontakt .split__box a:hover,.kontakt .split__box a:focus-visible{text-decoration:none; opacity:.85}

/* ---------- Breadcrumb (inner pages) ----------
   Same trail on every inner page (News, Angebote, Kitas, ...), so it lives here once. */
.breadcrumb{color:var(--gray); font-size:12px; padding-top:1.2rem}  /* XD ~11px */
/* XD: the navigable pages are underlined links (Startseite, News); the dropdown
   category (Presse) and the current page are plain text, not links. */
.breadcrumb a{color:inherit; text-decoration:underline}

/* ---------- News cards (shared) ----------
   Same card on the home News teaser and on every News/Presse listing, so it lives
   here once. XD: subtle shadow, no border ("Kleiner Schatten unter jeder Newskachel");
   the body is a column and "weiter lesen" is pinned to the bottom so the links line up
   across a row regardless of title length. */
.cards{display:grid; grid-template-columns:repeat(3,1fr); gap:var(--grid-gap)}
.card{background:#fff; box-shadow:0 4px 16px rgba(0,0,0,.10); display:flex; flex-direction:column}
/* The thumbnail box is fixed by the ratio, never by the photo: portrait and landscape
   uploads have to produce the same card height so a row lines up. `height:auto` is
   repeated here on purpose, so the ratio holds even if this component is ever used on a
   page that does not load the base reset above. */
.card img{width:100%; height:auto; aspect-ratio:3/2; object-fit:cover}
.card__body{padding:1rem 1.1rem 1.2rem; display:flex; flex-direction:column; flex:1}
.card__date{color:var(--ink); font-size:14px; line-height:21px; font-weight:400; margin-bottom:.5rem}
.card__title{font-size:19px; line-height:22px; font-weight:700; margin-bottom:.9rem}
.card .link-arrow{font-size:14px; line-height:20px; margin-top:auto}
/* Card hover: a smooth zoom on the thumbnail (matches the Einrichtungen/Angebote cards).
   This lives here rather than in news.css because the same card renders on the start page,
   which loads design.css but not the news stylesheet. WCAG AA: colour/contrast unchanged;
   the zoom is clipped by the link wrapper and suppressed under prefers-reduced-motion. */
.card>a{display:block; overflow:hidden}
.card>a img{transition:transform .3s ease}
.card:hover>a img,.card:focus-within>a img{transform:scale(1.05)}
@media(prefers-reduced-motion:reduce){
  .card>a img{transition:none}
  .card:hover>a img,.card:focus-within>a img{transform:none}
}
@media(max-width:860px){ .cards{grid-template-columns:1fr 1fr} }
@media(max-width:560px){ .cards{grid-template-columns:1fr} }

/* ---------- News listing (Übersicht / Archiv) ----------
   Page intro, Themen filter (custom dropdown) and pager. Shared by both News listing
   variants, so it lives here once. */
/* The intro sits closer to the breadcrumb than a normal section would. This used to live in
   news.css, so only the News listings picked it up and the other listings carried their own
   inline value - which is how the archive pages ended up with different rhythms. */
.page-intro{padding-top:1.4rem}
.page-intro h1{font-size:var(--fs-h1); line-height:1.09; margin:.5rem 0 37px}  /* design: ~55px of space title->content */
.page-intro p{color:var(--ink2); max-width:820px; margin:0 0 .6rem}
/* The gap under the intro belongs to whatever follows it, which sets its own. Without this the
   last paragraph's own margin escapes the container and adds ~10px on top of that, so a page
   whose intro ends in a paragraph started 10px lower than one whose intro ends otherwise. */
.page-intro > *:last-child{margin-bottom:0}
/* An inline link in body copy is underlined and keeps the colour of the text around it, which is
   what the breadcrumb and the footer's contact details already do. The design draws this one
   without any mark at all, and it was built that way -- but a link that looks exactly like the
   sentence it sits in cannot be recognised as a link, which is the failure WCAG 1.4.1 describes.
   Colour is deliberately not the signal: the brand red reaches 4.94:1 on white, but only 2.63:1
   against the body text it would sit in, short of the 3:1 that colour needs to identify a link on
   its own. Red is also the arrow links' own convention. The underline carries it instead. */
.page-intro p a{color:inherit; text-decoration:underline; text-underline-offset:2px; font-weight:inherit}
.page-intro p a:hover,.page-intro p a:focus-visible{color:var(--red)}

/* The same for the text the editorial team writes. The link tool in the section blocks produced
   links with no mark at all -- measured on a facility page, a link inside "Individueller Text"
   rendered exactly like the sentence around it -- so the tool we gave editors for adding links
   made links nobody could see. Buttons and arrow links are excluded: they carry their own shape
   and their own colour. */
.awo-prose p a:not(.btn):not(.link-arrow),
.kprose p a:not(.btn):not(.link-arrow),
.prose p a:not(.btn):not(.link-arrow){text-decoration:underline; text-underline-offset:2px}
.awo-prose p a:not(.btn):not(.link-arrow):hover,.awo-prose p a:not(.btn):not(.link-arrow):focus-visible,
.kprose p a:not(.btn):not(.link-arrow):hover,.kprose p a:not(.btn):not(.link-arrow):focus-visible,
.prose p a:not(.btn):not(.link-arrow):hover,.prose p a:not(.btn):not(.link-arrow):focus-visible{color:var(--red)}
/* The space after the intro is the same whether a section heading or the filter bar follows it,
   so listings with a heading (Angebote, Einrichtungen) keep the rhythm of those without (News). */
.page-intro .section-h{margin-top:1.8rem}
/* The same space when the heading comes from the listing block rather than from the intro area
   (KKZAWO-148). The rule above only reaches a heading inside .page-intro, so the block's own
   optional title landed with no margin at all -- measured on /kitas/, 0px between the intro text
   and the heading, against 28.8px on the pages whose heading sits in the intro. Named per block
   rather than added to .section-h itself: that class is shared with the tile grid, the split
   section, the prose block and the facility page, which set their own spacing and would all
   shift. */
.wp-block-awo-einrichtung-list > .section-h,
.wp-block-awo-news-list > .section-h,
.wp-block-awo-angebot-list > .section-h{margin-top:1.8rem}
.nfilter{display:flex; gap:1rem; flex-wrap:wrap; margin:1.8rem 0 3rem}  /* XD: more air filter->grid */
/* The entries of a listing sit in their own section so the grid can run the full width, but the
   space above them is the one the filter bar already carries. Without this the generic section
   padding would be added on top and each listing would drift by whatever inline value it was
   given (the reason the four archive pages had four different rhythms). */
.awo-list{padding-top:0}
/* A native <select> cannot style its open list; XD wants a red-bordered field with a
   filled black triangle and a light-gray panel with a black-highlighted option. */
.nselect{position:relative; display:inline-block; width:calc((100% - 2*var(--grid-gap))/3)}
.nselect__btn{display:flex; align-items:center; justify-content:space-between; gap:1rem; width:100%;
  padding:.9rem 1.1rem; border:1px solid var(--red); border-radius:0; background:#fff;
  font-size:1rem; font-weight:400; color:var(--ink); cursor:pointer; text-align:left}
.nselect__btn .tri{flex:none; width:12px; height:8px;
  background:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='9' viewBox='0 0 14 9'%3E%3Cpath d='M0 0h14L7 9z' fill='%23171717'/%3E%3C/svg%3E") center/contain no-repeat}
/* The Ort variant of the dropdown: the design draws a thin chevron here where the Themen filter
   uses a filled triangle. It sits with the component rather than with one page's stylesheet
   because two listings use it -- facilities and offers -- and the offers page does not load the
   facilities sheet. */
.nselect--ort .tri{width:14px; height:9px;
  background:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='9' viewBox='0 0 14 9'%3E%3Cpath d='M1 1.5l6 6 6-6' fill='none' stroke='%23171717' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center/contain no-repeat}
.nselect__list{position:absolute; left:0; right:0; top:100%; margin-top:4px; z-index:40;
  background:var(--light); list-style:none; padding:.4rem 0; display:none}
.nselect.is-open .nselect__list{display:block}
.nselect__list li{padding:.6rem 1.1rem; color:var(--ink); font-size:1rem; cursor:pointer}
.nselect__list li[aria-selected="true"],.nselect__list li:hover{background:var(--ink); color:#fff}
.pager{display:flex; justify-content:center; align-items:center; gap:.5rem; margin-top:6.5rem}  /* XD: generous air cards->pager */
.pager a{width:38px; height:38px; border:1px solid var(--border); border-radius:50%; display:flex; align-items:center; justify-content:center; color:var(--ink); font-weight:700; font-size:.9rem}
.pager a.is-active{background:var(--red); border-color:var(--red); color:#fff}
/* Arrows are loose (no circle), thin-stroked SVG chevrons; left black, right red. */
.pager a.arrow{width:auto; height:auto; border:0; border-radius:0; padding:0; line-height:0}
.pager a.arrow svg{display:block; width:19px; height:32px}
.pager a.arrow--prev{color:var(--ink); margin-right:.5rem}
.pager a.arrow--next{color:var(--red); margin-left:.5rem}
@media(max-width:860px){ .nselect{width:calc((100% - var(--grid-gap))/2)} }
/* Mobile: the design shows a compact pager (arrows + first pages only) and less air above it. */
@media(max-width:560px){ .nselect{width:100%} .pager a.pg-more{display:none} .pager{margin-top:3rem} }

/* ---------- Footer ---------- */
/* Footer — scaled x0.79. Red bar design 434.46->343px, footlinks design 62.73->50px */
.footlinks{display:flex; flex-wrap:wrap; gap:1.75rem; justify-content:flex-end; align-items:center; margin-top:138px; margin-bottom:28px; min-height:50px; font-size:16px; font-weight:700; color:#171717}  /* gap content->footlinks: design 175 x0.79; gap footlinks->red bar */
.footlinks a{color:#171717; transition:color .15s}
/* Same hover feedback as the header navigation, for a consistent interaction. */
.footlinks a:hover,.footlinks a:focus-visible{color:var(--red)}
.footbar{background:var(--red); color:#fff}
.footbar__inner{display:grid; grid-template-columns:1.4fr .8fr 1fr; align-items:start; gap:2.5rem; min-height:343px; padding:56px 0}  /* horizontal 0 -> aligns with content edge (174), like the rest */
.footbar .col h2{font-size:14px; margin:0 0 .95rem; font-weight:700; line-height:1.2; color:#fff}  /* headings carry their own colour, so the white of .footbar does not reach them */
/* Contact links: same treatment as the red box on the Einrichtung page -- underlined so they are
   distinguishable without relying on colour (WCAG SC 1.4.1), and the underline gives way on hover. */
.footbar__contact a{color:inherit; text-decoration:underline; text-underline-offset:2px}
.footbar__contact a:hover,.footbar__contact a:focus-visible{text-decoration:none; opacity:.85}
.footbar .col:last-child h2{margin-bottom:1.5rem}  /* more space 'Veranstaltungen:' -> logo (design) */
.footbar .col p{font-size:14px; margin:0 0 .9rem; line-height:24px; color:#fff}  /* design 18/30 x0.79 */
.footbar .col p.footbar__org{margin-bottom:1.7rem}  /* more space heading->address (design desktop) */
.footbar__org strong{font-weight:700; font-size:16px; line-height:1.2}
.social{display:flex; flex-direction:column; gap:.8rem}
.social a{width:59px;height:59px;display:flex;align-items:center;justify-content:center}
/* Social and sponsor logos: official client assets (white, transparent). */
.social img{width:52px;height:52px;display:block}
.sponsor{display:flex; align-items:center; gap:.7rem}
.sponsor__logo{display:flex; align-items:center; flex:0 0 auto}
/* The Sparkasse logo already contains the wordmark — no separate text block. */
.sponsor__logo img{height:74px; width:auto; display:block}  /* design: prominent logo */

@media(max-width:860px){
  .mainnav{display:none}
  .split{min-height:0}
  .split__img{width:100%}
  .split__img img{height:300px}
  /* Stack image over box in both variants, with the separation the design shows
     (measured 16px on the mobile artboard). The previous -40px pulled the box up
     over the section heading whenever the box came first in the source. */
  .split{display:flex; flex-direction:column}
  .split__img{order:1}
  /* The photo credit is not shown under the split images on mobile (Jobs, Ehrenamt);
     the design has the image run straight into the red box. */
  .split .credit{display:none}
  /* The desktop box padding (78px sides) is far too wide for a phone, squeezing the
     heading into six narrow lines. The mobile artboard uses ~30px sides. */
  .split__box{order:2; position:static; transform:none; width:100%; min-height:0;
    margin-top:16px; padding:40px 30px}
  /* The red bar is full-width (no side or bottom margin — it runs to the page edge
     and to the bottom), with only a gap above it after the service links. */
  .footbar{margin:24px 0 0}
  .footbar__inner{grid-template-columns:1fr; gap:1.6rem; padding-left:24px; padding-right:24px}
  /* Service links stack in a left-aligned column, as the mobile design shows,
     instead of the right-justified rows the desktop layout uses. */
  /* Column list aligned to the content edge (the .container already provides the 24px
     side padding — no extra indent). More air above and between the rows, per the XD. */
  .footlinks{flex-direction:column; align-items:flex-start; gap:1.15rem; margin-top:5rem}
  /* Sparkasse logo a touch larger and with more air above it, as in the design. */
  .sponsor__logo img{height:56px}
  /* Address and contact run as one continuous block on mobile (the desktop design
     keeps them as two separate paragraphs; mobile joins them). */
  .footbar .col .footbar__org + p{margin-bottom:0}
}
/* ---------- Mobile navigation ----------
   Below the breakpoint the design swaps the hover menu for a panel: a toggle opens
   the navigation, each section expands in place, and the service links and buttons
   from the top bar move underneath. The markup is the same as on desktop; only the
   layout changes, so there is a single navigation in the DOM. */
/* The open mobile panel's service row. Hidden by default, and the default is what matters:
   declared only inside the mobile media query it would fall back to display:block above the
   breakpoint, which put a second "Leichte Sprache" on every desktop page. */
.navservice{display:none}

.navtoggle{display:none; width:44px; height:44px; padding:0; border:0; background:none; cursor:pointer;
  position:relative; flex:0 0 auto}
.navtoggle span, .navtoggle::before, .navtoggle::after{content:''; position:absolute; left:10px; right:10px;
  height:3px; background:var(--ink); transition:.2s}
.navtoggle span{top:20px}
.navtoggle::before{top:12px}
.navtoggle::after{top:28px}
/* Open state: the bars become the red cross of the design. */
header.is-open .navtoggle span{opacity:0}
header.is-open .navtoggle::before{top:20px; transform:rotate(45deg); background:var(--red)}
header.is-open .navtoggle::after{top:20px; transform:rotate(-45deg); background:var(--red)}
/* The submenu expanders are built by the script for both layouts. On desktop they are a
   small caret beside the top-level link and give the mega-menu a click/keyboard toggle,
   so it no longer relies on hover alone (hover stays as a pointer enhancement). */
.subtoggle{display:inline-flex; align-items:center; justify-content:center; width:1.5em; height:1.5em;
  margin-left:.15em; padding:0; border:0; background:none; color:inherit; cursor:pointer; vertical-align:middle}
.subtoggle::after{content:''; width:8px; height:8px; margin-top:-3px;
  border-right:2px solid currentColor; border-bottom:2px solid currentColor; transform:rotate(45deg)}
.mainnav > li.is-open > a,.mainnav > li.is-open .subtoggle{color:var(--red)}
.mainnav > li.is-open .subtoggle::after{margin-top:2px; transform:rotate(-135deg)}
.mainnav > li.is-open .submenu{opacity:1; visibility:visible; transform:translateY(0)}

@media(max-width:860px){
  header{display:flex; flex-direction:column}

  /* The service bar stays on top in both states. It used to swap places with
     the logo row when the panel opened, which moved the bar below the menu and carried the
     toggle 33px up the screen, so the X appeared somewhere other than the hamburger the
     visitor had just pressed. Keeping the order fixed also means Spenden, Sprache wählen,
     Jobs and Suche stay reachable at the top while the menu is open, so the panel no longer
     repeats them underneath. */
  .topbar{order:1}
  /* The logo row is a .container, whose `margin:0 auto` in this flex column shrinks
     it to its content and centres it, leaving the hamburger 43px from the edge.
     Force full width with a small side padding so the logo sits left and the
     hamburger tucks against the right edge (~16px), as in the design. */
  .header{order:2; width:100%; margin:0; padding:.8rem 16px 1rem; flex-wrap:wrap}

  .navtoggle{display:block; margin-left:auto}

  /* "Leichte Sprache" is dropped from the bar at this width for room, and it was hidden in
     the open panel as well -- measured, display:none in both states, so on a phone there was
     no way to reach it at all. It goes at the end of the panel, which is where the design
     puts its service row too.
     The accessibility-statement icon stays hidden here on purpose: that page does not exist
     yet, so the link is not rendered at all and there is nothing to place or verify. */
  .a11y{display:none}
  .navservice{display:none}
  header.is-open .navservice{display:flex; flex-basis:100%; order:4; align-items:center;
    gap:1.5rem; padding:1.1rem 0 .2rem}

/* The list sits inside a <nav>, so that wrapper is the flex item that has to span
     the row; and the panel has to re-assert display, because the mockup's earlier
     rule hides .mainnav outright at this width. */
  .header > nav{flex-basis:100%; order:3}
  header:not(.is-open) .header > nav{display:none}
  /* Air between the logo row and the first entry: measured, the first row's border started at
     the exact bottom of the logo, with nothing between them. In rem rather than px so the gap
     grows with the visitor's default font size, as the rest of the spacing here does; a px value
     would stay 20px while the text around it got larger. */
  header.is-open .header > nav{padding-top:1.25rem}
  header.is-open .mainnav{display:flex}
  .mainnav{flex-basis:100%; flex-direction:column; gap:0; font-size:1.4rem}
  .mainnav > li{border-bottom:1px solid var(--border); display:flex; flex-wrap:wrap; align-items:center}
  .mainnav > li > a{flex:1; padding:.9rem 0}
  .mainnav > li.is-open > a{color:var(--red)}

  /* The chevron the design puts at the end of each row. */
  .subtoggle{display:block; width:44px; height:44px; border:0; background:none; cursor:pointer; position:relative; flex:0 0 auto}
  .subtoggle::after{content:''; position:absolute; top:16px; left:14px; width:11px; height:11px;
    border-right:2px solid var(--ink); border-bottom:2px solid var(--ink); transform:rotate(45deg)}
  .mainnav > li.is-open .subtoggle::after{transform:rotate(-135deg); border-color:var(--red); top:20px}

  /* Submenus sit in the flow instead of floating, and only when expanded. */
  .submenu{position:static; opacity:1; visibility:visible; transform:none; transition:none;
    flex-basis:100%; min-width:0; background:none; border-top:0; box-shadow:none; padding:0 0 .6rem; display:none}
  .mainnav > li.is-open .submenu{display:block}
  .mainnav > li:last-child .submenu{right:auto}
  .submenu a{padding:.5rem 0 .5rem 1.2rem; border:0; font-size:1rem}
  .submenu a + a{border-top:0}
  .submenu a:hover,.submenu a.is-active{background:none; color:var(--red)}

  /* Closed service bar. The mobile design drops "Leichte Sprache" (only Jobs and
     Suche remain), the two buttons touch each other and the bar reaches the top
     edge with no margin — the buttons run to y=0. */
  /* Full-width light-gray service band. Jobs/Suche sit on the left, aligned with the
     content margin; Spenden + Sprache wählen are flush to the right edge, touching. */
  .topbar{font-size:1rem; background:var(--light)}
  /* Spacing comes from explicit margins, not from `gap` cancelled by a negative margin:
     the bar has to survive a 360px screen, and gap+(-gap) left it 1px over the viewport. */
  .topbar__inner{flex-wrap:nowrap; align-items:stretch; justify-content:flex-start;
    gap:0; padding:0 0 0 14px}
  /* "Leichte Sprache" is the first link; it is not in the mobile bar. */
  .topbar__inner > a:not(.btn):first-child{display:none}
  .topbar a:not(.btn){white-space:nowrap; align-self:center; margin-right:16px}
  /* Tightened for the 16px bar so it survives a 320px screen. */
  .topbar .btn{padding:.5rem .55rem; white-space:nowrap; display:flex; align-items:center}
  /* Push the two buttons to the right edge; they sit flush against each other. */
  .topbar .btn--red{margin-left:auto}
  .topbar .lang{margin-left:0}
  /* Very narrow phones (320px): tighten the left group rather than drop links. */
  @media(max-width:359px){
    .topbar__inner{padding-left:2px}
    .topbar a:not(.btn){margin-right:6px}
    .topbar .btn{padding:.5rem .38rem}
  }
  .topbar .lang .btn{height:100%}
  /* The design's mobile bar has no dropdown caret on "Sprache wählen". */
  .topbar .caret{display:none}

  /* Nothing changes in the bar when the panel opens (KKZAWO-153). It used to become the
     panel's footer -- buttons at flex-basis:100%, links alongside -- but the container kept
     flex-wrap:nowrap from the closed layout, so instead of stacking, everything was forced
     onto one line: measured at 375px, "Suche" ended 53px past the right edge and was simply
     cut off. Leaving the bar alone removes the duplication and the overflow at once. */
  /* Overlay the bar (absolute, high z-index) instead of pushing the row down, and open
     on tap via .is-open rather than hover — the reported mobile issues (content shift +
     dropdown hidden behind the logo). */
  .lang-menu{position:absolute; right:0; top:100%; min-width:100%; opacity:1; visibility:visible;
    z-index:120; display:none}
  .lang.is-open .lang-menu{display:block}
}
/* Text for screen readers only. WordPress happens to define this in a core
   stylesheet, but the canvas drops most of what the theme loads and the static
   mockup has no such stylesheet at all, so declare it here rather than depend on
   whichever sheet happens to be present. */
.screen-reader-text{position:absolute; width:1px; height:1px; padding:0; margin:-1px;
  overflow:hidden; clip:rect(0,0,0,0); white-space:nowrap; border:0}

/* ---------- Vertical spacing (awo/spacer) ----------
   A gap chosen from the design's scale, never typed. The height arrives as the preset's own
   variable, so changing the scale changes every gap on the site instead of leaving numbers behind
   in the content.

   On narrow screens the same choice is worth less room: the scale is calibrated against a 1092px
   column, and a 5rem gap that reads as a section break on a desktop swallows a phone screen. The
   factor is applied here, once, rather than offered as a second field -- the editorial team picks
   a size, not a size per device. */
.awo-spacer{height:var(--awo-spacer-size);flex:none}
@media(max-width:860px){
  .awo-spacer{height:calc(var(--awo-spacer-size) * .6)}
}

/* The editor draws the gap to scale with a label, so an empty block is not an empty box. */
.awo-spacer-edit__bar{background:repeating-linear-gradient(135deg,#f3f3f3,#f3f3f3 6px,#e9e9e9 6px,#e9e9e9 12px);border:1px dashed #c9c9c9}
.awo-spacer-edit__label{display:block;margin-top:.25rem;font-size:12px;color:var(--ink2)}
