/* Basis: Reset und Elementstile. Setzt die Tokens in lesbaren Fließtext um. */

*,
*::before,
*::after {
  box-sizing: border-box;
}

html {
  -webkit-text-size-adjust: 100%;
}

/*
  Weiches, orientierendes Scrollen bei allen In-Page-Anker-Klicks
  (Hero-CTA -> #kontakt, Navigation innerhalb der Seite, Zurück-Button des
  Fit-Finders). Nur aktiv, wenn der Nutzer nicht ausdrücklich reduzierte
  Bewegung angefordert hat; unter reduced-motion springt der Browser wie
  gewohnt direkt an das Ziel. `scroll-margin-top` sorgt zugleich dafür, dass
  die Ziel-Sektion nicht unter der sticky Kopfzeile verschwindet, sondern
  einen ruhigen Rand darüber behält.
*/
@media (prefers-reduced-motion: no-preference) {
  html {
    scroll-behavior: smooth;
  }
}

.section,
.hero-editorial,
.page-hero {
  scroll-margin-top: 5rem;
}

body {
  margin: 0;
  font-family: var(--font-body);
  font-size: var(--text-body);
  line-height: var(--line-height-body);
  color: var(--color-text);
  background-color: var(--color-surface);
}

img {
  max-width: 100%;
  display: block;
}

/*
  Schaltflächen erben Schrift und Farbe nicht von selbst, jeder Browser setzt
  dafür eigene Vorgaben ein. Am Schreibtisch fiel das nie auf, weil Chrome ein
  neutrales Schwarz und eine unauffällige Schrift wählt. iOS Safari setzt
  dagegen sein Systemblau und die Systemschrift ein: Der Menü-Knopf erschien
  auf dem iPhone blau und in fremder Schrift, obwohl im Projekt nirgends eine
  blaue Farbe definiert ist. Betroffen waren alle vier Schaltflächenarten
  (Menü, Fit-Finder-Optionen, Zurück, Fortschrittspunkte), weil keine von
  ihnen eine eigene Farbe gesetzt hatte.

  Der Reset zieht Schrift und Farbe auf die Umgebung zurück. Er steht
  bewusst auf dem Element und nicht auf einer Klasse, damit jede künftige
  Schaltfläche automatisch mitgenommen wird; die Komponentenklassen haben die
  höhere Spezifität und überschreiben ihn weiterhin, wo sie eigene Werte
  mitbringen.
*/
button {
  font: inherit;
  color: inherit;
  -webkit-appearance: none;
  appearance: none;
}

h1,
h2,
h3 {
  font-family: var(--font-display);
  line-height: var(--line-height-heading);
  margin: 0 0 var(--space-2);
  font-weight: 600;
}

h1 {
  font-size: var(--text-display);
  line-height: var(--line-height-display);
}

h2 {
  font-size: var(--text-heading);
}

h3 {
  font-size: var(--text-subheading);
}

p {
  margin: 0 0 var(--space-3);
  max-width: var(--text-max-width);
}

p:last-child {
  margin-bottom: 0;
}

a {
  color: var(--color-accent-text);
  text-decoration-thickness: 1px;
  text-underline-offset: 0.15em;
  transition: color var(--duration-state) var(--easing-standard),
    text-decoration-thickness var(--duration-state) var(--easing-standard);
}

a:hover {
  color: var(--color-accent-text-hover);
  text-decoration-thickness: 2px;
}

/*
  Touch-Rückmeldung für Textlinks, siehe Runde 26. Auf einem Touchscreen gibt
  es keinen Hover, ein Antippen blieb deshalb bisher ohne jede Bestätigung.
  Bewusst nur ein Farbwechsel und keine Bewegung: Ein Textlink im Fließtext
  soll beim Antippen antworten, aber nicht springen.
*/
a:active {
  color: var(--color-accent-text-hover);
}

/* Invertierte Flächen (Footer, tiefe Sektions-Bänder) kehren die Linkfarbe um,
   damit sie auf dunklem Waldgrün lesbar bleibt, siehe design-direction.md */
.site-footer a,
.section--band-forest a {
  color: var(--color-link-on-inverse);
}

.site-footer a:hover,
.section--band-forest a:hover {
  color: var(--color-link-on-inverse-hover);
}

ul,
ol {
  padding-left: 1.25em;
  max-width: var(--text-max-width);
}

small,
.meta {
  font-size: var(--text-meta);
  color: var(--color-text-muted);
}

/* Sichtbarer, konsistenter Fokuszustand für Tastaturbedienung, unabhängig vom Element */
:focus-visible {
  outline: 3px solid var(--color-focus);
  outline-offset: 2px;
  border-radius: var(--radius-sm);
}

/* Nur für Sehende verborgen, für Screenreader und Tastaturnutzer verfügbar */
.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/*
  Der Sprunglink ist nur für Tastaturnutzerinnen gedacht und bleibt bis zum
  Fokus außerhalb des Bildes. Er wurde dafür früher über einen festen
  Negativwert (`top: -3rem`) verschoben, was ihn an seine eigene Höhe koppelte:
  Als in Runde 26 der Innenabstand für eine sicher treffbare Fläche vergrößert
  wurde, überstieg seine Höhe die 3rem, und er ragte dauerhaft sichtbar in die
  Seite. Die Verschiebung rechnet jetzt mit der tatsächlichen Höhe des Elements
  (`-100%`) statt mit einem geschätzten Wert und bleibt damit korrekt, egal wie
  sich Schriftgröße oder Innenabstand künftig ändern.
*/
.skip-link {
  position: absolute;
  left: var(--space-2);
  top: var(--space-2);
  transform: translateY(calc(-100% - var(--space-2) - 0.5rem));
  background: var(--color-surface-inverse);
  color: var(--color-text-on-inverse);
  padding: 0.8rem var(--space-2);
  border-radius: var(--radius-sm);
  z-index: 100;
  transition: transform var(--duration-state) var(--easing-standard);
}

