/*
 * The website's only stylesheet — copied verbatim into site/dist/ by
 * tools/site/build.ts.
 *
 * Rules that are not style choices but commitments (legal/de/datenschutz.md
 * § 6.2, legal/PRUEFPUNKTE.md point 11): no @import, no url() to another host,
 * no web fonts. System fonts only, everything self-hosted, no request ever
 * leaves the origin.
 */

/* ---------------------------------------------------------------- tokens -- */

/*
 * Die Farben stammen aus dem Programm selbst — #1e2128 als Grund, #262a33 als
 * hellerer Ton, #4f8cff als Akzent; dasselbe Blau wie im App-Icon. Der
 * Wiedererkennungswert ist der ganze Zweck.
 *
 * IM HELLEN MODUS IST DER AKZENT EIN ANDERER, und das ist kein Versehen:
 * #4f8cff auf hellem Grund erreicht nur 3,2:1 und reicht damit weder für
 * Verweise noch für eine Knopfbeschriftung. Das abgedunkelte #2f6ad9 derselben
 * Familie kommt auf 5,0:1 — im Nebeneinander kaum zu unterscheiden, aber für
 * Menschen mit schwächeren Augen und bei Sonnenlicht der Unterschied zwischen
 * lesbar und nicht.
 *
 * Wer hier eine Farbe ändert, rechnet den Kontrast bitte nach (WCAG 2.1: 4,5:1
 * für Fließtext, 3:1 für große Schrift) statt nach Augenmaß zu gehen. Genau
 * dieser Punkt entscheidet, ob die Seite für einen Teil der Käufer benutzbar
 * ist — und das sieht man ihr mit gesunden Augen auf einem guten Schirm nicht an.
 */
:root {
  color-scheme: light dark;

  --bg: #f7f8fa;
  --bg-alt: #eceef3;
  --surface: #ffffff;
  --border: #dde0e6;
  --border-strong: #c1c6d1;
  /* Der Fließtext trägt den dunklen Programmton — dieselbe Farbfamilie. */
  --text: #1e2128;
  --text-muted: #5a616e;
  /* Abgedunkeltes #4f8cff: 5,02:1 auf Weiß, 4,72:1 auf dem Seitengrund. */
  --accent: #2f6ad9;
  --accent-hover: #24539f;
  /* Fläche von Knöpfen. Im hellen Modus dieselbe Farbe wie der Verweis; im
     dunklen das UNVERÄNDERTE Icon-Blau, weil dort dunkle Schrift daraufliegt
     und der Kontrast damit stimmt (5,01:1). */
  --accent-solid: #2f6ad9;
  --on-accent: #ffffff;
  --accent-bg: #e8effc;
  --shadow: 0 1px 2px rgb(30 33 40 / 5%), 0 8px 24px rgb(30 33 40 / 7%);

  --font: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial,
    sans-serif;
  --font-mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas,
    monospace;

  --wrap: 62rem;
  --radius: 10px;
}

@media (prefers-color-scheme: dark) {
  :root {
    /* Hier stehen die Programmfarben unverändert. */
    --bg: #1e2128;
    --surface: #262a33;
    /* Eine Spur heller als die Karten, sonst verschwänden die Code-Felder
       darauf spurlos — sie benutzen denselben Wert. */
    --bg-alt: #2e333e;
    --border: #3a4050;
    --border-strong: #545c70;
    --text: #e9ecf2;
    --text-muted: #a4abb9;
    /* Etwas heller als #4f8cff: auf dem Kartenton #262a33 käme das reine
       Icon-Blau nur auf 4,47:1 und verfehlte den Fließtext-Wert knapp. Die
       Knöpfe unten benutzen weiterhin das unveränderte #4f8cff. */
    --accent: #649bff;
    --accent-hover: #8fb6ff;
    --accent-solid: #4f8cff;
    --on-accent: #1e2128;
    --accent-bg: #23304a;
    --shadow: 0 1px 2px rgb(0 0 0 / 35%), 0 8px 24px rgb(0 0 0 / 32%);
  }
}

/* ------------------------------------------------------------------ base -- */

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

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

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: var(--font);
  font-size: 1.0625rem;
  line-height: 1.65;
  /* Long compound nouns (Umsatzsteuer-Identifikationsnummer …) must never push
     the layout wider than the viewport on a 360 px phone. */
  overflow-wrap: break-word;
  hyphens: auto;
}

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

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

a:hover {
  color: var(--accent-hover);
}

:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  border-radius: 3px;
}

