/* ═══════════════════════════════════════════════════════════════════
   Grundlage — zugleich Entwurf A, „Werkstatt"

   Hier stehen alle Bausteine: Kopfleiste, Knoepfe, Auftakt, Kennzahlen,
   Katalog, Einbau, Support, Fuss. Entwurf A ist diese Datei allein;
   B und C laden sie ebenfalls und ueberschreiben in b.css bzw. c.css
   nur das, was sich unterscheidet.

   Wer hier etwas aendert, aendert es in allen drei Entwuerfen. Genau
   dafuer ist es so gebaut.

   Die Fortsetzung von dv_docs mit anderen Mitteln: hell, dicht,
   Haarlinien statt Schatten, keine Verläufe. Plex Mono trägt alles
   Strukturelle (Namen, Versionen, Beschriftungen), Plex Sans den Text,
   Plex Serif genau eine Stelle — den Einleitungssatz.

   Die Leitidee: Wer diese Scripts kauft, kauft die Sorgfalt. Also zeigt
   die Startseite Sorgfalt, statt sie zu behaupten. Kein Bild im Auftakt,
   sondern die server.cfg — der Beweis für „zwei Abhängigkeiten" ist der
   Beweis.
   ═══════════════════════════════════════════════════════════════════ */

/* ── Bausteine, die überall gleich aussehen ───────────────────────── */

.knopf{
  display:inline-flex;align-items:center;justify-content:center;gap:.5em;
  padding:.6rem 1.05rem;border-radius:var(--r-sm);border:1px solid transparent;
  font:500 var(--t-sm)/1 var(--sans);white-space:nowrap;cursor:pointer;
  transition:background-color .14s, border-color .14s, color .14s;
}
.knopf:hover{text-decoration:none}
.knopf-gross{padding:.8rem 1.4rem;font-size:.9375rem}

.knopf-primaer{background:var(--accent);color:var(--on-accent);border-color:var(--accent)}
.knopf-primaer:hover{background:var(--accent-ink);border-color:var(--accent-ink)}

.knopf-still{background:var(--surface);color:var(--ink);border-color:var(--line-ui)}
.knopf-still:hover{border-color:var(--ink-2);background:var(--surface)}

.eyebrow{
  display:flex;align-items:center;gap:.55rem;margin-bottom:var(--s-4);
  font:600 var(--t-micro)/1 var(--mono);letter-spacing:.13em;text-transform:uppercase;
  color:var(--ink-2);
}
.eyebrow .punkt{
  width:7px;height:7px;border-radius:50%;background:var(--c-amethyst);flex:none;
}

.abschnitt-h{
  font:600 var(--t-h2)/1.22 var(--sans);letter-spacing:-.018em;
  text-wrap:balance;margin-bottom:var(--s-3);
}
.abschnitt-p{
  max-width:58ch;color:var(--ink-2);font-size:var(--t-sm);line-height:1.65;
}

/* ── Kopfleiste ──────────────────────────────────────────────────── */
.site-head{
  position:sticky;top:0;z-index:50;
  background:var(--surface);border-bottom:1px solid var(--line);
}
.head-in{display:flex;align-items:center;gap:var(--s-5);min-height:60px}

.marke{color:var(--ink);flex:none}
.marke:hover{text-decoration:none}
.marke-t{font:600 1.0625rem/1 var(--mono);letter-spacing:-.03em}
.marke-t i{font-style:normal;color:var(--accent)}

.haupt-nav{display:flex;gap:var(--s-5);margin-right:auto}
.haupt-nav a{
  font:500 var(--t-sm)/1 var(--mono);color:var(--ink-2);
  padding:.5rem 0;border-bottom:2px solid transparent;
}
.haupt-nav a:hover{color:var(--ink);text-decoration:none;border-bottom-color:var(--line-2)}

.head-tools{display:flex;align-items:center;gap:var(--s-3)}

.ikon{
  display:grid;place-items:center;width:34px;height:34px;padding:0;
  background:transparent;border:1px solid var(--line-ui);border-radius:var(--r-sm);
  color:var(--ink-2);cursor:pointer;transition:border-color .14s,color .14s;
}
.ikon:hover{border-color:var(--ink-2);color:var(--ink)}
.ikon svg{grid-area:1/1}
.i-mond{display:none}
:root[data-theme="dark"] .i-sonne{display:none}
:root[data-theme="dark"] .i-mond{display:block}
@media (prefers-color-scheme:dark){
  :root:not([data-theme="light"]) .i-sonne{display:none}
  :root:not([data-theme="light"]) .i-mond{display:block}
}

.sprache{display:flex;border:1px solid var(--line-ui);border-radius:var(--r-sm);overflow:hidden}
.sprache a{
  display:grid;place-items:center;min-width:34px;min-height:32px;
  font:500 var(--t-micro)/1 var(--mono);letter-spacing:.06em;color:var(--ink-2);
}
.sprache a:hover{color:var(--ink);text-decoration:none;background:var(--surface-2)}
.sprache a.is-on{background:var(--accent-wash);color:var(--accent-ink)}

