/*
Theme Name: AStA Gwyneth
Version: 1.0
Description: AStA Universität Lüneburg child theme for Gwyneth
Template: gwyneth
Author: AStA Universität Lüneburg
Text Domain: asta-gwyneth
*/

@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;
  }
}

/* A4: Keep the parent skip links visible with the secondary focus outline. */
.menu-skip-links a:focus-visible {
  background-color: var(--wp--preset--color--contrast) !important;
  color: var(--wp--preset--color--base) !important;
  outline: 2px solid var(--wp--preset--color--secondary);
  outline-offset: 2px;
}

@media (prefers-color-scheme: dark) {
  body {
    --wp--preset--color--base: #1A1A2E;       /* dark main surface (MMM #1A1A2E) */
    --wp--preset--color--base-alt: #F5F3FF;     /* light alt for cards/contrast regions */
    --wp--preset--color--contrast: #FFFFFF;     /* white text on dark (≥4.5:1 vs base) */
    --wp--preset--color--contrast-alt: #0F0D1A; /* near-black for light-alt regions */
    --wp--preset--color--primary-mixed: #2e1065;
    --wp--preset--color--secondary-mixed: #1e3a8a;
    /* C-10: primary (#6D28D9) on the dark base measures 2.40:1 — below the
       3:1 AA large-text floor. Headings resolve through this token; light
       surfaces keep the default primary. */
    --asta-heading-color: #A78BFA;              /* 6.27:1 vs #1A1A2E */
  }

  /* The dark surface is `base` (#1A1A2E). theme.json binds the body text to
     `contrast-alt` and post-title links resolve to `primary`/`secondary`; on the
     dark surface those measure 1.13:1 and 2.40:1, i.e. body copy is effectively
     invisible. `contrast-alt` has to stay near-black because it is also the
     background of the always-dark regions (header script bar, language bar), so
     the body colour is rebound for this surface instead. `html body` wins on
     specificity over the generated `body` rule. */
  html body {
    color: var(--wp--preset--color--contrast);
  }

  html body .wp-block-post-title a,
  html body .wp-block-post-excerpt__excerpt,
  html body .wp-block-post-excerpt__more-link,
  html body .wp-block-read-more,
  html body .wp-block-post-date {
    color: var(--wp--preset--color--contrast);
  }

  html body .wp-block-post-excerpt__more-link,
  html body .wp-block-read-more,
  html body .wp-block-post-title a {
    text-decoration: underline;
  }

  /* Blocks that paint their own light surface keep dark text, otherwise the
     rebound body colour above would sit white-on-light. `a` is restored to the
     primary accent, which clears 4.5:1 on this surface. */
  html body .has-base-alt-background-color,
  html body .has-base-alt-background-color * {
    color: var(--wp--preset--color--contrast-alt);
  }

  html body .has-base-alt-background-color a {
    color: var(--wp--preset--color--primary);
    text-decoration: underline;
  }

  /* C-10b: theme.json binds body links to secondary (#3B82F6), which measures
     3.66:1 on the dark base. Content links resolve to blue-400 (6.71:1).
     C-15: links on light base-alt cards are excluded — they keep `primary`
     via the base-alt rule above (#60A5FA measured 2.31:1 on #F5F3FF). */
  html body .wp-block-post-content a:not([class*="-color"]):not(.has-base-alt-background-color a):not(.insta-fallback) {
    color: #60A5FA;
  }

  /* C-22: no-JS dark fallback — cancel the light gradient default below
     unless a manual override already forced light (that class rule must
     still win here too). */
  html:not(.asta-theme-light) .wp-block-cover:not(:has(.wp-block-cover__image-background, video.wp-block-cover__video-background)) > .wp-block-cover__background.has-contrast-alt-background-color {
    background-image: none;
  }
}

/* C-09: the `contrast` overlay token inverts to white in dark mode, so covers
   that bind it end up with auto-white cover text on light grey (measured
   2.52:1). Bind cover overlays that use `contrast` to the scheme-stable
   `contrast-alt` (near-black in both schemes); for image-less covers raise the
   dim to a legibility floor so the 1.25rem subtitle clears 4.5:1 (9.15:1 light,
   17.4:1 dark). The floor also applies to `contrast-alt` covers because the
   generated dim utility resolves through an opacity custom-property that can
   land on the 0.5 default. */
.wp-block-cover__background.has-contrast-background-color {
  background-color: var(--wp--preset--color--contrast-alt) !important;
}

.wp-block-cover:not(:has(.wp-block-cover__image-background, video.wp-block-cover__video-background)) > .wp-block-cover__background.has-contrast-background-color,
.wp-block-cover:not(:has(.wp-block-cover__image-background, video.wp-block-cover__video-background)) > .wp-block-cover__background.has-contrast-alt-background-color {
  opacity: 0.8;
}

/* C-22: the hero's no-image cover fallback bound `contrast-alt`, which is
   #1A1A1A light vs #0F0D1A dark — different hex, same perceived near-black
   in both schemes. Light mode gets the existing Figma-approved "Night Sky"
   gradient instead; dark mode's flat colour stays untouched. This is the
   default (also the no-JS/OS-light fallback, since light needs no explicit
   opt-in elsewhere in this file); the two rules cancelling it back to `none`
   wherever the effective scheme is dark sit next to their respective
   dark-scheme rules below. */
.wp-block-cover:not(:has(.wp-block-cover__image-background, video.wp-block-cover__video-background)) > .wp-block-cover__background.has-contrast-alt-background-color {
  background-image: var(--wp--preset--gradient--night-sky);
}

/* C-10: headings resolve through --asta-heading-color (default = primary, so
  light rendering is unchanged). Headings that carry any colour utility class
  (`has-*-color`, incl. cover white) keep their explicit colour; headings on
  light cards are already re-bound dark by the base-alt rule above. */
:root {
  --asta-heading-color: var(--wp--preset--color--primary);
}

html body :is(h1, h2, h3, h4, h5, h6):not([class*="-color"]):not(.has-text-color) {
  color: var(--asta-heading-color);
}

/* Cover text is white by construction; headings inside a cover must inherit
   that rather than resolve through the heading token (purple on grey fails). */
.wp-block-cover :is(h1, h2, h3, h4, h5, h6):not([class*="-color"]):not(.has-text-color) {
  color: inherit;
}

/* C-11: manual scheme override. The header toggle was a dead `<details>`
   control; dark mode is now JS-selectable (assets/dark-mode.js mirrors the
   effective scheme onto <html>) while the @media block above remains the
   no-JS fallback. Dependent rules are duplicated under the class because a
   media query cannot be entered by attribute; every colour is token-driven,
   so force-light under an OS-dark preference restores the light tokens and
   the media-gated rules resolve to the light palette. */
html.asta-theme-dark body {
  --wp--preset--color--base: #1A1A2E;
  --wp--preset--color--base-alt: #F5F3FF;
  --wp--preset--color--contrast: #FFFFFF;
  --wp--preset--color--contrast-alt: #0F0D1A;
  --wp--preset--color--primary-mixed: #2e1065;
  --wp--preset--color--secondary-mixed: #1e3a8a;
  --asta-heading-color: #A78BFA;
}

html.asta-theme-dark body {
  color: var(--wp--preset--color--contrast);
}

html.asta-theme-dark body .wp-block-post-title a,
html.asta-theme-dark body .wp-block-post-excerpt__excerpt,
html.asta-theme-dark body .wp-block-post-excerpt__more-link,
html.asta-theme-dark body .wp-block-read-more,
html.asta-theme-dark body .wp-block-post-date {
  color: var(--wp--preset--color--contrast);
}

html.asta-theme-dark body .wp-block-post-excerpt__more-link,
html.asta-theme-dark body .wp-block-read-more,
html.asta-theme-dark body .wp-block-post-title a {
  text-decoration: underline;
}