h1,
h2,
h3 {
  line-height: 1.2;
  letter-spacing: -0.01em;
  text-wrap: balance;
  margin: 0 0 0.5em;
}

h1 {
  font-size: clamp(1.85rem, 1.25rem + 2.6vw, 2.8rem);
}

h2 {
  font-size: clamp(1.35rem, 1.1rem + 1.1vw, 1.75rem);
}

h3 {
  font-size: 1.0625rem;
}

p {
  margin: 0 0 1em;
}

code {
  font-family: var(--font-mono);
  font-size: 0.9em;
  background: var(--bg-alt);
  padding: 0.1em 0.35em;
  border-radius: 4px;
}

hr {
  border: 0;
  border-top: 1px solid var(--border);
  margin: 2rem 0;
}

.wrap {
  width: min(var(--wrap), 100% - 2.5rem);
  margin-inline: auto;
}

.skip {
  position: absolute;
  left: -9999px;
}

.skip:focus {
  position: static;
  display: inline-block;
  margin: 0.5rem;
  padding: 0.5rem 0.75rem;
  background: var(--surface);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius);
}

/* ---------------------------------------------------------------- header -- */

/* Sprungziele müssen UNTER der mitlaufenden Leiste landen, nicht dahinter.
   Ohne das verdeckt die Leiste genau die Überschrift, zu der gesprungen wurde —
   gemessen 63 px am Rechner, 103 px auf dem Handy, wo sie zweizeilig umbricht.
   Mit etwas Luft darüber, damit die Überschrift nicht an der Kante klebt. */
:target,
section[id],
[id] > h2 {
  scroll-margin-top: 5.5rem;
}

@media (max-width: 599px) {
  :target,
  section[id],
  [id] > h2 {
    scroll-margin-top: 8rem;
  }
}

/* Mitlaufend: Die Produktseite ist auf dem Handy fast neun Bildschirme hoch.
   Ohne mitlaufende Leiste heißt „ich will das kaufen" ganz nach oben wischen.
   `position: sticky` ist reines CSS — kein JavaScript, keine Zusage gebrochen. */
.site-head {
  position: sticky;
  top: 0;
  z-index: 20;
  border-bottom: 1px solid var(--border);
  background: var(--surface);
}

/* Auf dem Handy bricht die Leiste auf zwei Zeilen um und nähme mitlaufend zu
   viel vom Bildschirm. Deshalb dort enger und kleiner. */
@media (max-width: 599px) {
  .head-in {
    padding: 0.55rem 0;
    gap: 0.35rem 1rem;
  }

  .head-nav {
    font-size: 0.9rem;
    gap: 0.25rem 1rem;
  }
}

/* Die Hauptaktion sieht in der Leiste auch wie eine aus.
   MIT `.head-nav` davor, und das ist kein Schmuck: `.head-nav a` färbt alle
   Verweise der Leiste grau und ist spezifischer als ein einzelner Klassenname.
   Ohne den Vorsatz stand hier grauer Text auf blauem Grund. */
.head-nav a.nav-buy {
  background: var(--accent-solid);
  color: var(--on-accent);
  font-weight: 600;
  border-radius: 6px;
  padding: 0.25rem 0.7rem;
}

.head-nav a.nav-buy:hover {
  background: var(--accent-hover);
  color: var(--on-accent);
  text-decoration: none;
}

.head-in {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem 1.5rem;
  padding: 0.9rem 0;
}

.brand {
  display: inline-flex;
  align-items: center;
  gap: 0.55rem;
  color: var(--text);
  font-weight: 600;
  font-size: 1.05rem;
  letter-spacing: -0.01em;
  text-decoration: none;
}

.brand:hover {
  color: var(--accent);
}

.brand svg {
  flex: none;
  color: var(--accent);
}

.head-nav {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem 1.25rem;
  font-size: 0.95rem;
}

.head-nav a {
  color: var(--text-muted);
  text-decoration: none;
}

.head-nav a:hover {
  color: var(--accent);
  text-decoration: underline;
}

.lang-nav {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.35rem;
  font-size: 0.85rem;
  color: var(--text-muted);
}

.lang-nav a {
  color: var(--text-muted);
  text-decoration: none;
}

.lang-nav a:hover {
  color: var(--accent);
}

.lang-nav [aria-current="page"] {
  color: var(--text);
  font-weight: 600;
}

.card-lang {
  margin: 0.35rem 0 0;
  font-size: 0.9rem;
}

/* ------------------------------------------------------------------ hero -- */