.burger{
  display:none;place-items:center;width:38px;height:38px;padding:0;margin-left:auto;
  background:transparent;border:1px solid var(--line-ui);border-radius:var(--r-sm);
  color:var(--ink);cursor:pointer;
}
.mobil-nav{
  display:flex;flex-direction:column;gap:var(--s-1);
  padding:var(--s-3) var(--pad) var(--s-5);border-top:1px solid var(--line);
}
.mobil-nav a{padding:.7rem .2rem;font:500 .9375rem/1 var(--mono);color:var(--ink-2)}
.mobil-nav .knopf{margin-top:var(--s-3);justify-content:center}

/* ── Auftakt ─────────────────────────────────────────────────────── */
.hero{border-bottom:1px solid var(--line);background:var(--surface)}
.hero-in{
  display:grid;grid-template-columns:minmax(0,1.05fr) minmax(0,.95fr);
  /* Zwei Zeilen rechts: Codekarte, darunter die Frameworks. Die
     Textspalte laeuft ueber beide - sonst beginnt die zweite Zeile
     erst unterhalb des laengeren Textes und es klafft eine Luecke. */
  grid-template-rows:auto auto;align-content:start;
  column-gap:clamp(2rem,5vw,4.5rem);row-gap:var(--s-4);align-items:start;
  padding-top:clamp(2.5rem,5vw,4.25rem);padding-bottom:clamp(2.5rem,5vw,4.25rem);
}
.hero-text{grid-column:1;grid-row:1/3}
.hero h1{
  /* Nicht --t-hero: die Ueberschrift steht in der halben Spaltenbreite,
     dort zerfaellt sie bei 68px in vier Zeilen. */
  font:700 clamp(1.9rem,1.35rem + 2.3vw,3.05rem)/1.12 var(--sans);
  letter-spacing:-.03em;text-wrap:balance;
}
.hero .lede{
  margin-top:var(--s-5);max-width:52ch;
  font:400 clamp(1.0625rem,.98rem + .4vw,1.1875rem)/1.6 var(--serif);
  color:var(--ink-2);
}
.hero .lede strong{font-weight:600;color:var(--ink)}
.hero .lede code{
  font-size:.78em;background:var(--surface-2);padding:.06em .28em;
  border-radius:4px;color:var(--ink);
}
.hero-tasten{display:flex;flex-wrap:wrap;gap:var(--s-3);margin-top:var(--s-6)}
.hero-fuss{
  margin-top:var(--s-5);padding-top:var(--s-4);border-top:1px solid var(--line);
  max-width:48ch;font-size:var(--t-xs);line-height:1.6;color:var(--ink-3);
}

/* Die server.cfg als Beweisstück. */
.hero-code{
  grid-column:2;grid-row:1;
  margin:0;background:var(--sunken);border:1px solid var(--line);border-radius:var(--r-lg);
  overflow:hidden;
}
.hero-code figcaption{
  display:flex;align-items:center;gap:.5rem;
  padding:.7rem 1rem;border-bottom:1px solid var(--line);background:var(--surface-2);
}
.hero-code .datei{
  font:500 var(--t-micro)/1 var(--mono);letter-spacing:.09em;text-transform:uppercase;
  color:var(--ink-3);
}
.hero-code figcaption::before{
  content:"";width:3px;height:13px;border-radius:2px;flex:none;
  background:var(--c-amethyst);
}
.hero-code pre{margin:0;padding:1.15rem 1.25rem;overflow-x:auto}
.hero-code code{font-size:.8125rem;line-height:1.75;color:var(--ink)}
.hero-code .c{color:var(--code-c);font-style:italic}
.hero-code .k{color:var(--code-k);font-weight:500}
.hero-code-note{
  padding:.9rem 1.25rem 1.1rem;border-top:1px solid var(--line);background:var(--surface);
  font-size:var(--t-xs);line-height:1.6;color:var(--ink-3);
}
.hero-code-note code{background:var(--surface-2);padding:.1em .35em;border-radius:4px}

/* ── Drei Versprechen ────────────────────────────────────────────── */
.versprechen{padding:clamp(3rem,6vw,4.5rem) 0;border-bottom:1px solid var(--line)}
.drei{
  display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:var(--s-3);
}
/* Alle drei Karten gleich gepolstert. Hier stand einmal eine
   Sonderregel fuer die erste Karte — Ueberbleibsel aus einem Entwurf,
   in dem die Spalten durch Haarlinien getrennt und links buendig mit
   dem Fliesstext standen. In der Kartenfassung sass der Inhalt der
   ersten Karte dadurch 1px vom Rand entfernt statt 25. */
.drei li{padding:var(--s-5)}
.drei h3{
  font:600 clamp(1.0625rem,1rem + .35vw,1.25rem)/1.3 var(--sans);
  letter-spacing:-.014em;margin-bottom:var(--s-3);
  display:flex;align-items:center;gap:.5rem;
}
.drei h3::before{
  content:"";width:6px;height:6px;border-radius:50%;background:var(--c-amethyst);flex:none;
}
.drei li:nth-child(2) h3::before{background:var(--c-azur)}
.drei li:nth-child(3) h3::before{background:var(--c-smaragd)}
.drei p{font-size:var(--t-sm);line-height:1.7;color:var(--ink-2)}
.drei code{background:var(--surface-2);padding:.1em .35em;border-radius:4px;color:var(--ink)}