html.asta-theme-dark body .has-base-alt-background-color,
html.asta-theme-dark body .has-base-alt-background-color * {
  color: var(--wp--preset--color--contrast-alt);
}

html.asta-theme-dark body .has-base-alt-background-color a {
  color: var(--wp--preset--color--primary);
  text-decoration: underline;
}

html.asta-theme-dark body .wp-block-post-content a:not([class*="-color"]):not(.has-base-alt-background-color a):not(.insta-fallback) {
  color: #60A5FA;
}

/* C-22: manual override to dark (regardless of OS) must cancel the light
   gradient the same way as the no-JS fallback above. */
html.asta-theme-dark .wp-block-cover:not(:has(.wp-block-cover__image-background, video.wp-block-cover__video-background)) > .wp-block-cover__background.has-contrast-alt-background-color {
  background-image: none;
}

@media (prefers-color-scheme: dark) {
  /* `initial` restores the light-mode state exactly: the *-mixed tokens have
     no light definition, so force-light must leave them unset, not invent
     values. */
  html.asta-theme-light body {
    --wp--preset--color--base: #F5F3FF;
    --wp--preset--color--base-alt: #FFFFFF;
    --wp--preset--color--contrast: #0F0D1A;
    --wp--preset--color--contrast-alt: #1A1A1A;
    --wp--preset--color--primary-mixed: initial;
    --wp--preset--color--secondary-mixed: initial;
    --asta-heading-color: var(--wp--preset--color--primary);
  }
}

/* Manual-toggle control (replaces the dead <details> pattern). */
.asta-dark-toggle__button {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  box-sizing: border-box;
  min-height: 32px;
  padding: 0.25rem 0.9rem;
  border: 1px solid var(--asta-header-foreground, #fff);
  border-radius: 999px;
  background: transparent;
  color: var(--asta-header-foreground, #fff);
  font: inherit;
  font-size: 0.85rem;
  cursor: pointer;
}

.asta-dark-toggle__button:focus-visible {
  outline: 2px solid var(--wp--preset--color--secondary);
  outline-offset: 2px;
}

/* A2: AStA header row. The header stays on contrast in both schemes. */
.asta-site-header {
  --asta-header-background: #0F0D1A;
  --asta-header-foreground: #FFFFFF;
  --asta-nav-background: var(--wp--preset--color--primary);
  --asta-nav-foreground: #FFFFFF;
  box-sizing: border-box;
  width: 100%;
  align-items: center;
  column-gap: clamp(0.75rem, 2vw, 1.5rem);
  background-color: var(--asta-header-background) !important;
  color: var(--asta-header-foreground) !important;
}

@media (min-width: 75rem) {
  .asta-site-header {
    flex-wrap: nowrap;
  }
}

.asta-site-header > .asta-header-brand {
  flex: 0 1 auto;
  min-width: 0;
}

.asta-site-header .asta-header-logo img {
  display: block;
  width: clamp(6.5rem, 12vw, 9rem);
  height: auto;
}

.asta-site-header .wp-block-site-title,
.asta-site-header .wp-block-site-title a {
  color: var(--asta-header-foreground) !important;
}

.asta-site-header .wp-block-site-title a {
  text-decoration: none;
}

.asta-site-header .wp-block-site-title a:hover,
.asta-site-header .wp-block-site-title a:focus-visible {
  color: var(--wp--preset--color--secondary) !important;
}

.asta-site-header > .asta-dark-toggle {
  flex: 0 0 auto;
  min-width: max-content;
}

.asta-site-header > .asta-dark-toggle > .wp-block-group {
  margin: 0;
}

.asta-site-header .asta-dark-toggle .wp-block-details summary {
  color: var(--asta-header-foreground) !important;
  cursor: pointer;
}

.asta-site-header .asta-dark-toggle .wp-block-details summary::-webkit-details-marker {
  display: none;
}

.asta-site-header > .asta-primary-navigation {
  flex: 1 1 auto;
  min-width: 12rem;
  margin: 0;
}

.asta-site-header > .asta-language-switcher-wrap {
  flex: 0 0 auto;
  margin-inline-start: auto;
}

/* Base switcher reset — shared by every consumer (header, footer). Purely
   structural; no visual pill treatment here, so the footer instance
   (.asta-footer-three .asta-language-switcher) is unaffected by the
   header-specific pill styling below. */
.asta-language-switcher {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  margin: 0;
  padding: 0;
  list-style: none;
}

.asta-language-switcher .lang-item-de {
  order: 1;
}

.asta-language-switcher .lang-item-en {
  order: 2;
}

.asta-language-switcher a {
  display: inline-flex;
  align-items: center;
  color: var(--asta-header-foreground) !important;
  font-size: 0.875rem;
  font-weight: 700;
  text-decoration: none;
}

.asta-language-switcher img {
  display: block;
  height: auto;
}

.asta-language-switcher a:hover,
.asta-language-switcher a:focus-visible,
.asta-language-switcher .current-lang > a {
  color: var(--wp--preset--color--secondary) !important;
  text-decoration: underline;
  text-underline-offset: 0.2em;
}

/* Segmented pill — header instance only (.asta-header-language-switcher).
   Mirrors .asta-dark-toggle__button's capsule shape (same min-height /
   border-radius) so the two utility controls read as one matched pair, per
   the confirmed design decision. Overrides the shared base rules above for
   this instance; the footer switcher keeps the original plain-link style. */
.asta-header-language-switcher {
  align-items: stretch;
  gap: 0;
  min-height: 32px;
  border: 1px solid var(--asta-header-foreground, #fff);
  border-radius: 999px;
  overflow: hidden;
}

.asta-header-language-switcher a {
  justify-content: center;
  height: 100%;
  padding: 0.25rem 0.9rem;
  text-decoration: none;
}

.asta-header-language-switcher a:hover,
.asta-header-language-switcher a:focus-visible {
  text-decoration: none;
}

.asta-header-language-switcher .current-lang > a {
  background: var(--asta-header-foreground, #fff);
  color: var(--asta-header-background, #0F0D1A) !important;
  text-decoration: none;
}

.asta-header-language-switcher .current-lang > a:hover,
.asta-header-language-switcher .current-lang > a:focus-visible {
  color: var(--asta-header-background, #0F0D1A) !important;
}

/* A2: Max Mega Menu topbar uses the Night Sky primary role.
   pathway-08: the bar is a rounded pill (radius 8) with 16px of end padding,
   like the design. The radius has to sit on `ul#mega-menu-topbar` as well:
   Max Mega Menu paints that list the same purple over the wrapper's exact
   rectangle, so a radius on the wrapper alone is covered by a square list. */
#mega-menu-wrap-topbar {
  width: auto;
  background: var(--asta-nav-background);
  border-radius: 8px;
}

#mega-menu-wrap-topbar #mega-menu-topbar {
  background: var(--asta-nav-background);
  border-radius: 8px;
  padding: 0 6px;
}

/* 6px list padding + 10px item padding = the design's 16px of end padding. */
#mega-menu-wrap-topbar #mega-menu-topbar > li.mega-menu-item > a.mega-menu-link {
  position: relative;
  z-index: 0;
  border-radius: 8px;
  background: transparent !important;
  color: var(--asta-nav-foreground);
  font-weight: 500;
}

/* Hover, focus, the open panel's own item and the current page paint an inset
   pill (4px, radius 8) rather than a full-height block: a block would run into
   the bar's top and bottom edges and cut the pill's silhouette in two.
   It has to be a pseudo-element because Max Mega Menu zeroes the radius of the
   open item (`li.mega-toggle-on > a.mega-menu-link`, one class more specific
   than any rule this file can write without `!important`), and `display: block`
   is load-bearing: Max Mega Menu's clearfix rule sets `display: none` on
   `a.mega-menu-link::after` and only the declarations listed here override it. */
#mega-menu-wrap-topbar #mega-menu-topbar > li.mega-menu-item > a.mega-menu-link::after {
  content: "";
  display: block;
  position: absolute;
  inset: 4px;
  border-radius: 8px;
  background: var(--asta-header-background);
  opacity: 0;
  z-index: -1;
  pointer-events: none;
}

#mega-menu-wrap-topbar #mega-menu-topbar > li.mega-menu-item > a.mega-menu-link:hover::after,
#mega-menu-wrap-topbar #mega-menu-topbar > li.mega-menu-item > a.mega-menu-link:focus::after,
#mega-menu-wrap-topbar #mega-menu-topbar > li.mega-menu-item.mega-toggle-on > a.mega-menu-link::after,
#mega-menu-wrap-topbar #mega-menu-topbar > li.mega-menu-current-menu-item > a.mega-menu-link::after {
  opacity: 1;
  background: var(--asta-header-background) !important;
}

#mega-menu-wrap-topbar #mega-menu-topbar ul.mega-sub-menu {
  background: var(--wp--preset--color--surface);
  /* pathway-08: the panel is a rounded card now, so a 3px accent rule on every
     nested sub-menu drew a purple line under each group header — the shipped
     panel had one border on the outer panel, not sixteen. */
  border-top: 0;
  box-shadow: 0 8px 24px rgba(15, 13, 26, 0.18);
}