.hero {
  padding: clamp(2.5rem, 1.5rem + 5vw, 5rem) 0 clamp(2rem, 1rem + 3vw, 3.5rem);
}

.hero p.lead {
  font-size: clamp(1.05rem, 1rem + 0.4vw, 1.2rem);
  color: var(--text-muted);
  max-width: 44rem;
  margin-bottom: 0;
  /* Keine Silbentrennung in der Begrüßung: Der Absatz ist auf 44rem begrenzt,
     Platz ist also da — „Eismoti-ve" und „For-mat" lasen sich wie Zeilennot
     (Christian, 26.08.). Auf 360 px fängt overflow-wrap weiterhin auf. */
  hyphens: manual;
}

/* Folgen zwei Absätze aufeinander, brauchen sie einen sichtbaren Abstand —
   sonst ist die Aufteilung im Quelltext vorhanden und auf der Seite nicht. */
.hero p.lead + p.lead {
  margin-top: 0.9rem;
}

/* Programmname mit dem App-Icon daneben: dasselbe Bild, das später im Dock
   steht — der Wiedererkennungswert ist der ganze Zweck. Nur Augenbraue und
   Überschrift stehen neben dem Icon; der Absatz darunter beginnt wieder an der
   linken Kante, bündig mit dem Icon, statt um dessen Breite eingerückt zu sein. */
.hero-head {
  display: flex;
  align-items: center;
  gap: 1.25rem;
  margin-bottom: 1.5rem;
}

.hero-head > div {
  min-width: 0;
}

.hero-head h1,
.hero-head .eyebrow {
  margin-bottom: 0;
}

.hero-head .eyebrow {
  margin-bottom: 0.35rem;
}

.app-icon {
  flex: none;
  width: clamp(56px, 8vw, 88px);
  height: auto;
  border-radius: 22%;
}

/* Unter 480 px rutscht das Icon über die Überschrift, statt ihr die halbe
   Zeilenbreite zu nehmen — „Beh.Stitched" bräche sonst mitten im Wort. */
@media (max-width: 479px) {
  .hero-head {
    flex-direction: column;
    align-items: flex-start;
    gap: 0.9rem;
  }
}

/* Das Eröffnungsbild des Rundgangs steht über den Wegen, in voller Breite. */
.tour-opener {
  margin: 0 0 2.25rem;
}

/* Kopfbereich der Produktseite: Text links, Bild rechts. Unter 900 px steht das
   Bild darunter — auf dem Handy zuerst lesen, dann sehen. */
.hero-grid {
  display: grid;
  gap: 1.75rem;
  align-items: center;
}

@media (min-width: 900px) {
  .hero-grid {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1.05fr);
    gap: 2.5rem;
  }
}

.hero-shot {
  margin: 0;
}

.hero-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
  margin: 1.5rem 0 0;
}

.hero-price {
  margin: 0.9rem 0 0;
  color: var(--text-muted);
  font-size: 0.98rem;
}

.hero-price::first-line {
  font-weight: 600;
}

/* Die fünf, sechs Aussagen, die einen Kauf entscheiden — mit Luft, damit man
   sie im Vorbeiscrollen mitnimmt. */
.tiles {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 17rem), 1fr));
  gap: 1rem;
  margin: 1.5rem 0 0;
}

.tile {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 1.1rem 1.2rem;
}

.tile h3 {
  margin: 0 0 0.35rem;
}

.tile p {
  margin: 0;
  color: var(--text-muted);
  font-size: 0.95rem;
}

/* Die vollständige Funktionsliste — rund vierzig Stichpunkte — steht
   zugeklappt darunter. Wer wissen will, ob das Programm zu ihm passt, liest die
   Kacheln; wer Einzelheiten sucht, klappt auf. */
.feature-details {
  margin-top: 2rem;
  border-top: 1px solid var(--border);
  padding-top: 1rem;
}

.feature-details > summary {
  cursor: pointer;
  font-weight: 600;
  color: var(--accent);
  padding: 0.2rem 0;
}

.feature-details > summary:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  border-radius: 4px;
}

/* Lizenzbedingungen unter den Kaufknöpfen, nicht davor. */
.buy-points {
  margin: 1.4rem 0 0;
  color: var(--text-muted);
  font-size: 0.95rem;
}

/* Die Einzelheiten zur Lizenz — wie die Funktionsliste zugeklappt. Sichtbar
   bleiben zwei Punkte; was hier steht, liest ohnehin niemand VOR der
   Entscheidung, muss aber vollständig nachlesbar sein. */
.buy-details {
  margin-top: 1rem;
}