/* ── Kennzahlen ──────────────────────────────────────────────────── */
.zahlen-band{padding:clamp(3rem,6vw,4.5rem) 0}
.zahlen{
  display:grid;grid-template-columns:repeat(auto-fit,minmax(150px,1fr));
  gap:1px;margin-top:var(--s-6);
  background:var(--line);border:1px solid var(--line);border-radius:var(--r);overflow:hidden;
}
.zahl{background:var(--surface);padding:var(--s-4) var(--s-5) var(--s-5)}
.zahl-n{
  font:600 clamp(1.5rem,1.2rem + 1vw,2rem)/1.1 var(--sans);letter-spacing:-.025em;
  font-variant-numeric:tabular-nums;color:var(--ink);
}
.zahl-l{margin:.4rem 0 0;font-size:var(--t-xs);color:var(--ink-3);line-height:1.4}

/* ── Katalog ─────────────────────────────────────────────────────── */
.katalog{padding:clamp(3rem,6vw,4.5rem) 0;border-top:1px solid var(--line);background:var(--surface)}
.katalog-kopf{
  display:flex;flex-wrap:wrap;align-items:flex-end;justify-content:space-between;
  gap:var(--s-5);margin-bottom:var(--s-6);
}
.suche input{
  width:min(320px,100%);padding:.62rem .85rem;
  border:1px solid var(--line-ui);border-radius:var(--r-sm);
  background:var(--sunken);color:var(--ink);font:400 var(--t-sm) var(--sans);
}
.suche input::placeholder{color:var(--ink-3)}
.suche input:focus{outline:none;border-color:var(--accent);background:var(--surface)}
.suche input:focus-visible{outline:2px solid var(--accent);outline-offset:1px}

/* Bleibt beim Blaettern durch 33 Karten stehen - sonst muss man zum
   Filtern jedes Mal nach oben. 60px ist die Hoehe der Kopfleiste. */
.filter{
  display:flex;flex-wrap:wrap;gap:var(--s-2);margin-bottom:var(--s-6);
  position:sticky;top:60px;z-index:20;
  padding:var(--s-3) 0;margin-top:calc(var(--s-3) * -1);
  background:var(--surface);border-bottom:1px solid var(--line);
}
.chip{
  display:inline-flex;align-items:center;gap:.45rem;
  /* 32px hoch - ueber dem Mindestmass von 24x24 fuer Zielflaechen. */
  padding:.5rem .8rem;border-radius:var(--r-pill);cursor:pointer;
  background:transparent;border:1px solid var(--line-ui);color:var(--ink-2);
  font:500 var(--t-xs)/1 var(--sans);
  transition:border-color .14s,color .14s,background-color .14s;
}
.chip:hover{border-color:var(--gc-ink,var(--ink-2));color:var(--ink)}
.chip.is-on{
  border-color:var(--gc-ink,var(--accent-ink));
  color:var(--gc-ink,var(--accent-ink));
  background:var(--surface);
  box-shadow:inset 0 0 0 1px var(--gc-ink,var(--accent-ink));
}
.chip-n{
  font:500 var(--t-micro)/1 var(--mono);color:var(--ink-3);
  padding-left:.45rem;border-left:1px solid var(--line-ui);
}
.chip.is-on .chip-n{color:inherit;opacity:.75;border-left-color:currentColor}

.groups{display:flex;flex-direction:column;gap:clamp(2rem,4vw,3rem)}
.grp{border-top:2px solid var(--gc);padding-top:var(--s-4)}
.grp[hidden]{display:none}
.grp-name{
  display:flex;align-items:center;gap:.6rem;
  font:600 1.0625rem/1.2 var(--sans);letter-spacing:-.012em;
}
.grp-count{
  font:600 var(--t-micro)/1 var(--mono);padding:.25rem .45rem;border-radius:var(--r-pill);
  background:var(--surface-2);color:var(--ink-3);
}
.grp-desc{margin-top:.3rem;font-size:var(--t-xs);color:var(--ink-3)}

/* ── Die Sammlung: eine Zeile je Ressource ────────────────────────
   Zugeklappt Name, Kurztext und Fassung in einer Zeile; aufgeklappt
   die Angaben und der Weg in den Shop. Alles steht im Markup — ohne
   JavaScript liegt es offen da statt zu fehlen. */
.liste{display:flex;flex-direction:column;margin-top:var(--s-4)}
.cell{border-bottom:1px solid var(--line)}
.cell:first-child{border-top:1px solid var(--line)}
.cell[hidden]{display:none}

.eintrag-h{margin:0;font:inherit}
.eintrag-schalter{
  display:grid;grid-template-columns:15rem minmax(0,1fr) auto auto;
  align-items:baseline;gap:var(--s-4);width:100%;
  padding:.85rem .75rem;border:0;border-radius:var(--r-sm);
  background:transparent;text-align:left;cursor:pointer;
  transition:background-color .16s;
}
.eintrag-schalter:hover{background:var(--surface)}
.eintrag-name{
  font:600 .9375rem/1.35 var(--mono);letter-spacing:-.015em;color:var(--gc-ink);
}
.eintrag-kurz{font-size:var(--t-xs);line-height:1.5;color:var(--ink-2)}
.eintrag-ver{
  font:400 var(--t-micro)/1 var(--mono);color:var(--ink-3);
  padding:.22rem .4rem;border:1px solid var(--line);border-radius:4px;
}
.eintrag-pfeil{
  display:grid;place-items:center;width:20px;height:20px;color:var(--ink-3);
  transition:transform .24s, color .16s;
}
.eintrag-schalter:hover .eintrag-pfeil{color:var(--ink)}
.eintrag-schalter[aria-expanded="true"] .eintrag-pfeil{transform:rotate(180deg);color:var(--gc-ink)}
.eintrag-schalter[aria-expanded="true"] .eintrag-kurz{color:var(--ink-3)}