/* Phase 2: Max Mega Menu's own admin-generated stylesheet
   (wp-content/uploads/maxmegamenu/style_<lang>.css) sets the top-level grid
   panel's background to `rgba(34, 34, 34, 0)` (fully transparent) via
   `#mega-menu-wrap-topbar #mega-menu-topbar > li.mega-menu-megamenu > ul.mega-sub-menu`,
   a more specific selector than the rule above, so it wins regardless of
   cascade order and the hero section bleeds through the gaps between grid
   columns. Match that selector's specificity to override it back to opaque. */
#mega-menu-wrap-topbar #mega-menu-topbar > li.mega-menu-megamenu > ul.mega-sub-menu {
  background-color: var(--wp--preset--color--surface);
}

#mega-menu-wrap-topbar #mega-menu-topbar ul.mega-sub-menu li.mega-menu-item > a.mega-menu-link {
  color: var(--asta-nav-foreground);
}

#mega-menu-wrap-topbar #mega-menu-topbar ul.mega-sub-menu li.mega-menu-item > a.mega-menu-link:hover,
#mega-menu-wrap-topbar #mega-menu-topbar ul.mega-sub-menu li.mega-menu-item > a.mega-menu-link:focus {
  color: var(--asta-nav-foreground);
  background: var(--wp--preset--color--primary);
}

#mega-menu-wrap-topbar #mega-menu-topbar ul.mega-sub-menu li.mega-menu-item.mega-current-menu-item > a.mega-menu-link {
  color: var(--asta-nav-foreground);
  font-weight: 600;
}

/* Step 1.5: v11 scan-layer chips use native menu-item classes. */
#mega-menu-wrap-topbar #mega-menu-topbar li.asta-menu-nochip {
  display: none !important;
}

/* 2026-10-20 (owner): the coloured chip pills are gone. The Aktuelles and StuPa
   panels still mark their rows with `asta-menu-chip`, so the hook stays and only
   the paint is removed — these read as plain links now, spaced like a list. */
#mega-menu-wrap-topbar #mega-menu-topbar li.asta-menu-chip > a.mega-menu-link {
  display: inline-flex;
  width: auto;
  margin: 0.2rem 1.5rem 0.2rem 0;
  padding: 0.2rem 0;
  border-radius: 0;
  background: transparent;
  color: var(--asta-panel-ink);
  line-height: 1.35;
  /* Chips are top-level column items, which MMM styles as headings (measured:
     uppercase, 700, 16px) through a longer selector than this one. They are
     ordinary links now, so the heading treatment is cancelled explicitly. */
  font-size: 14px !important;
  font-weight: 400 !important;
  letter-spacing: normal !important;
  text-transform: none !important;
}

#mega-menu-wrap-topbar #mega-menu-topbar li.asta-menu-chip > a.mega-menu-link:hover,
#mega-menu-wrap-topbar #mega-menu-topbar li.asta-menu-chip > a.mega-menu-link:focus {
  background: transparent;
  color: var(--asta-panel-ink);
  text-decoration: underline;
  text-underline-offset: 0.2em;
}

/* Step 1.5a: one full-width contextual CTA row per grid panel. */
#mega-menu-wrap-topbar #mega-menu-topbar li.cta-anchor-row {
  box-sizing: border-box;
  clear: both;
  float: none;
  width: 100%;
  margin: 1rem 0 0;
  padding: 0.75rem 0 0;
  border-top: 1px solid var(--wp--preset--color--secondary);
  background: var(--wp--preset--color--surface);
}

#mega-menu-wrap-topbar #mega-menu-topbar li.cta-anchor-row > ul.mega-sub-menu {
  box-sizing: border-box;
  width: 100%;
  margin: 0;
  padding: 0;
  border-top: 0;
  background: transparent;
  box-shadow: none;
  left: auto !important;
  right: auto !important;
}

#mega-menu-wrap-topbar #mega-menu-topbar li.cta-anchor-row ul.mega-sub-menu {
  left: auto !important;
  right: auto !important;
  background: var(--wp--preset--color--surface);
}

#mega-menu-wrap-topbar #mega-menu-topbar li.cta-anchor-row > ul.mega-sub-menu > li.cta-anchor-column {
  box-sizing: border-box;
  float: none;
  width: 100%;
  max-width: 100%;
  margin: 0;
  padding: 0;
}

#mega-menu-wrap-topbar #mega-menu-topbar li.cta-anchor-row li.cta-anchor-link {
  float: none;
  width: 100%;
  margin: 0;
  padding: 0;
}

#mega-menu-wrap-topbar #mega-menu-topbar li.cta-anchor-row li.cta-anchor-link > a.mega-menu-link {
  display: inline-flex;
  box-sizing: border-box;
  max-width: 100%;
  align-items: center;
  color: var(--wp--preset--color--secondary) !important;
  white-space: normal;
  overflow-wrap: anywhere;
}

#mega-menu-wrap-topbar #mega-menu-topbar li.cta-anchor-row li.cta-anchor-link > a.mega-menu-link:hover,
#mega-menu-wrap-topbar #mega-menu-topbar li.cta-anchor-row li.cta-anchor-link > a.mega-menu-link:focus {
  color: var(--wp--preset--color--accent) !important;
}

@media (min-width: 768px) {
  #mega-menu-wrap-topbar #mega-menu-topbar > li:nth-last-child(-n + 2) ul.mega-sub-menu ul.mega-sub-menu {
    left: auto !important;
    right: 250px !important;
  }

  #mega-menu-wrap-topbar #mega-menu-topbar > li:nth-last-child(-n + 2) li.cta-anchor-row ul.mega-sub-menu {
    left: auto !important;
    right: auto !important;
  }
}