.buy-details > summary {
  cursor: pointer;
  color: var(--accent);
  font-size: 0.95rem;
  padding: 0.2rem 0;
}

.buy-details > summary:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  border-radius: 4px;
}

.buy-details ul {
  color: var(--text-muted);
  font-size: 0.95rem;
  margin: 0.6rem 0 0;
}

.card-price {
  margin: 0.2rem 0 0;
  font-weight: 600;
}

.eyebrow {
  display: inline-block;
  font-size: 0.8rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text-muted);
  margin-bottom: 0.75rem;
}

/* --------------------------------------------------------------- section -- */

/* Trennlinien nur dort, wo sie gliedern statt zu zerhacken. Vorher trug JEDER
   Abschnitt eine Linie oben — bei sieben Abschnitten liest sich das wie ein
   Formular, nicht wie eine Seite. Jetzt rahmen genau zwei Blöcke ein: die
   Funktions-Highlights und der Download-Bereich. */
section {
  padding: clamp(2rem, 1.25rem + 3vw, 3.25rem) 0;
}

/* Auf dem Handy enger: sechs Abschnitte × zweimal 32 px sind fast ein halber
   Bildschirm allein an Zwischenraum. */
@media (max-width: 599px) {
  section {
    padding: 1.5rem 0;
  }
}

.section-framed {
  border-top: 1px solid var(--border);
  border-bottom: 1px solid var(--border);
}

section > .wrap > p:first-of-type {
  color: var(--text-muted);
  max-width: 44rem;
}

/* ----------------------------------------------------------------- cards -- */

.cards {
  display: grid;
  /* auto-FILL, not auto-fit: with a single product the card keeps a sensible
     column width instead of stretching across the whole page. */
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 21rem), 1fr));
  gap: 1.25rem;
  margin: 1.75rem 0 0;
  padding: 0;
  list-style: none;
}

.card {
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: 1.4rem 1.4rem 1.5rem;
}

.card h3 {
  font-size: 1.3rem;
  margin: 0;
}

.card .tagline {
  color: var(--text-muted);
  font-size: 0.95rem;
  margin: 0;
}

.card p.body {
  margin: 0.3rem 0 0;
}

.card .more {
  margin-top: auto;
  padding-top: 0.9rem;
  font-weight: 600;
  text-decoration: none;
}

.card .more:hover {
  text-decoration: underline;
}

.badge {
  align-self: flex-start;
  font-size: 0.78rem;
  font-weight: 600;
  letter-spacing: 0.02em;
  color: var(--accent);
  background: var(--accent-bg);
  border-radius: 999px;
  padding: 0.15rem 0.6rem;
}

/* ----------------------------------------------------------------- steps -- */

.steps {
  display: grid;
  /* 14rem lets all four workflow steps sit in one row on a desktop width. */
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 14rem), 1fr));
  gap: 1.25rem;
  margin: 1.75rem 0 0;
  padding: 0;
  list-style: none;
  counter-reset: step;
}

.steps li {
  counter-increment: step;
  border-top: 2px solid var(--border-strong);
  padding-top: 0.9rem;
}

.steps li h3 {
  margin: 0 0 0.3rem;
}

.steps li h3::before {
  content: counter(step) " · ";
  color: var(--text-muted);
  font-variant-numeric: tabular-nums;
}

.steps li p {
  margin: 0;
  color: var(--text-muted);
  font-size: 0.97rem;
}

/* -------------------------------------------------------------- features -- */

/* Zwei Spalten, deren Inhalt im HTML festgelegt ist — nicht ein Raster, das
   zeilenweise füllt und die Zuordnung beim nächsten neuen Block umwürfe. Unter
   760 px stapeln sich die Spalten in Lesefolge untereinander. */
.groups {
  display: grid;
  gap: 1.25rem 2.5rem;
  margin-top: 1.5rem;
}

@media (min-width: 760px) {
  .groups {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    align-items: start;
  }
}

.group-col {
  display: flex;
  flex-direction: column;
  gap: 1.25rem;
}

.groups h3 {
  margin-bottom: 0.4rem;
}

.groups ul {
  margin: 0;
  padding-left: 1.1rem;
}

.groups li,
.groups p {
  margin-bottom: 0.35rem;
  color: var(--text-muted);
  font-size: 0.97rem;
}

.groups p {
  margin: 0;
}

/* --------------------------------------------------------------- formats -- */

.format-group {
  margin-top: 1.5rem;
}

.format-group h3 {
  margin-bottom: 0.5rem;
}