/* Aufklappen ohne gemessene Höhen: 0fr auf 1fr lässt sich animieren,
   und visibility nimmt das Verborgene aus Tastaturweg und
   Vorlesereihenfolge — anders als ein blosses overflow:hidden.

   Das Zuklappen hängt an `.js`: ohne JavaScript gäbe es niemanden, der
   wieder aufklappt, und die halbe Sammlung wäre unerreichbar. Dann
   liegt sie eben offen da. */
.eintrag-mehr{display:grid;grid-template-rows:1fr}
.js .eintrag-mehr{
  grid-template-rows:0fr;visibility:hidden;
  transition:grid-template-rows .3s ease, visibility 0s .3s;
}
.js .eintrag-mehr.auf{
  grid-template-rows:1fr;visibility:visible;
  transition:grid-template-rows .3s ease, visibility 0s;
}
/* Ohne JavaScript ist der Schalter kein Schalter. */
html:not(.js) .eintrag-pfeil{display:none}
html:not(.js) .eintrag-schalter{cursor:default}
.eintrag-mehr>div{overflow:hidden;min-height:0}
.eintrag-mehr-in{
  padding:0 .75rem var(--s-5) 15.75rem;
  display:flex;flex-direction:column;align-items:flex-start;gap:var(--s-4);
}
.eintrag-text{font-size:var(--t-sm);line-height:1.65;color:var(--ink-2);max-width:68ch}
.eintrag-fakten{
  display:grid;grid-template-columns:repeat(auto-fit,minmax(190px,1fr));
  gap:var(--s-3) var(--s-5);width:100%;
}
.eintrag-fakten dt{
  font:600 var(--t-micro)/1 var(--mono);letter-spacing:.1em;text-transform:uppercase;
  color:var(--ink-3);margin-bottom:.35rem;
}
.eintrag-fakten dd{margin:0;font-size:var(--t-xs);line-height:1.6;color:var(--ink)}
.eintrag-fakten code{
  background:var(--surface-2);padding:.1em .35em;border-radius:4px;
  font-size:.95em;color:var(--ink-2);
}
.eintrag-fakten .dim{color:var(--ink-3)}
.knopf-klein{padding:.5rem .9rem;font-size:var(--t-xs)}

.filter-leer{
  padding:var(--s-7) 0;text-align:center;color:var(--ink-2);font-size:var(--t-sm);
}
.filter-leer b{display:block;margin-bottom:.35rem;color:var(--ink);font-weight:600}

/* ── Einbau ──────────────────────────────────────────────────────── */
.einbau{padding:clamp(3rem,6vw,4.5rem) 0;border-top:1px solid var(--line)}
.einbau-in{
  display:grid;grid-template-columns:minmax(0,1.35fr) minmax(0,1fr);
  gap:clamp(2rem,5vw,4rem);align-items:start;
}
.schritte{counter-reset:s;margin-top:var(--s-5);display:flex;flex-direction:column;gap:var(--s-5)}
/* Ziffer links, Titel und Text rechts. Die Ziffer muss ueber beide
   Zeilen gehen - sonst rutscht der Absatz unter die Ziffer statt neben sie. */
.schritte li{
  counter-increment:s;
  display:grid;grid-template-columns:auto minmax(0,1fr);
  column-gap:var(--s-4);align-items:baseline;
}
.schritte li::before{
  content:counter(s,decimal-leading-zero);grid-row:1/3;
  font:500 var(--t-xs)/1.5 var(--mono);color:var(--accent-ink);
}
.schritte h3{grid-column:2;font:600 var(--t-h3)/1.35 var(--sans);margin-bottom:.3rem}
.schritte p{grid-column:2;font-size:var(--t-sm);line-height:1.62;color:var(--ink-2)}
.schritte code,.einbau-kasten code{
  background:var(--surface-2);padding:.1em .35em;border-radius:4px;color:var(--ink);
}

.einbau-kasten{
  padding:var(--s-5);background:var(--surface);
  border:1px solid var(--line);border-left:3px solid var(--c-bernstein);
  border-radius:0 var(--r) var(--r) 0;
}
.einbau-kasten h3{font:600 var(--t-h3)/1.3 var(--sans);margin-bottom:var(--s-3)}
.einbau-kasten p{font-size:var(--t-sm);line-height:1.6;color:var(--ink-2)}
.dateiliste{margin:var(--s-4) 0;display:flex;flex-direction:column;gap:.5rem}
.dateiliste li{
  display:flex;flex-wrap:wrap;align-items:baseline;gap:.5rem;
  padding-bottom:.5rem;border-bottom:1px solid var(--line);
}
.dateiliste li:last-child{border-bottom:0;padding-bottom:0}
.dateiliste code{font-size:var(--t-xs);font-weight:500}
.dateiliste span{font-size:var(--t-xs);color:var(--ink-3)}
.klein{font-size:var(--t-xs);color:var(--ink-3);line-height:1.55}