@media (max-width: 767px) {
  .asta-site-header {
    justify-content: flex-start;
    row-gap: 0.75rem;
  }

  .asta-site-header > .asta-header-brand {
    flex: 1 1 auto;
  }

  .asta-site-header > .asta-dark-toggle {
    order: 2;
    margin-inline-start: auto;
  }

  .asta-site-header > .asta-language-switcher-wrap {
    order: 3;
    margin-inline-start: auto;
  }

  .asta-site-header > .asta-primary-navigation {
    flex-basis: 100%;
    min-width: 0;
    order: 4;
  }

  #mega-menu-wrap-topbar {
    width: 100%;
  }

  /* pathway-08 gives the desktop bar 16px of end padding; the mobile drawer
     rows are full-bleed, so the 6px list padding and the 8px corner are reset. */
  #mega-menu-wrap-topbar,
  #mega-menu-wrap-topbar #mega-menu-topbar {
    border-radius: 0;
  }

  #mega-menu-wrap-topbar #mega-menu-topbar {
    padding: 0;
  }

  #mega-menu-wrap-topbar #mega-menu-topbar li.asta-menu-chip > a.mega-menu-link {
    display: block;
    margin: 0;
    padding: 0.65rem 1rem;
    border-radius: 0;
    background: transparent;
    color: var(--asta-nav-foreground);
  }
}

/*
 * C-23 (pathway-08 §1–5): the mega-menu's visible text.
 *
 * Measured on the rendered panel 2026-10-20 (Figma capture 30:203): item titles
 * #666666 on #1A1A2E = 2.97:1 and group headers #555555 = 2.29:1 — both below
 * the 4.5:1 floor. The cause was not a missing colour on the link: Max Mega
 * Menu's generated stylesheet paints the *inner* spans
 * (span.mega-menu-title / span.mega-menu-description), while this child theme
 * coloured only a.mega-menu-link. The inner span is what the reader sees, so the
 * white never applied.
 *
 * The generated sheet is per-language and stamped "DO NOT MAKE MANUAL EDITS", so
 * the override belongs here. These tokens mirror the Night Sky library and are
 * deliberately scheme-stable: the panel is dark in both modes, so its ink must
 * not invert. Ratios on #1A1A2E: ink 17.06:1, muted 9.31:1, accent 6.27:1.
 */
#mega-menu-wrap-topbar {
  --asta-panel-ink: #ffffff;
  --asta-panel-ink-muted: rgba(255, 255, 255, 0.72);
  --asta-panel-accent: #a78bfa;
}

/* Item titles and descriptions: the inner spans that actually render the text. */
#mega-menu-wrap-topbar #mega-menu-topbar ul.mega-sub-menu li.mega-menu-item > a.mega-menu-link span.mega-menu-title,
#mega-menu-wrap-topbar #mega-menu-topbar ul.mega-sub-menu li.mega-menu-item > a.mega-menu-link span.mega-menu-description {
  color: var(--asta-panel-ink) !important;
}

/* Items that carry no description have their label as a bare text node inside
   the anchor — no span to colour — so they inherited MMM's #666 and rendered
   grey next to their white neighbours (measured: linkColor rgb(102,102,102) on
   "Formulare / Anträge"). Colouring the link covers both shapes. The CTA links
   are excluded: the other panels' `.cta-anchor-row` CTA is a blue link by design,
   and the AStA CTA brings its own white-on-primary rule. */
#mega-menu-wrap-topbar #mega-menu-topbar ul.mega-sub-menu li.mega-menu-item:not(.cta-anchor-link):not([class*="asta-cta-link"]) > a.mega-menu-link {
  color: var(--asta-panel-ink) !important;
}

#mega-menu-wrap-topbar #mega-menu-topbar ul.mega-sub-menu li.mega-menu-item > a.mega-menu-link span.mega-menu-description {
  font-size: 12px !important;
  line-height: 1.42 !important;
  font-style: normal !important;
  opacity: 0.72;
}

/*
 * Group headers ("Über uns", "Jobs", "Referate") are the items whose parent
 * ul's parent is li.mega-menu-column. Measured from the rendered DOM: a header
 * chains SPAN < A < LI.mega-menu-item < UL < LI.mega-menu-column, while an item
 * chains SPAN < A < LI.mega-menu-item < UL < LI.mega-menu-item. `has-children`
 * is NOT the discriminator — items carry it too — so keying on the column is the
 * only rule that colours the three headers and leaves every item link white.
 * Declared after the ink rule and with more classes, so it wins on specificity.
 */
#mega-menu-wrap-topbar #mega-menu-topbar li.mega-menu-column > ul.mega-sub-menu > li.mega-menu-item:not(.asta-menu-chip) > a.mega-menu-link span.mega-menu-title {
  color: var(--asta-panel-accent) !important;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.09em;
  text-transform: uppercase;
}

/*
 * Descriptions are inline, and only where the label is an abbreviation.
 *
 * 2026-10-20 (owner): a description on its own second line doubled the height of
 * every Referate row. It now sits on the same line, after an en dash, in the same
 * description style (12px, 72% white). Only the seven entries whose label is an
 * abbreviation carry one — the class `asta-desc` is set on those menu items (DE
 * and EN), so the choice lives in the menu, not in a title match here.
 */
#mega-menu-wrap-topbar #mega-menu-topbar ul.mega-sub-menu span.mega-menu-description {
  display: none;
}

#mega-menu-wrap-topbar #mega-menu-topbar li.asta-desc > a.mega-menu-link span.mega-menu-description {
  display: inline;
}

/* MMM wraps title and description in one span; making it a row puts them on the
   same line and lets the smaller text sit on the title's baseline. */
#mega-menu-wrap-topbar #mega-menu-topbar ul.mega-sub-menu span.mega-description-group {
  display: inline-flex;
  align-items: baseline;
  gap: 0.5em;
  max-width: 100%;
}

#mega-menu-wrap-topbar #mega-menu-topbar li.asta-desc > a.mega-menu-link span.mega-menu-description::before {
  content: "– ";
}

/* Panel: a centred 1200px card instead of a full-bleed 1440px band. The shipped
   panel measured 1440x1086 + 66px header = 1152px against a ~900px viewport, so
   its bottom rows were unreachable without scrolling inside the panel; this
   brings it to 1200x635. */
@media (min-width: 768px) {
  /* All five panels are 1200px cards, so they have to centre on the page and not
     on the 534px pill (grid panels) or on their own item (the two flyouts, which
     overflowed the viewport right edge by 526px). Making the wrapper and the
     top-level flyout items static hands the panels' containing block to the
     sticky header, which is the viewport width; `left/right: 0` +
     `margin-inline: auto` then centres them, and `top: 100%` means "below the
     header". Max Mega Menu writes the panel's `left` inline and keeps flyout
     items `position: relative`, hence `!important`. */
  #mega-menu-wrap-topbar,
  #mega-menu-wrap-topbar #mega-menu-topbar,
  #mega-menu-wrap-topbar #mega-menu-topbar > li.mega-menu-flyout {
    position: static !important;
  }
}

#mega-menu-wrap-topbar #mega-menu-topbar > li.mega-menu-megamenu > ul.mega-sub-menu {
  box-sizing: border-box;
  /* pathway-08 §4: 18px below the 66px header (`.mm-wrap` padding-top), i.e. the
     panel starts at y=84. It used to start on the bar's own bottom edge, which
     fused bar and panel into one shape and hid the bar's bottom corners. */
  top: calc(100% + 18px);
  left: 0 !important;
  right: 0 !important;
  max-width: 1200px;
  margin-inline: auto;
  padding: 32px;
  border-top: 0;
  border-radius: 12px;
}

#mega-menu-wrap-topbar #mega-menu-topbar ul.mega-sub-menu li.mega-menu-item > a.mega-menu-link {
  min-height: 34px;
  padding: 6px 10px;
  border-radius: 8px;
  font-size: 14.5px;
  line-height: 1.45;
}

/* The CTA capsule reuses the header language-switcher shape (999px). It is scoped
   to the AStA panel's CTA, which is NOT a .cta-anchor-row — it is
   li.mega-menu-item-asta-cta-link-<id>. The other panels' .cta-anchor-row CTAs
   keep their existing blue-link treatment: restyling them was never part of the
   approved design, and the mobile contract asserts that colour. */