.pills {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
  margin: 0 0 0.5rem;
  padding: 0;
  list-style: none;
}

.pills li {
  font-family: var(--font-mono);
  font-size: 0.85rem;
  letter-spacing: 0.02em;
  background: var(--bg-alt);
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 0.15rem 0.55rem;
}

.note {
  color: var(--text-muted);
  font-size: 0.92rem;
  margin: 0;
  max-width: 44rem;
}

/* Abstand nach oben, wo eine Anmerkung direkt an einen Block anschliesst.
   Früher ein style="…"-Attribut in build.ts — das ist jetzt verboten: die
   Content-Security-Policy der Seite erlaubt nur Stile aus dieser Datei, damit
   überhaupt keine Lücke bleibt, durch die eingebetteter Code hereinkäme. */
.note-spaced {
  margin-top: 1.25rem;
}

/* -------------------------------------------------------------- purchase -- */

.buy {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: clamp(1.4rem, 1rem + 1.5vw, 2.2rem);
  margin-top: 1.5rem;
}

.buy ul {
  margin: 0 0 1.5rem;
  padding-left: 1.1rem;
}

.buy li {
  margin-bottom: 0.4rem;
  color: var(--text-muted);
}

.buy-platforms {
  margin: 0.85rem 0 1.1rem;
  max-width: 40rem;
  padding: 0.75rem 0.9rem;
  border-left: 3px solid var(--accent);
  background: var(--surface-2, var(--surface));
}

/* Zwei Kaufknöpfe (privat / gewerblich) nebeneinander, auf schmalen Schirmen
   untereinander. */
.buy-buttons {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem 1.5rem;
  margin: 0.4rem 0 0.2rem;
}

/* Knopf und Preis gehören zusammen und dürfen nie getrennt umbrechen: Ein
   Preis, der unter dem falschen Knopf landet, ist keine Unschönheit, sondern
   eine falsche Preisangabe. */
.buy-option {
  display: inline-flex;
  align-items: baseline;
  gap: 0.6rem;
  white-space: nowrap;
}

.buy-price {
  font-weight: 600;
  font-size: 1.05rem;
}

.button {
  display: inline-block;
  background: var(--accent-solid);
  color: var(--on-accent);
  font-weight: 600;
  text-decoration: none;
  border-radius: 8px;
  padding: 0.6rem 1.3rem;
}

.button:hover {
  background: var(--accent-hover);
  color: var(--on-accent);
}

.cta-note {
  color: var(--text-muted);
  font-size: 0.92rem;
  margin: 0.9rem 0 0;
  max-width: 40rem;
}

/* -------------------------------------------------------------- download -- */

.downloads {
  display: grid;
  gap: 1.25rem;
  margin: 1.5rem 0 0;
}