/* ── Support ─────────────────────────────────────────────────────── */
.support{
  padding:clamp(3rem,6vw,4.5rem) 0;
  border-top:1px solid var(--line);background:var(--surface);
}
.support-in{
  display:grid;grid-template-columns:minmax(0,1.3fr) minmax(0,1fr);
  gap:clamp(2rem,5vw,4rem);align-items:start;
}
.support .hero-tasten{margin-top:var(--s-5)}
.support-fakten{
  display:grid;gap:1px;background:var(--line);
  border:1px solid var(--line);border-radius:var(--r);overflow:hidden;
}
.support-fakten>div{background:var(--surface);padding:.85rem 1.1rem}
.support-fakten dt{
  font:600 var(--t-micro)/1 var(--mono);letter-spacing:.1em;text-transform:uppercase;
  color:var(--ink-3);margin-bottom:.35rem;
}
.support-fakten dd{margin:0;font-size:var(--t-sm);color:var(--ink)}

/* ── Fuß ─────────────────────────────────────────────────────────── */
.site-foot{border-top:1px solid var(--line);padding-top:clamp(2.5rem,5vw,3.5rem)}
.foot-in{
  display:grid;grid-template-columns:minmax(0,1.6fr) repeat(3,minmax(0,1fr));
  gap:var(--s-6) var(--s-5);padding-bottom:var(--s-7);
}
.foot-marke p{margin-top:.6rem;font-size:var(--t-xs);color:var(--ink-3);max-width:28ch}
.site-foot nav{display:flex;flex-direction:column;align-items:flex-start}
.site-foot h2{
  font:600 var(--t-micro)/1 var(--mono);letter-spacing:.11em;text-transform:uppercase;
  color:var(--ink-3);margin-bottom:.35rem;
}
/* Zielflaeche 24px hoch statt der 20px, die die Zeile allein ergibt. */
.site-foot nav a{font-size:var(--t-sm);color:var(--ink-2);padding:.28rem 0;display:block}
.site-foot nav a:hover{color:var(--ink)}
.foot-unten{
  display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;
  gap:var(--s-3);padding-block:var(--s-4);border-top:1px solid var(--line);
  font-size:var(--t-xs);color:var(--ink-3);
}
.foot-lang a{color:var(--ink-2);padding:.28rem 0;display:inline-block}

/* ── Umbrüche ────────────────────────────────────────────────────── */
@media (max-width:1080px){
  .hero-in{grid-template-columns:minmax(0,1fr);gap:var(--s-6)}
  .hero-code{max-width:560px}
  .einbau-in,.support-in{grid-template-columns:minmax(0,1fr)}
  .foot-in{grid-template-columns:repeat(2,minmax(0,1fr))}
}
@media (max-width:860px){
  .haupt-nav,.head-tools{display:none}
  .burger{display:grid}
  /* Untereinander bleiben es Karten — die Trennlinien-Variante stammt
     aus einem verworfenen Entwurf. */
  .drei{grid-template-columns:minmax(0,1fr)}
  .katalog-kopf{align-items:flex-start}
  .suche input{width:100%}
}
@media (max-width:560px){
  .foot-in{grid-template-columns:minmax(0,1fr);gap:var(--s-5)}
  .hero-tasten .knopf{flex:1 1 100%}
  .grid{grid-template-columns:minmax(0,1fr)}
}

/* Die mobile Navigation gehoert ausschliesslich unter 860px. Ohne diese
   Regel bliebe sie nach einem Wechsel von schmal zu breit offen stehen. */
@media (min-width:861px){ .mobil-nav{display:none!important} }

/* Die Kompatibilitaetszeile schliesst den Auftakt rechts ab. Ohne sie
   endet die Spalte auf halber Hoehe und der Rest bleibt leer. */
.kompat{
  grid-column:2;grid-row:2;align-self:start;
  display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:1px;
  background:var(--line);border:1px solid var(--line);border-radius:var(--r);
  overflow:hidden;
}
.kompat li{background:var(--surface);padding:.7rem .9rem}
.kompat-n{
  display:block;font:600 var(--t-xs)/1.2 var(--mono);color:var(--ink);
}
.kompat-s{display:block;margin-top:.2rem;font-size:var(--t-micro);color:var(--ink-3)}
@media (max-width:1080px){
  .hero-text{grid-column:1;grid-row:auto}
  .hero-code{grid-column:1;grid-row:auto}
  .kompat{grid-column:1;grid-row:auto;max-width:560px;margin-top:0}
}
@media (max-width:420px){
  .kompat{grid-template-columns:minmax(0,1fr)}
}

/* ── „Sehen, was die Scripts können" ──────────────────────────────
   Links die Auswahl, rechts die Aufnahme. Der Abschnitt trägt die
   Hauptlast der Seite: hier entscheidet sich, ob jemand versteht, was
   er kauft. */