#mega-menu-wrap-topbar #mega-menu-topbar li[class*="asta-cta-link"] > a.mega-menu-link {
  display: inline-flex;
  height: 44px;
  align-items: center;
  padding: 0 20px;
  border-radius: 999px;
  background: var(--wp--preset--color--primary);
  color: var(--asta-panel-ink) !important;
  font-size: 14.5px;
  font-weight: 700;
}

/* Max Mega Menu's generated sheet sets `a.mega-menu-link { display: block }`
   with enough specificity to beat the shared capsule rule above, which left the
   AStA CTA a 1106px-wide pill with no horizontal padding. These declarations are
   !important for the same reason the text-colour overrides are. */
#mega-menu-wrap-topbar #mega-menu-topbar li[class*="asta-cta-link"] > a.mega-menu-link {
  display: inline-flex !important;
  width: auto !important;
  box-sizing: border-box;
  align-items: center;
  height: 44px !important;
  padding: 0 20px !important;
  border-radius: 999px !important;
  background: var(--wp--preset--color--primary) !important;
  color: var(--asta-panel-ink) !important;
  font-size: 14.5px !important;
  font-weight: 700 !important;
}

#mega-menu-wrap-topbar #mega-menu-topbar li[class*="asta-cta-link"] {
  text-align: right;
}

/* A4: Focus indicators (2px outline, offset) */
a:focus-visible,
button:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible,
[tabindex]:focus-visible {
  outline: 2px solid var(--wp--preset--color--secondary) !important;
  outline-offset: 2px !important;
}

#mega-menu-wrap-topbar.mega-keyboard-navigation a:focus,
#mega-menu-wrap-topbar.mega-keyboard-navigation .mega-menu-toggle:focus,
#mega-menu-wrap-topbar.mega-keyboard-navigation button:focus {
  outline: 2px solid var(--wp--preset--color--secondary) !important;
  outline-offset: 2px !important;
}

/* Fluent Forms and the mobile search panel have more specific focus rules. */
.ff-el-form-control:focus,
.ff-btn-submit:focus,
[data-asta-mobile-search-toggle]:focus {
  outline: 2px solid var(--wp--preset--color--secondary) !important;
  outline-offset: 2px !important;
}

/* C-03: FluentForm submit button — plugin-level override (parent:
   dev-asta-gwyneth/app/public/wp-content/plugins/fluentform/assets/css/
   fluentform-public-default.css lines 13–16: #007bff / #fff fails 2.78:1).
   Child override per F-05/2.6 idiom — minimal, no parent edit. */
.ff-btn.ff-btn-submit,
.ff-default .ff-btn-primary:not(.ff_btn_no_style) {
  background-color: var(--wp--preset--color--primary) !important;
  border-color: var(--wp--preset--color--primary) !important;
  color: var(--wp--preset--color--base-alt) !important;
}

/* A3: Footer zones and social links */
/* pathway-08 §6 (2026-10-20): a token-native dark band.
   The previous version redefined --wp--preset--color--contrast and --base to
   stay dark, which silently re-coloured any nested component that inherited
   them — the same mechanism as the mega-menu contrast bug (C-23). It now binds
   the same scheme-stable pair the header defines on itself (.asta-site-header
   also uses literals), so no preset token changes meaning inside the footer.
   The selector carries .wp-block-group because WordPress' has-global-padding
   sets the group's padding with higher specificity than a bare class. */
.wp-block-group.asta-footer-three {
  --asta-footer-background: #0f0d1a;
  --asta-footer-foreground: #ffffff;
  /* C-14 kept without the token swap: headings resolve through the accent that
     already measures 6.27:1 on this surface (same value as the mega-menu label). */
  --asta-heading-color: #a78bfa;
  position: relative;
  box-sizing: border-box;
  background-color: var(--asta-footer-background);
  color: var(--asta-footer-foreground);
  /* px, not rem: the root font is fluid (17.72px at 1440), so 2.75rem rendered
     48.7px and 1.375rem 24.4px against a design of 44 and 22. */
  padding: 44px var(--wp--preset--spacing--content) 22px;
  padding-bottom: 22px !important;
  font-size: 14px;
  line-height: 1.5;
  /* WordPress spaces the heading and the list by the block gap, which measured
     28.7px here against a designed 12 — it was making the legal column the
     tallest and pushing the copyright below the contact line. */
  --wp--style--block-gap: 12px;
}

.asta-footer-three__columns {
  align-items: flex-start;
  justify-content: space-between;
}

.asta-footer-three__zone {
  min-width: 0;
}

.asta-footer-three__zone--kontakt { flex: 0 1 30rem; }
.asta-footer-three__zone--folgen,
.asta-footer-three__zone--rechtliches { flex: 0 1 21.25rem; }

/* One heading treatment for all three zones. Measured before: Kontakt rendered
   1.25rem against 1rem for the other two, contradicting the DOM where all three
   are <h2>. The uppercase 12px label is the one the approved mega-menu uses. */
.asta-footer-three .asta-footer-three__zone h2 {
  margin: 0;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.09em;
  line-height: 1.6;
  text-transform: uppercase;
}

.asta-footer-contact p {
  margin: 0 0 4px;
  font-size: 14px;
  line-height: 1.5;
}

.asta-footer-contact p:last-child { margin-bottom: 0; }
.asta-footer-contact__name { font-weight: 700; }
.asta-footer-contact__address,
.asta-footer-contact__hours { opacity: 0.8; }
.asta-footer-contact__email a { color: inherit; }

.asta-footer-links {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 6px;
  font-size: 14px;
}

/* C-06 keeps its 24px target-size floor. */
.asta-footer-links li a,
.asta-footer-three__zone li a {
  display: inline-block;
  min-height: 24px;
  /* 24px, not the inherited 1.5 line-height: the rows measured 27px and made the
     legal column taller than the contact column. */
  line-height: 24px;
  color: inherit;
  text-decoration: none;
}

.asta-footer-links li a:hover,
.asta-footer-links li a:focus-visible {
  text-decoration: underline;
  text-underline-offset: 0.2em;
}

.asta-footer-three .asta-social-links { gap: 10px; }

.asta-footer-three .asta-social-link {
  align-items: center;
  color: inherit;
  display: inline-flex;
  gap: 10px;
  text-decoration: none;
}

.asta-footer-three .asta-social-link:hover,
.asta-footer-three .asta-social-link:focus-visible {
  text-decoration: underline;
  text-underline-offset: 0.2em;
}

.asta-footer-three .asta-social-icon {
  display: inline-flex;
  flex: 0 0 auto;
  height: 18px;
  width: 18px;
}

.asta-footer-three .asta-social-icon svg {
  height: 100%;
  width: 100%;
}

/* The copyright shares the contact email's line: absolutely positioned so it
   adds no height of its own, bottom-anchored to the padding edge. The footer's
   height is therefore the tallest column plus 22px, not columns plus a band. */
.asta-footer-three__copyright {
  margin: 10px 0 0;
  font-size: 13px;
  line-height: 1.6;
  opacity: 0.72;
  text-align: center;
}

@media (max-width: 767px) {
  .wp-block-group.asta-footer-three {
    padding: 28px var(--wp--preset--spacing--content) 20px;
    padding-bottom: 20px !important;
  }

  /*
   * The parent's accessibility module pads the last group of a
   * .has-mobile-padding-bottom container by 8em (measured: 128px) so content
   * clears a fixed mobile bar. This theme already reserves exactly that space on
   * the body (body { padding-bottom: 72px } against the 72px fixed bottom nav),
   * so the footer was carrying 128px of dead space on top of it. The selector
   * mirrors the parent's specificity plus one class so the override wins.
   */
  body .has-mobile-padding-bottom > .wp-block-group.asta-footer-three {
    padding-bottom: 20px !important;
  }
}