@media (min-width: 760px) {
  .downloads {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

.download {
  display: flex;
  flex-direction: column;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: 1.4rem 1.4rem 1.5rem;
}

.download h3 {
  font-size: 1.3rem;
  margin: 0 0 0.15rem;
}

/* Version · Größe · Datum. Klein und ruhig direkt unter dem Systemnamen —
   es sind Angaben, die man einmal überfliegt, nicht liest. */
.download-facts {
  color: var(--text-muted);
  font-size: 0.88rem;
  margin: 0 0 0.8rem;
}

.download-req {
  color: var(--text-muted);
  font-size: 0.95rem;
  margin: 0 0 1rem;
}

/* Das Datenschutz-Argument über den Karten. Abgesetzt wie die Hinweise in den
   Karten selbst, damit beides als dieselbe Art Auskunft gelesen wird: hier ist,
   was du wissen willst, bevor du das Programm auf deinen Rechner lässt. */
.download-privacy {
  border-left: 3px solid var(--accent-solid);
  padding-left: 0.9rem;
  margin: 0 0 0.5rem;
  max-width: 46rem;
}

/* Hinweis auf etwas, das dem Besucher gleich begegnet — derzeit die Warnung,
   die Windows bei einem unsignierten Installationsprogramm zeigt. Abgesetzt
   durch einen Balken statt durch Signalfarbe: Es ist keine Gefahr, sondern
   etwas, das man vorher wissen will. Rot wäre eine Übertreibung, die genau die
   Sorge auslöst, die der Text ausräumen soll. */
.download-firstrun {
  border-left: 3px solid var(--border-strong);
  padding-left: 0.85rem;
  color: var(--text-muted);
  font-size: 0.95rem;
  margin: 0 0 1rem;
}

/* Der Knopf sitzt unten, auch wenn die Nachbarkarte längeren Text hat: die
   Karte ist ein Flex-Container, dieser Abstand schiebt ihn ans Ende. So stehen
   „Für Windows herunterladen" und „Für macOS herunterladen" auf einer Höhe,
   statt um die Länge des Windows-Hinweises versetzt. */
.download-cta {
  margin: auto 0 0;
  padding-top: 0.3rem;
}

/* Dateiname und Prüfsumme sind ausgeklappt sofort die längste Stelle der
   Karte, werden aber von den wenigsten gebraucht. Zusammengefaltet bleibt der
   Knopf oberhalb der Falz — und ohne eine Zeile JavaScript, was auf dieser
   Seite kein Detail ist, sondern eine Zusage. */
.download-details {
  margin-top: 1.1rem;
  border-top: 1px solid var(--border);
  padding-top: 0.7rem;
  font-size: 0.92rem;
}

.download-details > summary {
  cursor: pointer;
  color: var(--text-muted);
  padding: 0.15rem 0;
}

.download-details > summary:hover {
  color: var(--accent);
}

/* Sichtbar, wo die Tastatur gerade steht — ein <summary> ist ein Bedienelement
   wie ein Knopf, auch wenn es nicht so aussieht. */
.download-details > summary:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  border-radius: 4px;
}

.download-check {
  color: var(--text-muted);
  margin: 0 0 0.6rem;
}

.download-check:last-child {
  margin-bottom: 0;
}

/* Dateiname und Prüfsumme. Zwei Spalten, damit die Werte untereinander stehen;
   unter 420 px bricht die Beschriftung auf eine eigene Zeile, sonst bliebe für
   eine 64-stellige Prüfsumme kein Platz. */
.download-meta {
  margin: 0.6rem 0 0.9rem;
  font-size: 0.92rem;
}

.download-meta > div {
  display: grid;
  grid-template-columns: 6.5rem minmax(0, 1fr);
  gap: 0.2rem 0.75rem;
  padding: 0.3rem 0;
  border-top: 1px solid var(--border);
}

@media (max-width: 419px) {
  .download-meta > div {
    grid-template-columns: minmax(0, 1fr);
  }
}

.download-meta dt {
  color: var(--text-muted);
}

.download-meta dd {
  margin: 0;
}

/* Prüfsummen und Befehlszeilen haben keine Leerzeichen zum Umbrechen. Ohne
   diese Regel schöbe eine 64-stellige Zeichenkette die ganze Seite auf einem
   360-px-Schirm seitlich hinaus. */
.breakable {
  overflow-wrap: anywhere;
  word-break: break-all;
}

/* Das iPad steht unter den beiden Karten, nicht daneben: Hier gibt es nichts
   herunterzuladen, und eine dritte Karte in derselben Reihe würde genau das
   versprechen. Deshalb über die volle Breite, ohne Schlagschatten. Der Knopf
   führt in den App Store. */
.ipad {
  margin-top: 1.5rem;
  border: 1px solid var(--border);
  border-left: 3px solid var(--accent);
  border-radius: 8px;
  padding: 1.2rem 1.4rem;
  background: var(--surface);
}

.ipad h3 {
  margin: 0 0 0.5rem;
}

.ipad p {
  color: var(--text-muted);
  font-size: 0.95rem;
  margin: 0 0 0.7rem;
  max-width: 46rem;
}

.ipad-cta {
  margin: 1rem 0 0;
}

/* Umrandeter Knopf statt gefülltem, wo ein zweiter Aufruf neben einem
   Hauptknopf stehen soll. */
.button-quiet {
  background: transparent;
  color: var(--accent);
  border: 1px solid var(--accent);
  padding: 0.5rem 1.15rem;
}

.button-quiet:hover {
  background: var(--accent-bg);
  color: var(--accent-hover);
}

@media (prefers-color-scheme: dark) {
  .button-quiet,
  .button-quiet:hover {
    color: var(--accent);
  }
}

/* -------------------------------------------------------- version history -- */

.release {
  border-top: 1px solid var(--border);
  padding-top: 1.5rem;
  margin-top: 2rem;
}

.release h2 {
  margin-bottom: 0.6rem;
}

.release-date {
  font-size: 0.95rem;
  font-weight: 400;
  color: var(--text-muted);
  white-space: nowrap;
}

/* ----------------------------------------------------------------- prose -- */

.prose {
  max-width: 44rem;
  padding: clamp(2rem, 1.5rem + 3vw, 3.5rem) 0;
}

.prose h1 {
  margin-bottom: 1rem;
}

.prose h2 {
  margin-top: 2rem;
}

.prose h3 {
  margin-top: 1.5rem;
  font-size: 1.05rem;
}

.prose ul {
  padding-left: 1.2rem;
}

.prose li {
  margin-bottom: 0.35rem;
}

.prose .meta {
  color: var(--text-muted);
  font-size: 0.92rem;
  margin-bottom: 2rem;
}

/* ---------------------------------------------------------------- footer -- */

.site-foot {
  border-top: 1px solid var(--border);
  background: var(--bg-alt);
  padding: 2rem 0 2.5rem;
  font-size: 0.92rem;
  color: var(--text-muted);
  margin-top: 2rem;
}

.foot-nav {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem 1.5rem;
  margin: 0 0 0.9rem;
  padding: 0;
  list-style: none;
}

.foot-nav a {
  text-decoration: none;
}

.foot-nav a:hover {
  text-decoration: underline;
}

.site-foot p {
  margin: 0 0 0.4rem;
}

/* Tutorial videos — SELF-HOSTED. See site/assets/video/README.md: a
   third-party player would make the privacy statement untrue and force a
   consent banner. tools/site/verify.ts fails the build on any iframe. */

.videos {
  display: grid;
  gap: 28px;
  margin-top: 20px;
}

@media (min-width: 900px) {
  .videos {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

.video {
  margin: 0;
}

.video video {
  display: block;
  width: 100%;
  height: auto;
  border-radius: 8px;
  background: #000;
  border: 1px solid var(--border);
}

.video figcaption h3 {
  display: flex;
  align-items: baseline;
  gap: 10px;
  margin: 12px 0 4px;
  font-size: 1.05rem;
}

.video-time {
  font-size: 0.85rem;
  font-weight: 400;
  color: var(--text-muted);
}

.video figcaption p {
  margin: 0;
  color: var(--text-muted);
}

/* Linked video card: our own preview image, a plain link out. No iframe, no
   request to Google on page load — that distinction is what keeps the site
   consent-banner-free (see legal/de/datenschutz.md § 6.3). */

.video-link a {
  position: relative;
  display: block;
  border-radius: 8px;
  overflow: hidden;
  border: 1px solid var(--border);
  background: var(--bg-alt);
  text-decoration: none;
}

.video-link img {
  display: block;
  width: 100%;
  height: auto;
}

.video-play {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 64px;
  height: 64px;
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: rgb(27 26 23 / 72%);
  color: #fff;
  font-size: 24px;
  padding-left: 4px;
}

.video-out {
  position: absolute;
  right: 10px;
  bottom: 10px;
  padding: 4px 10px;
  border-radius: 999px;
  background: rgb(27 26 23 / 72%);
  color: #fff;
  font-size: 0.8rem;
}

/* Screenshot gallery. The images are the heaviest thing on the page, so they
   are lazy and carry explicit dimensions — otherwise the text below them jumps
   while they arrive. */

.shots {
  display: grid;
  gap: 30px;
  margin-top: 20px;
}

@media (min-width: 960px) {
  .shots {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

.shot {
  margin: 0;
}

.shot img {
  display: block;
  width: 100%;
  height: auto;
  border-radius: 8px;
  border: 1px solid var(--border);
  box-shadow: var(--shadow);
  background: var(--bg-alt);
}

.shot figcaption {
  margin-top: 10px;
  font-size: 0.92rem;
  line-height: 1.55;
  color: var(--text-muted);
}

/* "Wofür Beh.Stitched gemacht ist" — the short why-this list under the lead. */

.reasons {
  display: grid;
  gap: 22px 30px;
  margin-top: 18px;
}

@media (min-width: 720px) {
  .reasons {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media (min-width: 1100px) {
  .reasons {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
}

.reason h3 {
  margin: 0 0 6px;
  font-size: 1.02rem;
}

.reason p {
  margin: 0;
  color: var(--text-muted);
  line-height: 1.6;
}

/* "In Aktion" — each way through the program: steps on one side, the picture
   it produces on the other. Below 900 px they stack, picture under text. */

.hero-shot {
  margin: 0;
}

.hero-shot img,
.option-shot img {
  display: block;
  width: 100%;
  height: auto;
  border-radius: 8px;
  border: 1px solid var(--border);
  box-shadow: var(--shadow);
  background: var(--bg-alt);
}

/* Im dunklen Modus zeigen die Bilder ein dunkles Programm auf dunklem Grund —
   ohne kräftigeren Rahmen verliert man die Kante des Bildschirmfotos und weiß
   nicht mehr, wo die Aufnahme aufhört und die Seite anfängt. Der Schlagschatten
   allein trägt auf dunklem Grund nichts, er ist selbst dunkel. */
@media (prefers-color-scheme: dark) {
  .shot img,
  .option-shot img {
    border-color: var(--border-strong);
  }
}

.hero-shot figcaption,
.option-shot figcaption {
  margin-top: 10px;
  font-size: 0.9rem;
  line-height: 1.55;
  color: var(--text-muted);
}

.options {
  display: grid;
  gap: 44px;
  margin-top: 24px;
}

.option {
  display: grid;
  gap: 22px;
  align-items: start;
}

@media (min-width: 900px) {
  .option {
    grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
    gap: 34px;
  }
  /* Alternate the side the picture sits on, so a long list of steps does not
     read as one column of text with pictures bolted on. */
  .option:nth-child(even) .option-text {
    order: 2;
  }
}

.option-text h3 {
  margin: 0 0 10px;
  font-size: 1.1rem;
}

.option-text ol {
  margin: 0;
  padding-left: 20px;
  line-height: 1.65;
}

.option-text li {
  margin-bottom: 6px;
}

.option-shot {
  margin: 0;
}

/* Invitation to a live demonstration, just before the purchase block. */
.demo {
  border: 1px solid var(--border);
  border-left: 3px solid var(--accent);
  border-radius: 8px;
  padding: 22px 24px;
  background: var(--surface);
}

.demo h2 {
  margin-top: 0;
}

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

/* --------------------------------------------------- Gratis-Stickdateien -- */

/* Die vier Motive auf /gratis-stickdateien/. Je Karte links die Vorschau,
   rechts Name, Zahlen und die Format-Knöpfe. Die Vorschau steht daneben und
   nicht darüber: die Bilder sind knapp doppelt so hoch wie breit, obenauf
   drückten sie die Knöpfe auf dem Handy unter den ersten Bildschirm. */

/* Die Kacheln folgen dichter auf die Begrüßung als ein gewöhnlicher
   Abschnitt: Zwischen „Wir freuen uns über dein Feedback." und den Karten lag
   sonst fast eine Bildschirmviertelhöhe Leere (Christian, 26.08.). */
#motive {
  padding-top: 0.5rem;
}

.freebies {
  display: grid;
  gap: 1.25rem;
  margin: 1.5rem 0 0;
}

@media (min-width: 860px) {
  .freebies {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

.freebie {
  display: grid;
  grid-template-columns: 84px minmax(0, 1fr);
  gap: 1rem;
  align-items: start;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: 1.2rem;
}

@media (min-width: 480px) {
  .freebie {
    grid-template-columns: 112px minmax(0, 1fr);
    gap: 1.3rem;
  }
}

.freebie-shot {
  display: block;
  width: 100%;
  height: auto;
  border: 1px solid var(--border);
  border-radius: 8px;
}

/* Der Stoffgrund der Vorschau ist hell; auf dunklem Seitengrund verlöre das
   Bild sonst seine Kante — dieselbe Behandlung wie bei den Bildschirmfotos. */
@media (prefers-color-scheme: dark) {
  .freebie-shot {
    border-color: var(--border-strong);
  }
}

.freebie h3 {
  margin: 0 0 0.2rem;
  font-size: 1.1rem;
}

.freebie-tagline {
  margin: 0 0 0.4rem;
  color: var(--text-muted);
  font-size: 0.95rem;
  line-height: 1.5;
}

.freebie-facts {
  margin: 0 0 0.9rem;
  color: var(--text-muted);
  font-size: 0.9rem;
}

/* Die sechs Formate als festes Raster aus drei Spalten, nicht als umbrechende
   Reihe: In die Karte passen je nach Breite fünf oder vier Knöpfe, und der
   Rest stand dann allein in der zweiten Zeile. Zweimal drei liest sich als
   Liste, fünf plus einer als Versehen. */
.freebie-formats {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 0.45rem;
  max-width: 16rem;
  margin: 0 0 0.9rem;
  padding: 0;
  list-style: none;
}

/* Kleiner als ein gewöhnlicher Knopf und in der Schreibmaschinenschrift, damit
   DST, EXP und JEF gleich breit stehen. */
.freebie-formats .button {
  font-family: var(--font-mono);
  font-size: 0.85rem;
  letter-spacing: 0.02em;
  padding: 0.3rem 0.4rem;
  text-align: center;
}

.freebie-sheet {
  margin: 0;
  font-size: 0.92rem;
}