.koennen{padding:clamp(3rem,7vw,5.5rem) 0;border-top:1px solid var(--line)}
.koennen-kopf{margin-bottom:var(--s-6);max-width:62ch}
.koennen-raster{
  display:grid;grid-template-columns:minmax(0,19rem) minmax(0,1fr);
  gap:clamp(1.5rem,3vw,2.5rem);align-items:start;
}

.koennen-wahl{display:flex;flex-direction:column;gap:.35rem}
.wahl{
  display:block;width:100%;text-align:left;cursor:pointer;
  padding:.8rem .95rem;border-radius:var(--r);
  background:transparent;border:1px solid transparent;
  transition:background-color .18s, border-color .18s, transform .18s;
}
.wahl:hover{background:var(--surface);border-color:var(--line)}
.wahl-name{
  display:block;font:600 .875rem/1.3 var(--mono);letter-spacing:-.015em;
  color:var(--ink-2);
}
.wahl-kurz{
  display:block;margin-top:.25rem;font-size:var(--t-xs);line-height:1.45;
  color:var(--ink-3);
}
.wahl.is-on{
  background:var(--surface);border-color:var(--gc);
  box-shadow:inset 3px 0 0 var(--gc);
}
.wahl.is-on .wahl-name{color:var(--gc-ink)}
.wahl.is-on .wahl-kurz{color:var(--ink-2)}

.tafel[hidden]{display:none}
.medien{
  aspect-ratio:16/9;border-radius:var(--r-lg);overflow:hidden;
  border:1px solid var(--line);background:var(--sunken);
  position:relative;
}
.medien video,.medien img{width:100%;height:100%;object-fit:cover;display:block}

/* Solange keine Aufnahme vorliegt, sagt der Platz, was hierher gehört
   und wie die Datei heißen soll. Kein graues Rechteck, das man für
   einen Fehler halten kann. */
.medien-platz{
  position:absolute;inset:0;overflow:hidden;
  display:flex;flex-direction:column;align-items:center;justify-content:center;
  gap:.6rem;padding:var(--s-5);text-align:center;
  background:
    repeating-linear-gradient(-45deg,
      transparent 0 11px,
      color-mix(in oklab, var(--gc) 5%, transparent) 11px 22px);
}
.medien-marke{
  padding:.25rem .6rem;border-radius:var(--r-pill);
  /* Nicht #fff: im Dunkelmodus ist --gc-ink die helle Fassung der
     Kategoriefarbe, weiße Schrift darauf läge bei 2:1. --bg ist in
     beiden Fassungen der Gegenpol und trägt. */
  background:var(--gc-ink);color:var(--bg);
  font:600 var(--t-micro)/1 var(--mono);letter-spacing:.11em;text-transform:uppercase;
}
.medien-text{font-size:var(--t-sm);color:var(--ink-2)}
.medien-text b{color:var(--ink);font-family:var(--mono);font-weight:600;font-size:.95em}
.medien-datei{
  font:400 var(--t-micro)/1.5 var(--mono);color:var(--ink-3);
  padding:.3rem .55rem;border-radius:var(--r-sm);
  background:var(--surface);border:1px solid var(--line);
}
.tafel-text{
  margin-top:var(--s-4);max-width:70ch;
  font-size:var(--t-sm);line-height:1.7;color:var(--ink-2);
}

@media (max-width:900px){
  .koennen-raster{grid-template-columns:minmax(0,1fr)}
  /* Aus der Liste wird eine Leiste, die quer läuft. */
  .koennen-wahl{
    flex-direction:row;gap:.5rem;overflow-x:auto;
    padding-bottom:.5rem;scroll-snap-type:x mandatory;
  }
  .wahl{flex:0 0 auto;width:auto;min-width:13.5rem;scroll-snap-align:start}
}

/* Auf schmalen Fenstern trägt die Zeile ihre feste 15rem-Spalte nicht
   mehr — Name, Fassung und Pfeil in die erste Zeile, der Kurztext
   darunter. */
@media (max-width:760px){
  .eintrag-schalter{
    grid-template-columns:minmax(0,1fr) auto auto;
    grid-template-areas:"name ver pfeil" "kurz kurz kurz";
    column-gap:var(--s-3);row-gap:.3rem;
    padding:.8rem .6rem;
  }
  .eintrag-name{grid-area:name}
  .eintrag-ver{grid-area:ver}
  .eintrag-pfeil{grid-area:pfeil;align-self:center}
  .eintrag-kurz{grid-area:kurz}
  /* Der Einzug richtete sich an der Namensspalte aus, die es hier
     nicht mehr gibt. */
  .eintrag-mehr-in{padding-left:.6rem;padding-right:.6rem}
  .eintrag-fakten{grid-template-columns:minmax(0,1fr);gap:var(--s-3)}
}

/* ── Der laufende Lua-Code im Auftakt ─────────────────────────────
   Drei Schnipsel liegen übereinander in einer Rasterzelle. So gibt der
   längste die Höhe vor und nichts springt, wenn gewechselt wird. */