.skip-link:focus {
  transform: translateY(0);
}

/*
  Scroll-Reveal, siehe animation-plan.md, Aufgabe "Orientieren": erklärt den
  Eintritt eines Abschnitts in den sichtbaren Bereich. Die Klasse js-reveal-ready
  wird von assets/js/main.js nur gesetzt, wenn IntersectionObserver tatsächlich
  läuft, deshalb bleibt jeder Inhalt ohne JavaScript sofort sichtbar, siehe
  Vellox-OS/06_SEO/01-technisches-seo.md zur Unabhängigkeit der Kerninhalte
  von einer einzelnen Laufzeitbedingung.
*/
.js-reveal-ready [data-reveal] {
  opacity: 0;
  transform: translateY(1.5rem);
  transition: opacity var(--duration-reveal) var(--easing-emphasis),
    transform var(--duration-reveal) var(--easing-emphasis);
}

.js-reveal-ready [data-reveal].is-revealed {
  opacity: 1;
  transform: none;
}

.js-reveal-ready [data-reveal-delay="1"] {
  transition-delay: 90ms;
}

.js-reveal-ready [data-reveal-delay="2"] {
  transition-delay: 180ms;
}

/*
  Akzent-Unterstrich unter Abschnittsüberschriften. Ohne Bewegung bleibt er
  sichtbar in voller Länge, mit aktivem Reveal wächst er beim Eintritt, siehe
  animation-plan.md, Aufgabe "Gewichten".
*/
.section__heading {
  position: relative;
  padding-bottom: var(--space-2);
}

/*
  Optionale, ruhige Subline direkt unter der Abschnittsüberschrift, siehe
  Runde 9. Sie beantwortet die Frage „warum steht dieser Abschnitt hier",
  in einer Zeile, in gedämpfter Farbe. Der wachsende Terrakotta-Unterstrich
  rückt darunter, weil padding-bottom auf dem Container liegt.
*/
.section__heading p {
  margin: var(--space-1) 0 0;
  color: var(--color-text-muted);
  font-size: var(--text-body);
  max-width: 32rem;
}

.section--band-forest .section__heading p {
  color: #c8cfba;
}

.section__heading::after {
  content: "";
  position: absolute;
  left: 0;
  bottom: 0;
  height: 3px;
  width: 3rem;
  border-radius: 2px;
  background-color: var(--color-surface-forest);
}

.js-reveal-ready .section__heading[data-reveal]::after {
  width: 0;
  transition: width var(--duration-moment) var(--easing-emphasis) 150ms;
}

.js-reveal-ready .section__heading[data-reveal].is-revealed::after {
  width: 3rem;
}

.section--band-forest .section__heading::after {
  background-color: var(--color-surface-sage-tint);
}

/*
  Druckregeln, siehe Runde 36. Bis dahin gab es keine, und ein Ausdruck warf
  drei konkrete Probleme auf: Die farbigen Bänder verbrauchten Toner ohne
  Aussage, die Navigation und die Schaltflächen wurden mitgedruckt, obwohl sie
  auf Papier nichts tun, und die zugeklappten Antworten der Fragen-Abschnitte
  fehlten vollständig, weil `details` ohne `open` seinen Inhalt nicht ausgibt.

  Gedruckt wird realistisch vor allem dreierlei: die Kontaktangaben, der Ablauf
  als Merkzettel vor einem Termin, und die Rechtstexte. Alle drei brauchen
  lesbaren Fließtext auf weißem Grund, keine Gestaltung.

  Die Adresse hinter Links wird ausgegeben, aber nur bei Links, die aus dem
  Dokument herausführen. Bei Sprungmarken innerhalb der Seite wäre sie sinnlos,
  bei mailto und tel steht die Information bereits im Linktext.
*/
@media print {
  .site-header,
  .site-nav,
  .nav-toggle,
  .skip-link,
  .button,
  .fitcheck,
  .hero-editorial__figure::before {
    display: none !important;
  }

  body {
    background: #fff;
    color: #000;
    font-size: 11pt;
    line-height: 1.45;
  }

  .section,
  .hero-editorial,
  .page-hero,
  .site-footer,
  .section--band-sage,
  .section--band-forest,
  .section--muted,
  .surface {
    background: none !important;
    color: #000 !important;
    box-shadow: none !important;
    padding-block: 0.6cm;
  }

  .section--band-forest a,
  .site-footer a,
  a {
    color: #000;
  }

  /* Zugeklappte Antworten werden auf Papier sonst gar nicht ausgegeben */
  details {
    display: block;
  }

  details > *:not(summary) {
    display: revert !important;
  }

  summary {
    font-weight: 700;
    list-style: none;
  }

  /* Nur Ziele außerhalb des Dokuments brauchen ihre Adresse im Ausdruck */
  a[href^="http"]::after {
    content: " (" attr(href) ")";
    font-size: 9pt;
    word-break: break-all;
  }

  h1, h2, h3 {
    break-after: avoid;
    page-break-after: avoid;
  }

  p, li, .faq-item {
    break-inside: avoid;
    page-break-inside: avoid;
  }

  img {
    max-width: 60mm;
  }

  /* Reveal-Animationen dürfen im Druck nichts verbergen */
  .js-reveal-ready [data-reveal] {
    opacity: 1 !important;
    transform: none !important;
  }
}