@media (min-width: 768px) {
  .asta-footer-three__copyright {
    position: absolute;
    right: var(--wp--preset--spacing--content);
    /* 22px puts the copyright's bottom exactly on the contact email's bottom
       (the padding edge), which is what "same line" means here. px, not rem:
       1.375rem resolved to 24.4px and sat 2px below the line. */
    bottom: 22px;
    left: var(--wp--preset--spacing--content);
    margin: 0;
  }
}

/* C-06: EN carousel dot target-size fix (module-level; ≥24px touch target,
   WCAG 2.5.8; regression: must not shift mobile bottom nav / MMM panel). */
.asta-pc-dot {
  min-width: 24px !important;
  min-height: 24px !important;
  padding: 2px !important;
}

/* C-02: primary-background button links received the parent auto-contrast text
   token (black on #6D28D9 = 2.96:1, fails WCAG 1.4.3 in both schemes). Bind the
   text to a palette token instead of a literal colour. */
.wp-block-button__link.has-primary-background-color {
  color: var(--wp--preset--color--base-alt) !important;
}

/* C-08: the parent global.css `details` rule paints every details surface with
   --wp--custom--details--color--background (a light tint) and white text. Inside
   the always-dark header the toggle must sit on the header surface; keep the
   existing white summary colour and drop the tinted panel (was 1.1:1). */
.asta-site-header .asta-dark-toggle .wp-block-details {
  background-color: transparent !important;
}

/* Desktop language bar (tha_header_before) — compact top utility strip above
   the header; palette tokens only (theme.json stays read-only). The strip is
   dark in both schemes, so it binds `contrast-alt` (near-black in light AND
   dark) rather than `contrast`, which inverts to white in dark mode and
   dropped the white link text to 1.1:1 (C-06 dark `color-contrast` cluster). */