.code-stapel{display:grid;grid-template-columns:minmax(0,1fr)}
.schnipsel{
  /* min-width:0 ist Pflicht: Rasterelemente stehen von Haus aus auf
     min-width:auto und wachsen mit ihrem Inhalt — eine lange Codezeile
     schöbe dann die ganze Seite auseinander, statt im Block zu
     scrollen. */
  grid-area:1/1;min-width:0;margin:0;padding:1.15rem 1.25rem 1.15rem 0;
  overflow-x:auto;counter-reset:z;
  transition:opacity .3s ease;
}
.schnipsel code{font-size:.8125rem;line-height:1.75;color:var(--ink)}

/* Zeilennummern aus einem Zähler — sie stehen nicht im Markup und
   verschieben sich deshalb nicht, wenn jemand eine Zeile einfügt. */
.zeile{
  display:block;position:relative;padding-left:3.4rem;counter-increment:z;
}
.zeile::before{
  content:counter(z);
  position:absolute;left:0;width:2.4rem;text-align:right;
  color:var(--ink-3);opacity:.55;font-variant-numeric:tabular-nums;
  user-select:none;
}

.schnipsel .c{color:var(--code-c);font-style:italic}
.schnipsel .s{color:var(--code-s)}
.schnipsel .k{color:var(--code-k);font-weight:500}
.schnipsel .n{color:var(--code-n)}
.schnipsel .g{color:var(--code-g);font-weight:500}
.schnipsel .b{color:var(--code-b)}

/* Anhalten. Pflicht, sobald etwas länger als fünf Sekunden von selbst
   läuft — WCAG 2.2.2. */
.code-halt{
  display:grid;place-items:center;width:26px;height:26px;padding:0;
  margin-left:auto;cursor:pointer;
  background:transparent;border:1px solid var(--line);border-radius:5px;
  color:var(--ink-3);transition:color .15s, border-color .15s;
}
.code-halt:hover{color:var(--ink);border-color:var(--line-ui)}
.code-halt svg{grid-area:1/1}
.code-halt .i-weiter{display:none}
.code-halt[aria-pressed="true"] .i-halt{display:none}
.code-halt[aria-pressed="true"] .i-weiter{display:block}

/* Bei reduzierter Bewegung wird nicht gewechselt — dann stehen alle
   drei untereinander, jeder mit seinem Dateinamen. */
.code-stapel.stapel-ruhig{display:block}
.code-stapel.stapel-ruhig .schnipsel{padding-top:.5rem}
.schnipsel-datei{
  display:block;padding:.9rem 1.25rem .2rem;
  font:500 var(--t-micro)/1 var(--mono);letter-spacing:.09em;
  text-transform:uppercase;color:var(--ink-3);
}
.code-stapel.stapel-ruhig .schnipsel-datei:first-child{padding-top:.2rem}

/* Die server.cfg steht jetzt beim Einbau, wo sie hingehört.

   grid-column:2 ist keine Kosmetik: die Schritte sind ein Raster aus
   Ziffernspalte und Textspalte. Ohne die Angabe fiele die Figur in die
   schmale Ziffernspalte, würde sie auf ihre Breite aufziehen und die
   ganze Seite mitnehmen. */
.schritte .cfg{grid-column:2}
.cfg{
  margin:var(--s-4) 0 0;background:var(--sunken);
  border:1px solid var(--line);border-radius:var(--r);overflow:hidden;
}
.cfg figcaption{
  padding:.6rem .9rem;border-bottom:1px solid var(--line);
  font:500 var(--t-micro)/1 var(--mono);letter-spacing:.09em;
  text-transform:uppercase;color:var(--ink-3);
}
.cfg pre{margin:0;padding:.9rem 1rem;overflow-x:auto}
.cfg code{font-size:.78rem;line-height:1.7;color:var(--ink)}
.cfg .c{color:var(--code-c);font-style:italic}
.cfg .k{color:var(--code-k);font-weight:500}

/* Der Reiter über dem Code nennt eine echte Datei — Dateinamen sind
   klein geschrieben, also bleiben sie es auch hier. */
.hero-code .datei{text-transform:none;letter-spacing:.02em;font-size:var(--t-xs)}

/* ── Die Kulisse hinter dem Auftakt ───────────────────────────────
   Drei Spalten echter Lua-Code, sehr leise gestellt, langsam nach oben
   laufend. Sie liegt unter dem Lichtschein und weit unter dem Text.

   Sie ist Zier und nichts sonst: aria-hidden im Markup, keine
   Zeigerereignisse, und der Text darüber steht auf --bg, nicht auf
   ihr — die Lesbarkeit hängt an keiner Stelle von ihr ab. */
