:root {
  --form-error-color: #a8443a;
}

/* Anchor target for the contactform element (#kontaktformular). #header is
   position: fixed, so without this offset an anchored jump lands behind it.
   Tune to match the header height if it changes. */
#kontaktformular {
  scroll-margin-top: 8rem;
}

.uppercase {
  text-transform: uppercase !important;
}

span.error,
label.error {
  color: var(--form-error-color);
}
.text-body {
  p {
    margin-bottom: 1rem;
  }
}

/* Contact form underline animation override.
   main.css animates the focus underline via .form-field::after (anchored to the
   wrapper's bottom). When a validation error renders inside the wrapper, that
   anchor drops below the error message. We disable the wrapper pseudo-element and
   animate the underline directly on the control instead, so it stays put under
   the input and the error message sits cleanly below it. */
.form-field:has(.form-input, .form-textarea, .form-select)::after {
  display: none;
}

.form-input,
.form-textarea,
.form-select {
  background-image: linear-gradient(currentColor, currentColor);
  background-repeat: no-repeat;
  background-position: left bottom;
  background-size: 0% 2px;
  transition: background-size 0.35s ease;
}

/* Error state: turn the underline red (static border + animated gradient),
   while leaving the typed text in its normal color. The :focus gradient is
   re-declared with currentColor in main.css/above, so it must be overridden
   here too, otherwise focusing an invalid field would reset it to black. */
.field_with_errors .form-input,
.field_with_errors .form-textarea,
.field_with_errors .form-select,
.field_with_errors .form-input:focus,
.field_with_errors .form-textarea:focus,
.field_with_errors .form-select:focus {
  border-bottom-color: var(--form-error-color);
  background-image: linear-gradient(
    var(--form-error-color),
    var(--form-error-color)
  );
}

.field_with_errors .form-checkbox input {
  border-color: var(--form-error-color);
}

.form-input:focus,
.form-textarea:focus,
.form-select:focus {
  background-image: linear-gradient(currentColor, currentColor);
  background-repeat: no-repeat;
  background-position: left bottom;
  background-size: 100% 2px;
  transition: background-size 0.35s ease;
}

/* No-hero content pages (e.g. legal). These pages have no full-bleed hero behind
   the fixed header, so the header must show its solid "scrolled" treatment from the
   first paint instead of the transparent-over-image look. The `body.no-hero` class
   is set server-side (see ApplicationHelper#page_has_hero?), so this is driven by
   template logic — not the scroll/JS animation. The rules below mirror main.css's
   `#header.sticky-h …` block; overrides.css loads after main.css, so they win at
   matching specificity, and the JS-toggled sticky-h class becomes a visual no-op. */
.no-hero #header {
  font-size: 0.85em !important;
  background: #f6f2ec;
  border-bottom: 1px solid #ebe6de;
}
.no-hero #header .logo img {
  max-width: 60%;
  transition: all 0.7s ease-in-out;
}
.no-hero #header .logo img.logo-w {
  opacity: 0;
}
.no-hero #header .logo img.logo-c {
  opacity: 1;
}
.no-hero #header .headerbar .menu {
  color: #000;
  padding-top: 1.5rem;
}
.no-hero #header .headerbar .menu a,
.no-hero #header .headerbar .menu .button {
  color: #000;
  margin: 0;
  line-height: normal;
}
.no-hero #header .headerbar .menu a:hover,
.no-hero #header .headerbar .menu a.active {
  color: #518196;
  text-decoration: none;
}
.no-hero #header .headerbar .menu .button-w {
  color: #000 !important;
  border-color: #000;
}
.no-hero #header .headerbar .menu .button-w:hover,
.no-hero #header .headerbar .menu .button-w:focus {
  color: #fff !important;
  border-color: #518196;
}
.no-hero #header .hamburger {
  color: #000;
}
.no-hero #header .hamburger-inner,
.no-hero #header .hamburger-inner::before,
.no-hero #header .hamburger-inner::after {
  background-color: #000;
}
.no-hero #header .headerbar.m2active a,
.no-hero #header .headerbar.m2active .button {
  color: #fff;
}
.no-hero #header .headerbar.m2active .button-w {
  color: #fff !important;
  border-color: #fff;
}
.no-hero #header .headerbar.m2active .button-w:hover,
.no-hero #header .headerbar.m2active .button-w:focus {
  border-color: #fff;
}
.no-hero #header .headerbar.m2active .hamburger {
  color: #fff;
}
.no-hero #header .headerbar.m2active .hamburger-inner,
.no-hero #header .headerbar.m2active .hamburger-inner::before,
.no-hero #header .headerbar.m2active .hamburger-inner::after {
  background-color: #fff;
}
.no-hero #header .headerbar.m2active .hamburger:hover .hamburger-inner,
.no-hero #header .headerbar.m2active .hamburger:hover .hamburger-inner::before,
.no-hero #header .headerbar.m2active .hamburger:hover .hamburger-inner::after {
  background-color: #fff;
}

/* Without a hero behind it, the fixed header no longer overlaps a full-bleed
   image — offset the content below the solid header instead. Matches the header
   padding steps in main.css's responsive breakpoints. */
.no-hero #main {
  padding-top: 9rem;
}
@media print, screen and (max-width: 64em) {
  .no-hero #main {
    padding-top: 7rem;
  }
}

/* Hero parallax overhang fix. main.css gives .parallax-img a 10% overhang
   (top: -10%; height: 120%), but the GSAP parallax translation exceeds that
   budget. Because the hero is the first element on the page it rests partway
   through its scroll range (never at progress 0), nudging the image downward —
   and the shorter "medium" (.hero2) size rests further along, exposing a few-px
   gap at the top. Widening the overhang to 15% each side keeps the image
   covered at every size without weakening the parallax effect elsewhere. */
.parallax-img {
  top: -15%;
  height: 130%;
}