.asta-language-bar {
  display: flex;
  justify-content: flex-end;
  gap: 0.75rem;
  padding: 0.25rem 1rem;
  background-color: var(--wp--preset--color--contrast-alt, #1A1A1A);
  color: var(--wp--preset--color--base-alt, #FFFFFF);
  font-size: 0.875rem;
}

.asta-language-bar__link {
  color: inherit;
  text-decoration: none;
}

.asta-language-bar__link[aria-current="true"] {
  text-decoration: underline;
  font-weight: 700;
}

.asta-language-bar__link:hover,
.asta-language-bar__link:focus-visible {
  text-decoration: underline;
}

/* C-19: WCAG 2.5.8 minimum target size. At mobile widths these link groups
   measured 15-21px tall (language bar 21, site title 21, footer links 18,
   in-content quick-link paragraphs 18, read-more 19, more-link 20, card
   title links 21, taxonomy chips 15, post dates 18, cmplz policy links 15).
   min-height on an inline-block lifts the line box without moving desktop
   layout (the block is mobile-only); padding keeps text centred in the box. */
@media (max-width: 767px) {
  .asta-language-bar__link,
  .asta-header-site-title a,
  .asta-footer-three a,
  .wp-block-post-content a,
  .wp-block-read-more,
  .wp-block-post-excerpt__more-link,
  .wp-block-post-title a,
  .wp-block-post-template .wp-block-heading a,
  .taxonomy-category a,
  .wp-block-post-date a,
  .cmplz-link {
    display: inline-block;
    min-height: 24px;
    padding-block: 2px;
  }
}

.asta-aktuelles__layout {
  display: grid;
  grid-template-columns: minmax(0, 2fr) minmax(16rem, 1fr);
  align-items: stretch;
  gap: 1rem;
}

.asta-news-bento {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  grid-auto-rows: minmax(10rem, auto);
  gap: 1rem;
}

.asta-news-bento__tile,
.asta-telegram-cta {
  min-width: 0;
  padding: 1.25rem;
  border: 1px solid var(--wp--preset--color--contrast);
  border-radius: 0.5rem;
  background-color: var(--wp--preset--color--base);
  color: var(--wp--preset--color--contrast);
}

.asta-news-bento__tile {
  display: flex;
  flex-direction: column;
  /*
   * Content sits together at the top instead of being pinned to both ends.
   * `space-between` pushed the date to the top and the title to the bottom, which
   * in a row whose height is set by a taller neighbour (an image tile) left a
   * large empty hole in the middle of every short tile. Rows keep their tidy
   * equal height; only the internal distribution changed.
   */
  justify-content: flex-start;
  gap: 0.35rem;
}

/* Phase 2, task 7: the hero's third action is a link rather than a third button,
   so the hero fits the first screen at 390px. A link still needs a usable target
   (WCAG 2.5.8), hence the padding and the explicit minimum height, and it must
   stay legible on the cover's dark overlay in both schemes. */
.asta-hero-tertiary a {
  display: inline-block;
  min-height: 44px;
  padding: 0.5rem 0.25rem;
  color: var(--wp--preset--color--base-alt);
  font-weight: 600;
  text-decoration: underline;
  text-underline-offset: 0.2em;
}

.asta-hero-tertiary a:focus-visible {
  outline: 2px solid var(--wp--preset--color--secondary);
  outline-offset: 2px;
}

/* Phase 2, task 5: the Schnellzugriff cards were six across in a 1200px row,
   which leaves 185px per card. Raising the card titles above the body size (the
   agreed typography fix) cannot fit a German compound noun in 185px, so the grid
   widens instead of the type shrinking back below body: three across on desktop,
   two on tablet, one on mobile. Hyphenation is kept as a safety net for any
   future long label. */
.asta-service-icon-grid .wp-block-columns {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 1rem;
}

.asta-service-icon-grid .wp-block-column {
  margin: 0;
}

.asta-service-icon-grid h3,
.asta-service-icon-grid h4 {
  /* The parent sets `break-word` on headings, which split "Semesterticket" as
     "Semeste / rticket" once the type grew. Hyphenation breaks it correctly. */
  overflow-wrap: normal;
  hyphens: auto;
  -webkit-hyphens: auto;
}

@media (max-width: 900px) {
  .asta-service-icon-grid .wp-block-columns {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media (max-width: 600px) {
  .asta-service-icon-grid .wp-block-columns {
    grid-template-columns: minmax(0, 1fr);
  }
}

/*
 * The feature tile is *wide*, not two rows tall.
 *
 * The first attempt used three tracks with the feature spanning two columns and
 * two rows. Reviewed in a screenshot, that produced 198px tiles stretched to
 * 306-622px: a feature tile 60% empty white space, because row heights are
 * content-driven and a two-row span doubles whatever the rows above happen to
 * need. A wide feature in a two-track grid fills the first row completely, keeps
 * every row content-sized, and leaves no holes at any tile count.
 */
.asta-news-bento__tile--feature {
  grid-column: span 2;
}

.asta-news-bento__image {
  display: block;
  width: 100%;
  aspect-ratio: 16 / 9;
  object-fit: cover;
  margin-bottom: 0.75rem;
  border-radius: 0.375rem;
}

.asta-news-bento__category {
  align-self: flex-start;
  display: inline-block;
  margin-bottom: 0.5rem;
  padding: 0.15rem 0.6rem;
  border-radius: 999px;
  background-color: var(--wp--preset--color--primary);
  color: var(--wp--preset--color--base-alt);
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.01em;
  text-transform: uppercase;
}

.asta-news-bento__date {
  font-size: 0.875rem;
}

.asta-news-bento__title,
.asta-telegram-cta__heading {
  margin: 0;
}

/*
 * The parent theme's global.css carries
 * `h3:not(:first-child) { margin-block-start: var(--wp--custom--spacing--heading) }`.
 * Specificity 0,1,1 beats the single-class reset above (0,1,0), so every tile
 * title inherited a 53px top margin and the tile looked like it had a hole in the
 * middle — that gap was the real cause, not the flex distribution. Two classes
 * outrank it.
 */
.asta-news-bento__tile .asta-news-bento__title,
.asta-telegram-cta .asta-telegram-cta__heading {
  margin-block-start: 0;
}

.asta-news-bento__title {
  font-size: clamp(1.125rem, 1.6vw, 1.5rem);
  line-height: 1.3;
}

/*
 * The promo heading had no size of its own, so it took the theme's default h3 —
 * 35.4px against the lead news headline's 31.7px, i.e. a side panel outranking
 * the main content. Sized below the feature title in both languages.
 */
.asta-telegram-cta__heading {
  font-size: clamp(1.35rem, 1.8vw, 1.6rem);
  line-height: 1.3;
}

.asta-news-bento__tile--feature .asta-news-bento__title {
  font-size: clamp(1.375rem, 2.2vw, 2rem);
}

.asta-news-bento__link {
  display: block;
  min-height: 44px;
  color: var(--wp--preset--color--contrast);
  text-decoration: underline;
  text-underline-offset: 0.15em;
}

.asta-news-bento__link:focus-visible,
.asta-telegram-cta__link:focus-visible {
  outline: 3px solid var(--wp--preset--color--secondary);
  outline-offset: 3px;
}

.asta-telegram-cta {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  justify-content: center;
  gap: 1rem;
}

.asta-telegram-cta__mark {
  display: grid;
  width: 3rem;
  height: 3rem;
  place-items: center;
  border: 2px solid currentColor;
  border-radius: 50%;
  font-weight: 700;
}

.asta-telegram-cta__description {
  margin: 0;
}

.asta-telegram-cta__link {
  display: inline-flex;
  min-height: 44px;
  align-items: center;
  padding: 0.5rem 1rem;
  border-radius: 0.25rem;
  background-color: var(--wp--preset--color--contrast);
  color: var(--wp--preset--color--base);
  font-weight: 700;
  text-decoration: underline;
  text-underline-offset: 0.15em;
}

@media (max-width: 900px) {
  .asta-aktuelles__layout {
    grid-template-columns: minmax(0, 1fr);
  }
}

@media (max-width: 600px) {
  .asta-news-bento {
    grid-template-columns: minmax(0, 1fr);
    grid-auto-rows: minmax(9rem, auto);
  }

  .asta-news-bento__tile--feature {
    grid-row: auto;
    /* A column span would create an implicit second track in a 1-column grid,
       which is how the first version of this rule broke mobile: tiles rendered
       33px and 310px wide instead of 359px. */
    grid-column: auto;
  }
}

.asta-referate-section h2 {
  margin-bottom: 1.5rem;
  text-align: center;
}

.referate-grid {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 1rem;
  margin: 0;
  padding: 0;
  list-style: none;
}

.ref-tile {
  min-width: 0;
}

.sq-box {
  position: relative;
  display: flex;
  width: 100%;
  aspect-ratio: 1 / 1;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  border-radius: 10px;
  background-color: var(--wp--preset--color--base);
  color: inherit;
  text-decoration: none;
}

.sq-box:focus-visible {
  outline: 3px solid var(--asta-heading-color);
  outline-offset: 3px;
}

.sq-box img.logo-img {
  display: block;
  max-width: 78%;
  max-height: 78%;
  object-fit: contain;
}

.insta-fallback {
  display: flex;
  width: 100%;
  height: 100%;
  min-height: 44px;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.4rem;
  color: var(--asta-heading-color);
  text-decoration: none;
}

.insta-fallback:focus-visible {
  box-shadow: inset 0 0 0 3px var(--asta-heading-color);
}

.insta-mark {
  display: grid;
  width: 34%;
  max-width: 3.5rem;
  place-items: center;
}

.insta-mark svg {
  display: block;
  width: 100%;
  height: auto;
}

.insta-handle {
  font-size: 0.72rem;
  font-weight: 700;
}

.name-fallback {
  display: flex;
  width: 100%;
  height: 100%;
  align-items: center;
  justify-content: center;
  padding: 0.9rem;
  text-align: center;
}

.name-fallback span {
  color: var(--asta-heading-color);
  font-size: 0.95rem;
  font-weight: 700;
  line-height: 1.3;
}

.time-pill {
  position: absolute;
  right: 0.5rem;
  bottom: 0.5rem;
  display: inline-flex;
  min-height: 32px;
  align-items: center;
  padding: 0.28rem 0.65rem;
  border-radius: 999px;
  background-color: var(--wp--preset--color--primary);
  box-shadow: 0 2px 6px rgba(15, 13, 26, 0.25);
  color: #fff;
  font-size: 0.72rem;
  font-weight: 700;
  line-height: 1;
  white-space: nowrap;
}

@media (max-width: 900px) {
  .referate-grid {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
}

@media (max-width: 600px) {
  .referate-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 0.75rem;
  }
}

/* Phase 9.5: Events timeline. Mirrors the .asta-news-bento__tile card
   surface (background: base, border: contrast, 0.5rem radius) for visual
   consistency with the section above it; .asta-event-row's border-bottom is
   suppressed on the last list item so the divider lines sit only between
   rows, not after the final one. */
.asta-events-timeline {
  max-width: 720px;
  margin: 0 auto;
  overflow: hidden;
  border: 1px solid var(--wp--preset--color--contrast);
  border-radius: 0.5rem;
  background-color: var(--wp--preset--color--base);
}

.asta-events-timeline .wp-block-post-template {
  margin: 0;
  padding: 0;
}

.asta-event-row {
  padding: 0.65rem 1rem;
  border-bottom: 1px solid var(--wp--preset--color--contrast);
  color: var(--wp--preset--color--contrast);
}

.asta-events-timeline .wp-block-post-template > li:last-child .asta-event-row {
  border-bottom: none;
}

.date-badge {
  display: inline-flex;
  flex-shrink: 0;
  align-items: center;
  justify-content: center;
  min-width: 4.5rem;
  padding: 0.3rem 0.65rem;
  border-radius: 999px;
  background-color: var(--wp--preset--color--primary);
  color: #fff;
  font-size: 0.75rem;
  font-weight: 700;
  text-align: center;
  white-space: nowrap;
}

/* Flex items default to a min-width floor of their own content's unwrapped
   size, which pushes long titles past the row/container edge instead of
   wrapping. min-width: 0 lifts that floor so the title wraps within the
   space left by the fixed-width date badge, at any viewport width. */
.asta-event-row .wp-block-post-title {
  flex: 1 1 auto;
  min-width: 0;
}

.asta-event-row .wp-block-post-title a {
  display: inline-block;
  padding: 0.25rem 0;
  color: var(--wp--preset--color--contrast);
  text-decoration: underline;
  text-underline-offset: 0.15em;
}

.asta-event-row .wp-block-post-title a:focus-visible {
  outline: 3px solid var(--wp--preset--color--secondary);
  outline-offset: 3px;
}

/*
 * Chip groups. Once the chips became children of a group (Wahlen / StuPa /
 * Beschlüsse) each rendered as a block, which is correct: MMM positions sub-menu
 * items with its own column geometry, and forcing the list to flex pushed the
 * chips off-canvas (measured x = -324). They stay stacked.
 */





/*
 * WCAG 1.4.3 on the social rows.
 *
 * Instagram's brand pink (#f00075) carries white labels at 4.23:1, below the
 * 4.5:1 AA floor for 15.6px text. The service colour is darkened to #d6006a,
 * which keeps the hue recognisable and measures 5.17:1 against white.
 */
.wp-block-social-links.has-visible-labels .wp-social-link-instagram {
  background-color: #d6006a !important;
  color: #fff !important;
}

/*
 * WCAG 1.4.3 on Complianz' blocked-embed notice.
 *
 * The plugin ships a white-on-#808080 banner (3.94:1) that only appears when a
 * third-party embed is blocked, so it never shows up in a plain page scan. The
 * grey is darkened to reach 5.41:1 and nothing else changes.
 */
.cmplz-blocked-content-notice,
.cmplz-blocked-content-container .cmplz-blocked-content-notice {
  background-color: #6b6b6b !important;
}

/*
 * Audit D1 — one wordmark.
 *
 * The header ships the AStA lockup as an image whose alt text is already
 * "AStA Universität Lüneburg", and `parts/header.html` prints the site title
 * next to it as the home link. Visually the wordmark appeared twice (measured at
 * 1440 px: logo 0–160, title 177–462; at 390 px the two came within 10 px).
 *
 * The logo stays as the visible wordmark; the site-title link stays in the DOM —
 * it is the header's only link home — and is hidden the way a skip link is,
 * revealed on focus so 2.4.7 still holds.
 */
.asta-site-header .asta-header-site-title {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

.asta-site-header .asta-header-site-title a:focus-visible {
  position: fixed;
  top: 8px;
  left: 8px;
  box-sizing: border-box;
  width: auto;
  height: auto;
  margin: 0;
  padding: 8px 14px;
  overflow: visible;
  clip-path: none;
  background: var(--wp--preset--color--contrast);
  color: var(--wp--preset--color--base-alt);
  border-radius: 8px;
  z-index: 1200;
}

/*
 * Audit D3 — one filled action in the hero.
 *
 * `.is-style-outline` is the block library's own variant, but the global
 * `:root :where(.wp-block-button__link.is-style-outline)` preset styles it with
 * the theme's link colour, which disappears on the cover gradient. Bind the
 * outline to the cover's foreground instead.
 */
.wp-block-cover .wp-block-button__link.is-style-outline.asta-hero-secondary {
  background: transparent !important;
  color: var(--wp--preset--color--base-alt) !important;
  border: 2px solid currentColor !important;
  padding: 0.55em 1.15em;
}

.wp-block-cover .wp-block-button__link.is-style-outline.asta-hero-secondary:hover,
.wp-block-cover .wp-block-button__link.is-style-outline.asta-hero-secondary:focus {
  background: var(--wp--preset--color--base-alt) !important;
  color: var(--wp--preset--color--contrast) !important;
}

/*
 * Audit D5 — links must not read as group headers.
 *
 * The HowTo and StuPa panels use Max Mega Menu's auto-flow layout, where every
 * top-level item is painted like a column header (uppercase, 700, accent). An
 * item that is a plain link — "Sitzungen", "Ausschüsse" — therefore looked like
 * a section title. Styling follows the subtree, not the depth: a first-level item
 * is a header only when it has children.
 */
#mega-menu-wrap-topbar #mega-menu-topbar > li.mega-menu-megamenu > ul.mega-sub-menu > li.mega-menu-item:not(:has(> ul)) > a.mega-menu-link span.mega-menu-title {
  font-size: 14px;
  font-weight: 400;
  letter-spacing: normal;
  text-transform: none;
  color: var(--asta-panel-ink);
}

/*
 * Audit D8 — hover weight in dark scheme.
 *
 * The panel row hovered to the same solid violet (#6D28D9) as a primary button,
 * so a hovered menu row carried as much weight as the page's main action. The
 * accent at 14 % keeps the state visible without competing.
 */
@media (prefers-color-scheme: dark) {
  #mega-menu-wrap-topbar #mega-menu-topbar ul.mega-sub-menu li.mega-menu-item > a.mega-menu-link:hover,
  #mega-menu-wrap-topbar #mega-menu-topbar ul.mega-sub-menu li.mega-menu-item > a.mega-menu-link:focus {
    background: rgba(167, 139, 250, 0.14);
  }
}

/*
 * Audit U3 — recovery paths on the 404 page.
 *
 * The five entries are links, not buttons: they are alternative routes, not
 * competing primary actions. They wrap, so the row degrades to two lines at
 * 390 px without a horizontal scrollbar.
 */
.asta-404-paths {
  gap: 0.5rem;
  margin-top: 1.5rem;
}

.asta-404-path {
  margin: 0;
}

.asta-404-path a {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding: 0 1rem;
  border: 1px solid var(--wp--preset--color--primary);
  border-radius: 999px;
  color: var(--wp--preset--color--primary);
  font-weight: 600;
  text-decoration: none;
}

.asta-404-path a:hover,
.asta-404-path a:focus {
  background: var(--wp--preset--color--primary);
  color: #fff;
}

/*
 * Audit D3/U3 — search buttons follow the single primary treatment.
 *
 * The block library paints `.wp-block-search__button` with the palette's
 * `secondary` fill (#3B82F6), which carries its white label at 3.67:1 — below
 * the 4.5:1 floor — and made search the fourth component to use "secondary blue"
 * for something primary. Violet measures 7.10:1.
 */
.wp-block-search .wp-block-search__button,
.wp-block-search__button.wp-block-search__button {
  background: var(--wp--preset--color--primary) !important;
  color: #fff !important;
  border-color: var(--wp--preset--color--primary) !important;
}

.wp-block-search .wp-block-search__button:hover,
.wp-block-search .wp-block-search__button:focus {
  filter: brightness(1.12);
}

/*
 * Dark scheme: headings inherit the ink of a block that sets its own.
 *
 * Measured on /erklaerung-zur-barrierefreiheit/ in dark scheme: two `<h2>`s sat
 * inside a group with `has-base-alt-background-color` (light, #f5f3ff) and
 * `has-contrast-alt-color` (near-black ink), but the global heading rule painted
 * them with the dark-scheme accent (#a78bfa) at 2.48:1. A container that
 * declares both a background and a text colour owns the ink of its children;
 * containers that only set a background keep the accent headings.
 */
html body [class*="has-text-color"][class*="-background-color"] :is(h1, h2, h3, h4, h5, h6):not([class*="-color"]):not(.has-text-color) {
  color: inherit;
}

/*
 * Audit U5 — visible breadcrumb trail.
 *
 * Mirrors the BreadcrumbList that already shipped as JSON-LD. Kept quiet: small,
 * muted, and above the body copy, so it is a position cue rather than another
 * navigation bar competing with the mega-menu.
 */
.asta-breadcrumbs {
  margin: 0 0 1.25rem;
}

.asta-breadcrumbs__list {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.25rem 0.5rem;
  margin: 0;
  padding: 0;
  list-style: none;
  font-size: 0.875rem;
}

.asta-breadcrumbs__item {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  color: var(--wp--preset--color--primary);
}

.asta-breadcrumbs__item + .asta-breadcrumbs__item::before {
  content: "/";
  color: var(--asta-breadcrumbs-separator, currentColor);
  opacity: 0.55;
}

.asta-breadcrumbs__item a {
  text-decoration: none;
  border-bottom: 1px solid transparent;
}

.asta-breadcrumbs__item a:hover,
.asta-breadcrumbs__item a:focus {
  border-bottom-color: currentColor;
}

.asta-breadcrumbs__item span[aria-current] {
  color: var(--asta-panel-ink);
  opacity: 0.85;
}

@media (prefers-color-scheme: dark) {
  .asta-breadcrumbs__item span[aria-current] {
    color: var(--wp--preset--color--base-alt);
  }
}

/*
 * Audit U4/U6 — result count under an archive or search title.
 */
.asta-result-count {
  margin: 0.5rem 0 0;
  font-size: 0.9375rem;
  opacity: 0.8;
}

/* A file that cannot be served says so instead of offering a 0-byte download. */
.asta-file-unavailable {
  color: var(--wp--preset--color--primary);
  font-size: 0.875em;
  font-weight: 600;
  white-space: nowrap;
}