.code-regen{
  position:absolute;inset:0;z-index:0;
  /* Absichtlich ungleiche Spaltenbreiten. Drei gleich breite Spalten
     mit gleicher Deckkraft lesen sich als Raster; ungleiche Breiten,
     Helligkeiten und Geschwindigkeiten ergeben Tiefe. */
  display:grid;grid-template-columns:1.15fr .78fr 1.07fr;
  gap:clamp(1.5rem,4vw,3.5rem);
  padding-inline:clamp(1rem,3vw,3rem);
  overflow:hidden;pointer-events:none;user-select:none;
  color:var(--ink);
  /* Oben unter der Kopfleiste einsetzen, unten auslaufen — sonst
     stößt der Code hart an die nächste Trennlinie. */
  -webkit-mask-image:linear-gradient(to bottom,transparent 0,#000 16%,#000 58%,transparent 96%);
          mask-image:linear-gradient(to bottom,transparent 0,#000 16%,#000 58%,transparent 96%);
}
/* Hinter Überschrift und Lede wird die Kulisse auf Hintergrundfarbe
   zurückgenommen. Sie läuft weiterhin über die ganze Breite — sie ist
   nur dort still, wo gelesen wird. Ein Schleier statt einer Maske:
   mask-composite braucht zwei Schreibweisen und fällt dort, wo es sie
   nicht gibt, auf „beide Masken addieren" zurück — also auf mehr
   Kulisse statt weniger. */
.code-regen::after{
  content:"";position:absolute;inset:0;pointer-events:none;
  background:radial-gradient(60% 46% at 50% 40%,
    var(--bg) 0%, var(--bg) 28%,
    color-mix(in oklab, var(--bg) 55%, transparent) 52%,
    transparent 76%);
}
.regen-spalte{overflow:hidden}
.code-regen pre{
  margin:0;white-space:pre;
  /* Nicht unter 12px: die Kulisse besteht aus knapp 400 Zeilen, und
     Prüfwerkzeuge zählen sie als Seitentext mit. Bei 10,5px sank der
     gemessene Anteil „lesbarer Text" auf 3 Prozent — obwohl kein Wort
     davon gelesen werden soll. 12px kosten nichts. */
  font:400 12px/2.05 var(--mono);
  letter-spacing:.01em;
  opacity:.075;
}
/* Jede Spalte anders hell und anders hoch angesetzt — so trifft keine
   Zeile der einen auf eine Zeile der anderen. */
.regen-spalte:nth-child(2) pre{opacity:.045;font-size:12px;line-height:2.3}
.regen-spalte:nth-child(3) pre{opacity:.06;font-size:12.5px;line-height:1.95}
.regen-spalte:nth-child(2){padding-top:2.1rem}
.regen-spalte:nth-child(3){padding-top:.9rem}
/* Im Hellmodus trägt dieselbe Deckkraft weiter — dunkle Schrift auf
   hellem Grund wirkt bei gleicher Deckkraft kräftiger. */
:root[data-theme="light"] .code-regen pre{opacity:.055}
@media (prefers-color-scheme:light){
  :root:not([data-theme="dark"]) .code-regen pre{opacity:.055}
}

/* Der Auftakt muss über der Kulisse liegen. */
.hero-in{position:relative;z-index:2}
.glanz{z-index:1}

@media (max-width:1100px){
  .code-regen{grid-template-columns:1.1fr .85fr}
  .regen-spalte:nth-child(3){display:none}
}
@media (max-width:700px){
  .code-regen{grid-template-columns:minmax(0,1fr)}
  .regen-spalte:nth-child(2){display:none}
  .code-regen pre{font-size:12px}
  /* Auf dem Telefon steht der Text über die ganze Breite — der
     Schleier muss entsprechend breiter greifen. */
  .code-regen::after{
    background:radial-gradient(125% 52% at 50% 36%,
      var(--bg) 0%, var(--bg) 44%,
      color-mix(in oklab, var(--bg) 60%, transparent) 66%,
      transparent 88%);
  }
}

/* Dritter Knopf im Auftakt: weder Werbung noch Nebensache. Nur Text
   mit Unterstreichung bei Beruehrung — er soll die beiden anderen
   nicht schwaechen. */
.knopf-schlicht{
  background:transparent;border-color:transparent;color:var(--ink-2);
  padding-inline:.6rem;
}
.knopf-schlicht:hover{
  color:var(--ink);text-decoration:underline;text-underline-offset:3px;
}

/* Kauf und Handbuch nebeneinander unter jedem aufgeklappten Eintrag. */
.eintrag-wege{display:flex;flex-wrap:wrap;align-items:center;gap:var(--s-2)}

/* ── Die Discord-Einladung im Auftakt ─────────────────────────────
   Kein vierter Knopf, sondern eine eigene Form: abgerundete Pille mit
   der Discord-Marke. So faellt sie auf, ohne mit den Kaufknoepfen um
   dieselbe Aufmerksamkeit zu ringen. */
.hero-discord{margin-top:var(--s-5)}
.hero-discord a{
  display:inline-flex;align-items:center;gap:.6rem;
  padding:.55rem 1rem .55rem .85rem;border-radius:var(--r-pill);
  border:1px solid var(--line-2);background:var(--surface);
  color:var(--ink-2);font-size:var(--t-sm);line-height:1.3;
  transition:border-color .16s, color .16s, background-color .16s;
}
.hero-discord a:hover{
  text-decoration:none;color:var(--ink);
  border-color:var(--accent);
  background:color-mix(in oklab, var(--accent) 10%, var(--surface));
}
.hero-discord b{color:var(--ink);font-weight:600}
.discord-mark{flex:none;color:var(--accent)}
.hero-discord a:hover .discord-mark{color:var(--accent-ink)}

@media (max-width:520px){
  .hero-discord a{
    /* Auf schmalen Fenstern soll die Pille nicht umbrechen. */
    padding:.5rem .8rem;gap:.5rem;font-size:var(--t-xs);
  }
  .hero-discord-t{text-align:left}
}
