/* ══════════════════════════════════════════════════════════════════════
   Storefront des LaStore.

   Die Werte stammen 1:1 aus Neue Webseite/website/assets/css/site.css —
   der Shop ist eigenständig, aber er ist dieselbe Marke. Abweichungen sind
   in design-system/lets-automate/pages/shop.md begründet und stehen nicht
   hier.

   Aeonik wird lokal ausgeliefert, wie auf www.letsautomate.ch. Als OTF und
   nicht als WOFF2, weil es die Dateien so gibt — WOFF2 wäre ein Drittel der
   Grösse und steht auf der Liste. Die Webfont-Lizenz ist ebenfalls offen;
   solange nur der Entwicklungsserver sie ausliefert, ist das folgenlos.
   ══════════════════════════════════════════════════════════════════════ */

@font-face { font-family:"Aeonik"; src:url("/fonts/Aeonik-Regular.otf") format("opentype"); font-weight:400; font-style:normal; font-display:swap; }
@font-face { font-family:"Aeonik"; src:url("/fonts/Aeonik-Medium.otf")  format("opentype"); font-weight:500; font-style:normal; font-display:swap; }
@font-face { font-family:"Aeonik"; src:url("/fonts/Aeonik-Bold.otf")    format("opentype"); font-weight:700; font-style:normal; font-display:swap; }

:root {
  --navy:#12316F; --navy-600:#1B4093; --navy-900:#0C1F47;
  --lime:#A1CA3B; --lime-600:#8CB32C; --lime-ink:#5A7A19; --lime-200:#DDECB4;
  --ink:#141414;
  --bg:#FFFFFF; --bg-soft:#F4F6FB; --bg-tint:#F5F9EC;
  --surface:#FFFFFF; --surface-2:#F8FAFD;
  --text:#141414; --text-strong:#0C1F47; --text-muted:#55606F;
  --border:#E3E8F1; --border-strong:#CBD4E3;
  --shadow-sm:0 1px 2px rgba(12,31,71,.06),0 2px 6px rgba(12,31,71,.05);
  --shadow-md:0 2px 4px rgba(12,31,71,.05),0 12px 28px -8px rgba(12,31,71,.14);
  --shadow-lg:0 4px 8px rgba(12,31,71,.05),0 32px 64px -24px rgba(12,31,71,.22);
  --on-navy:#EEF2FA; --on-navy-muted:#A9B8D6;
  --sp-1:.25rem; --sp-2:.5rem; --sp-3:.75rem; --sp-4:1rem; --sp-5:1.5rem;
  --sp-6:2rem; --sp-7:3rem; --sp-8:4rem;
  --gutter:clamp(1.25rem,4vw,2.5rem);
  --container:1200px;
  --r-sm:10px; --r-md:14px; --r-lg:20px; --r-xl:28px; --r-pill:999px;
  --t-fast:140ms; --t:220ms; --t-slow:380ms;
  --ease:cubic-bezier(.22,.61,.36,1);
  --section-y:clamp(3rem,5vw,4.5rem);
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --bg:#0B1122; --bg-soft:#0F172C; --bg-tint:#111C2C;
    --surface:#131D34; --surface-2:#182444;
    --text:#E9EEF7; --text-strong:#FFFFFF; --text-muted:#9DAAC2;
    --border:#233250; --border-strong:#31456B;
    --shadow-sm:0 1px 2px rgba(0,0,0,.3),0 2px 8px rgba(0,0,0,.28);
    --shadow-md:0 2px 6px rgba(0,0,0,.34),0 14px 32px -10px rgba(0,0,0,.6);
    --shadow-lg:0 6px 12px rgba(0,0,0,.4),0 36px 72px -28px rgba(0,0,0,.8);
  }
}
:root[data-theme="dark"] {
  --bg:#0B1122; --bg-soft:#0F172C; --bg-tint:#111C2C;
  --surface:#131D34; --surface-2:#182444;
  --text:#E9EEF7; --text-strong:#FFFFFF; --text-muted:#9DAAC2;
  --border:#233250; --border-strong:#31456B;
  --shadow-sm:0 1px 2px rgba(0,0,0,.3),0 2px 8px rgba(0,0,0,.28);
  --shadow-md:0 2px 6px rgba(0,0,0,.34),0 14px 32px -10px rgba(0,0,0,.6);
  --shadow-lg:0 6px 12px rgba(0,0,0,.4),0 36px 72px -28px rgba(0,0,0,.8);
}

* { box-sizing: border-box; }
body {
  margin:0; background:var(--bg); color:var(--text);
  font-family:"Aeonik","Inter",system-ui,-apple-system,"Segoe UI",sans-serif;
  font-size:17px; line-height:1.65; -webkit-font-smoothing:antialiased;
}
.container { max-width:var(--container); margin-inline:auto; padding-inline:var(--gutter); }
h1,h2,h3 { color:var(--text-strong); margin:0; text-wrap:balance; }
h1 { font-size:clamp(2.35rem,1.5rem + 3.1vw,3.7rem); font-weight:700; line-height:1.04; letter-spacing:-.035em; }
h2 { font-size:clamp(1.85rem,1.35rem + 1.9vw,2.6rem); font-weight:700; line-height:1.1; letter-spacing:-.03em; }
h3 { font-size:clamp(1.2rem,1.1rem + .5vw,1.45rem); font-weight:700; line-height:1.3; }
p { margin:0; }
/* Linkfarbe je Modus - ABER vollständig in :where() gekapselt, damit die
   Spezifität null ist. Ohne das gewann die Modusregel gegen .btn--primary
   und setzte lime auf den Lime-Knopf: gemessene 1.00:1, der Text war
   unsichtbar. Komponentenfarben müssen immer stärker sein als Modusregeln. */
:where(a) { color:var(--navy); }
:where(:root[data-theme="dark"] a) { color:var(--lime); }
@media (prefers-color-scheme: dark) {
  :where(:root:not([data-theme="light"]) a) { color:var(--lime); }
}
.lead { font-size:clamp(1.09rem,1.03rem + .4vw,1.3rem); line-height:1.6; color:var(--text-muted); max-width:62ch; }
.muted { color:var(--text-muted); }
.small { font-size:.9375rem; line-height:1.55; }
.xsmall { font-size:.8125rem; line-height:1.5; }
.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;
}

.eyebrow {
  display:inline-flex; align-items:center; gap:.55rem;
  font-size:.8125rem; font-weight:700; letter-spacing:.14em; text-transform:uppercase;
  color:var(--navy); margin-bottom:var(--sp-4);
}
.eyebrow::before { content:""; width:26px; height:2px; background:var(--lime); border-radius:2px; }
:root[data-theme="dark"] .eyebrow { color:var(--lime); }
@media (prefers-color-scheme: dark) { :root:not([data-theme="light"]) .eyebrow { color:var(--lime); } }

.btn {
  display:inline-flex; align-items:center; justify-content:center; gap:.55rem;
  padding:.9rem 1.5rem; border-radius:var(--r-pill); border:2px solid transparent;
  font:inherit; font-weight:700; font-size:1rem; letter-spacing:-.01em; cursor:pointer;
  min-height:52px; text-decoration:none;
  transition:background-color var(--t) var(--ease),border-color var(--t) var(--ease),
             color var(--t) var(--ease),transform var(--t-fast) var(--ease),box-shadow var(--t) var(--ease);
}
.btn:hover { transform:translateY(-2px); }
.btn:active { transform:translateY(0); }
.btn:focus-visible { outline:3px solid var(--navy); outline-offset:3px; }
:root[data-theme="dark"] .btn:focus-visible { outline-color:var(--lime); }
@media (prefers-color-scheme: dark) { :root:not([data-theme="light"]) .btn:focus-visible { outline-color:var(--lime); } }
.btn--primary { background:var(--lime); color:var(--ink); box-shadow:0 6px 20px -8px rgba(161,202,59,.9); }
.btn--primary:hover { background:var(--lime-600); }
.btn--secondary { background:transparent; border-color:var(--border-strong); color:var(--text-strong); }
.btn--secondary:hover { border-color:var(--navy); }
.btn--sm { min-height:44px; padding:.6rem 1.1rem; font-size:.9375rem; }
.btn svg { width:18px; height:18px; flex:none; }
.iconbtn {
  width:44px; height:44px; border-radius:var(--r-pill); display:grid; place-items:center;
  border:1px solid var(--border-strong); background:var(--surface); color:var(--text-strong);
  cursor:pointer; transition:border-color var(--t) var(--ease),background-color var(--t) var(--ease);
}
.iconbtn:hover { border-color:var(--navy); }
.iconbtn:focus-visible { outline:3px solid var(--navy); outline-offset:2px; }
.iconbtn svg { width:20px; height:20px; }


/* ── Marke und Bedienelemente im Kopf ─────────────────────────────── */
.skip {
  position:absolute; left:-9999px; top:0; z-index:60;
  background:var(--surface); color:var(--text-strong); font-weight:700;
  padding:.7rem 1.1rem; border:2px solid var(--navy); border-radius:0 0 var(--r-sm) 0;
}
.skip:focus { left:0; }
.brand { display:flex; align-items:center; text-decoration:none; color:var(--text-strong); }
/* Die Wortmarke im Logo steht auf currentColor - deshalb folgt sie hier dem
   Textton des Modus. Das Lime im Bildzeichen ist im SVG festgelegt. */
.brand svg.brand__logo { height:34px; width:auto; display:block; }
@media (min-width:760px) { .brand svg.brand__logo { height:40px; } }
.top__tools { display:flex; align-items:center; gap:var(--sp-3); margin-inline-start:auto; }
.top nav { margin-inline-start:var(--sp-6); }
#theme .i-moon { display:none; }
:root[data-theme="dark"] #theme .i-sun { display:none; }
:root[data-theme="dark"] #theme .i-moon { display:block; }

/* ── Fuss ─────────────────────────────────────────────────────────── */
.foot { border-top:1px solid var(--border); background:var(--bg-soft); padding-block:var(--sp-7) var(--sp-6); }
.foot__grid { display:grid; gap:var(--sp-6); grid-template-columns:repeat(auto-fit,minmax(200px,1fr)); }
.foot h3 { font-size:.8125rem; font-weight:700; letter-spacing:.14em; text-transform:uppercase; color:var(--text-muted); margin-bottom:var(--sp-3); }
.foot ul { list-style:none; margin:0; padding:0; display:grid; gap:.5rem; }
.foot a { color:var(--text-muted); text-decoration:none; font-size:.9375rem; }
.foot a:hover { color:var(--text-strong); text-decoration:underline; }
.foot address { font-style:normal; color:var(--text-muted); font-size:.9375rem; line-height:1.7; }
/* Die Höhe muss auf das SVG, nicht auf den Behälter: im Entwurf war
   .foot__logo das SVG selbst, hier ist es ein <div> darum. Ohne diese Regel
   zeichnet das SVG in seiner Eigengrösse — 2635 Einheiten breit — und läuft
   in die Adresszeile darunter. */
.foot__logo { margin-bottom:var(--sp-4); color:var(--text-strong); }
.foot__logo svg { height:30px; width:auto; display:block; }
.foot__bar {
  display:flex; align-items:center; justify-content:space-between; gap:var(--sp-5);
  flex-wrap:wrap; border-top:1px solid var(--border); margin-top:var(--sp-6); padding-top:var(--sp-5);
}
.foot__legal { color:var(--text-muted); font-size:.875rem; }
/* Das Label des Verbands wird nicht umgefärbt. Sein Rot liest sich in beiden
   Modi (4.35:1 auf Weiss, 4.32:1 auf dem dunklen Grund), also braucht es
   keine weisse Unterlage. */
.sms { display:flex; align-items:center; gap:var(--sp-3); }
.sms img { height:34px; width:auto; display:block; }
.sms span { font-size:.8125rem; color:var(--text-muted); max-width:22ch; line-height:1.45; }

/* ── Kopf ─────────────────────────────────────────────────────────── */
.top { border-bottom:1px solid var(--border); background:var(--surface); position:sticky; top:0; z-index:20; }
.top__in { display:flex; align-items:center; gap:var(--sp-6); min-height:76px; }
/* Die Wortmarke ist Teil des SVG und kein Text daneben — font-weight und
   font-size hätten hier nichts zu tun. Sie standen in einer früheren
   Fassung mit Textwortmarke und sind entfernt. */
.brand { display:flex; align-items:center; text-decoration:none; color:var(--text-strong); }
.top nav ul { list-style:none; display:flex; gap:var(--sp-5); margin:0; padding:0; align-items:center; }
.top nav a { color:var(--text-muted); text-decoration:none; font-size:.9375rem; font-weight:500; }
.top nav a[aria-current] { color:var(--text-strong); font-weight:700; }
.top nav a:hover { color:var(--text-strong); }
.count {
  background:var(--navy); color:#fff; border-radius:var(--r-pill);
  font-size:.75rem; font-weight:700; padding:1px 7px; margin-inline-start:.35rem;
  font-variant-numeric:tabular-nums;
}

/* ── Hero-Slider ──────────────────────────────────────────────────── */
.hero { padding-block:var(--section-y); }
.slider { position:relative; }
.slider__viewport { overflow:hidden; border-radius:var(--r-lg); }
.slider__track { display:flex; transition:transform 420ms var(--ease); }
.slide {
  flex:0 0 100%; min-width:0;
  display:grid; gap:var(--sp-6); align-items:center;
  grid-template-columns:1fr;
  padding:clamp(1.5rem,4vw,2.75rem);
  background:var(--bg-soft); border:1px solid var(--border); border-radius:var(--r-lg);
}
/* Text und Bild gleich breit. Vorher 1.15fr .85fr -- die Bildspalte bekam 42,5
   Prozent und damit 424 Pixel, in die ein 1600 Pixel breiter Bildschirmabzug
   auf 26,5 Prozent geschrumpft wurde. Eine Schrift, die im Original 14 Pixel
   hoch war, wurde damit 3,7 Pixel hoch und zu grauem Brei. */
@media (min-width:820px) { .slide { grid-template-columns:1fr 1fr; } }
.slide__art { display:grid; place-items:center; order:-1; }
@media (min-width:820px) { .slide__art { order:0; } }
.slide__art .logotile {
  width:clamp(132px,17vw,180px); aspect-ratio:1; display:block;
  filter:drop-shadow(0 20px 38px rgba(12,31,71,.22));
}
.slide__art .logotile .logo { width:100%; height:100%; }

/* ── Bildschirmbild im Rahmen ────────────────────────────────────────
   Software verkauft sich mit Bildern. Der Rahmen ist bewusst ein
   Anwendungsfenster und kein Browserfenster: das Modul laeuft IN
   FreeScout, und eine Adresszeile wuerde etwas anderes behaupten.

   Die Flaechen darin sind gezeichnet und keine echten Aufnahmen - in
   einem Entwurf ist das ehrlicher als ein Bild, das spaeter nicht
   stimmt. Auf der echten Seite stehen hier product_media-Bilder. */
.shot {
  /* max-width war 520px und deckelte das Bild auch dort, wo die Spalte mehr
     hergäbe. Jetzt bestimmt die Spalte die Breite; die Grenze bleibt nur, weil
     ein Bildschirmabzug ab einer bestimmten Grösse nicht mehr besser wird,
     sondern nur noch mehr Bytes kostet. */
  width:100%; max-width:720px; border-radius:var(--r-md); overflow:hidden;
  background:var(--bg); border:1px solid var(--border);
  box-shadow:0 24px 48px -18px rgba(12,31,71,.34); position:relative;
}
.shot__bar {
  display:flex; align-items:center; gap:.4rem; padding:.5rem .7rem;
  background:var(--bg-soft); border-bottom:1px solid var(--border);
}
.shot__dot { width:9px; height:9px; border-radius:50%; background:var(--border); flex:none; }
.shot__title {
  font-size:.7rem; font-weight:600; letter-spacing:.03em; text-transform:uppercase;
  color:var(--text-muted); margin-inline-start:.35rem;
}
.shot__badge {
  position:absolute; inset-block-start:.5rem; inset-inline-end:.6rem;
  width:26px; height:26px; border-radius:7px; background:var(--bg);
  border:1px solid var(--border); background-size:cover; background-position:center;
}
.shot__body { padding:.75rem .8rem .9rem; display:grid; gap:.42rem; }
.shot__row {
  display:grid; grid-template-columns:1fr auto; gap:.6rem; align-items:center;
  padding:.42rem .55rem; border-radius:var(--r-sm); background:var(--bg-soft);
  font-size:.72rem; color:var(--text-muted);
}
.shot__row--head { background:transparent; padding-block:.1rem; font-weight:700; color:var(--text-strong); }
.shot__row--hot { background:var(--bg-tint); color:var(--text-strong); font-weight:600; }
.shot__num { font-variant-numeric:tabular-nums; color:var(--text-strong); font-weight:600; }
.shot__pill {
  display:inline-block; padding:.06rem .4rem; border-radius:var(--r-pill);
  background:var(--lime-200); color:var(--lime-ink); font-size:.62rem; font-weight:700;
}
.shot__note { font-size:.66rem; color:var(--text-muted); padding-inline:.55rem; }

/* ── Videofläche ─────────────────────────────────────────────────────
   Das Vorschaubild liegt hier, der Player nicht. Er entsteht erst beim
   Klick - vorher gibt es keine Verbindung zu YouTube und damit auch
   nichts, wofuer man eine Einwilligung braeuchte. */
.vid { position:relative; aspect-ratio:16/9; width:100%; max-width:520px; }
.vid__poster {
  position:absolute; inset:0; border-radius:var(--r-md); overflow:hidden;
  background:linear-gradient(150deg,var(--navy-900),var(--navy) 62%,var(--navy-600));
  border:1px solid var(--border); box-shadow:0 24px 48px -18px rgba(12,31,71,.34);
}
.vid__poster::after {
  content:""; position:absolute; inset:0;
  background:
    radial-gradient(120px 80px at 78% 22%, rgba(161,202,59,.32), transparent 70%),
    repeating-linear-gradient(115deg, rgba(255,255,255,.05) 0 2px, transparent 2px 22px);
}
.vid__play {
  position:absolute; inset:0; display:grid; place-items:center; gap:.5rem;
  background:transparent; border:0; cursor:pointer; color:#fff; border-radius:var(--r-md);
  align-content:center;
}
.vid__play:focus-visible { outline:3px solid var(--lime); outline-offset:3px; }
.vid__disc {
  width:62px; height:62px; border-radius:50%; display:grid; place-items:center;
  background:rgba(12,31,71,.72); border:2px solid rgba(255,255,255,.55);
  transition:transform .18s ease, background .18s ease;
}
.vid__play:hover .vid__disc { transform:scale(1.07); background:rgba(12,31,71,.86); }
.vid__disc svg { width:24px; height:24px; margin-inline-start:3px; }
.vid__label { font-size:.82rem; font-weight:600; text-shadow:0 1px 6px rgba(0,0,0,.45); }
.vid__hint {
  position:absolute; inset-block-end:.55rem; inset-inline:.7rem;
  font-size:.66rem; color:var(--on-navy-muted); text-align:center; line-height:1.35;
}

/* ── Bilderstreifen auf der Detailseite ──────────────────────────── */
.strip { display:grid; gap:var(--sp-4); margin-top:var(--sp-6);
  grid-template-columns:repeat(auto-fit,minmax(240px,1fr)); align-items:start; }
.strip figure { margin:0; display:grid; gap:.5rem; }
.strip .shot, .strip .vid { max-width:none; }
.strip figcaption { font-size:.8rem; color:var(--text-muted); }

/* ── Sprachwahl ─────────────────────────────────────────────────── */
.langpick { position:relative; display:inline-flex; align-items:center; }
.langpick select {
  appearance:none; font:inherit; font-size:.875rem; font-weight:600;
  color:var(--text-strong); background:var(--bg); cursor:pointer;
  border:1px solid var(--border); border-radius:var(--r-sm);
  padding:.42rem 1.9rem .42rem .55rem;
}
.langpick select:focus-visible { outline:3px solid var(--navy); outline-offset:2px; }
.langpick svg {
  position:absolute; inset-inline-end:.5rem; width:15px; height:15px;
  color:var(--text-muted); pointer-events:none;
}

/* ── Support ────────────────────────────────────────────────────── */
.support { background:var(--bg-soft); padding-block:var(--section-y); }

/* Zwei Drittel Fragen, ein Drittel Ticket.
   minmax(0,…) und nicht 2fr/1fr allein: eine fr-Spalte ist mindestens so breit
   wie ihr laengster unteilbarer Inhalt. In den FAQ-Antworten stehen eine
   Tabelle und lange Wortzusammensetzungen -- ohne die 0 als Untergrenze
   schiebt eines davon die Spalte auf und der Teiler stimmt nicht mehr.
   Unter 900px eine Spalte: ein Drittel von 899px waere kein Formular mehr. */
.support__spalten { display:grid; gap:var(--sp-6); }
/* Auf dem Telefon zuerst das Ticket, dann die Fragen.
   Einspaltig laege die Ticketbox sonst hinter zehn FAQ-Eintraegen -- gemessen
   etwa vier Bildschirmhoehen tief. Wer auf einer Support-Seite landet, will
   fragen oder lesen; das Fragen darf nicht das weiter entfernte von beiden
   sein.
   Nur die SICHTBARE Reihenfolge dreht sich. Im Markup bleiben die Fragen
   vorn, und in dieser Reihenfolge liest eine Vorlesesoftware sie auch --
   inhaltlich ist das die richtige, hier verschiebt sich nur die Fläche. */
.support__seite { order:-1; }
@media (min-width:900px) {
  .support__spalten { grid-template-columns:minmax(0,2fr) minmax(0,1fr); gap:var(--sp-6); align-items:start; }
  .support__seite { order:0; }
}

/* Karten wie auf der Kasse -- die Klasse bleibt, weil checkout.blade.php sie
   benutzt. Auf der Support-Seite selbst gibt es sie seit dem 08.09.2026 nicht
   mehr. */
.support__card {
  background:var(--bg); border:1px solid var(--border); border-radius:var(--r-md);
  padding:var(--sp-5);
}
.support__card h3 { margin:0 0 var(--sp-2); font-size:1.05rem; }
.support__card p { margin:0; color:var(--text-muted); font-size:.9375rem; }
.support__card a { font-weight:600; }

/* Der Platzhalter fuers Ticketformular. Bauart wie .buybox auf der Kasse. */
.ticketbox {
  border:1px solid var(--border); border-radius:var(--r-lg); background:var(--surface);
  padding:var(--sp-5); box-shadow:var(--shadow-sm);
}
/* NICHT klebend -- und das ist eine Korrektur, keine Unterlassung.

   Bis zum 23.09.2026 stand hier position:sticky auf .support__seite. Das war
   richtig, solange in der Box drei Zeilen und ein Knopf standen: 300 Pixel,
   die beim Lesen der FAQ mitwandern.

   Seit dort das Ticketformular steht, ist die Box 980 Pixel hoch -- gemessen
   bei 1440x900, also hoeher als der Bildschirm. Sticky haelt ein Element an
   top:96px fest; was unten herausragt, ist damit nicht mehr erreichbar, und
   das Untere sind hier das Dateifeld und der Senden-Knopf.

   Heute faellt das nicht auf: die FAQ-Spalte ist kuerzer als das Formular,
   also gibt es gar keine Strecke, auf der etwas kleben koennte. Es faellt
   erst auf, wenn jemand ueber die Veroeffentlichungsschnittstelle FAQ-
   Eintraege ergaenzt -- und dann sucht er den Grund in der FAQ und nicht
   hier. Deshalb weg, bevor es soweit ist. */
.ticketbox h2 { margin:0 0 var(--sp-3); font-size:1.35rem; }
/* Der Abstand zwischen «SUPPORT-TICKET» und «Ticket eröffnen».

   .eyebrow bringt ihn selbst mit (margin-bottom:var(--sp-4)) -- hier stand er
   trotzdem auf 0, gemessen. Der Grund ist .ticketbox p { margin:0 } eine
   Zeile weiter unten: zwei Klassen gegen eine, die Kartenregel gewinnt gegen
   die Bauteilregel. In der FAQ-Spalte, wo dieselbe Klasse an derselben Stelle
   steht, sind es 16 Pixel.

   Zwei Klassen im Selektor, damit es nicht noch einmal passiert. */
.ticketbox .eyebrow { margin-bottom:var(--sp-3); }
.ticketbox p { margin:0; color:var(--text-muted); font-size:.9375rem; line-height:1.6; }
.ticketbox hr { border:0; border-top:1px solid var(--border); margin-block:var(--sp-5); }
.ticketbox__hinweis { font-size:.875rem; }

/* ── Das Ticketformular aus dem FormBuilder ──────────────────────
   Das eingebettete Formular bringt ABSICHTLICH kein Stylesheet mit: es soll
   das Design der Wirtsseite übernehmen. Der Server liefert nur Markup mit
   kurzen ff-Klassen; wie es aussieht, wird hier entschieden.

   Ohne diesen Block stünden in der Box Browser-Standardfelder -- graue
   Kästchen in Times, mitten in Aeonik. Das ist kein Schönheitsfehler: ein
   Formular, das aussieht wie von einer anderen Seite, wirkt wie eines, dem
   man seine Mailadresse nicht gibt.

   Die Klassen sind unter .ticketbox gebunden. Steht das Formular später
   irgendwo sonst im Shop, braucht es dort eigene Regeln -- das ist gewollt:
   die Felder sollen sich ihrer Umgebung anpassen, nicht umgekehrt. */
.ticketbox {
  /* Zwei eigene Töne, weil der Shop keine semantischen Farben hat. Grün ist
     das Lime der Marke in seiner lesbaren Fassung -- auf Weiss hat das helle
     Lime als Textfarbe keine 2:1. */
  --ff-bad:#B3261E;
  --ff-ok:var(--lime-ink);
}
:root[data-theme="dark"] .ticketbox { --ff-bad:#F2B8B5; --ff-ok:var(--lime); }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .ticketbox { --ff-bad:#F2B8B5; --ff-ok:var(--lime); }
}

.ticketbox__formular { margin-top:var(--sp-4); }
.ticketbox .ff { display:grid; gap:var(--sp-4); }
.ticketbox .ff-fields { display:grid; gap:var(--sp-4); }

/* «Mit * markierte Felder sind Pflichtfelder.» -- eine Fussnote, die oben
   steht, weil sie erst dort nützt. */
.ticketbox .ff-hint { font-size:.8125rem; color:var(--text-muted); }
.ticketbox .ff-row { display:grid; gap:var(--sp-2); }
.ticketbox .ff-label {
  font-size:.875rem; font-weight:600; color:var(--text-strong); line-height:1.4;
}
/* Der Stern trägt keine Aussage allein -- required und aria-required stehen
   im Markup. Er ist die zweite Spur, deshalb darf er auffallen. */
.ticketbox .ff-req { margin-inline-start:.2em; color:var(--ff-bad); }

.ticketbox .ff-in,
.ticketbox .ff-ta,
.ticketbox .ff-sel {
  width:100%; font:inherit; font-size:.9375rem; color:var(--text);
  background:var(--bg); border:1px solid var(--border-strong);
  border-radius:var(--r-sm); padding:.65rem .8rem;
  transition:border-color var(--t) var(--ease),box-shadow var(--t) var(--ease);
}
.ticketbox .ff-ta { resize:vertical; min-height:7rem; line-height:1.6; }
/* appearance:none nimmt dem Auswahlfeld den Systemlook -- sonst steht ein
   macOS-Knopf zwischen zwei Aeonik-Feldern. Der Pfeil kommt als Hintergrund,
   nicht als SVG-Element: er gehört zum Feld, nicht ins Markup. */
.ticketbox .ff-sel {
  appearance:none; cursor:pointer; padding-inline-end:2.2rem;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%2355606F' stroke-width='2' stroke-linecap='round'%3E%3Cpath d='M4 6l4 4 4-4'/%3E%3C/svg%3E");
  background-repeat:no-repeat; background-position:right .7rem center; background-size:15px;
}
.ticketbox .ff-in:focus-visible,
.ticketbox .ff-ta:focus-visible,
.ticketbox .ff-sel:focus-visible {
  outline:3px solid var(--navy); outline-offset:1px; border-color:var(--navy);
}
:root[data-theme="dark"] .ticketbox .ff-in:focus-visible,
:root[data-theme="dark"] .ticketbox .ff-ta:focus-visible,
:root[data-theme="dark"] .ticketbox .ff-sel:focus-visible { outline-color:var(--lime); border-color:var(--lime); }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .ticketbox .ff-in:focus-visible,
  :root:not([data-theme="light"]) .ticketbox .ff-ta:focus-visible,
  :root:not([data-theme="light"]) .ticketbox .ff-sel:focus-visible { outline-color:var(--lime); border-color:var(--lime); }
}

/* Das Dateifeld. Der Systemknopf darin lässt sich nicht erben -- also bekommt
   er wenigstens dieselbe Form wie alles andere. */
.ticketbox .ff-in[type="file"] { padding:.5rem .6rem; font-size:.875rem; cursor:pointer; }
.ticketbox .ff-in[type="file"]::file-selector-button {
  font:inherit; font-size:.8125rem; font-weight:600; cursor:pointer;
  margin-inline-end:.7rem; padding:.4rem .8rem;
  color:var(--text-strong); background:var(--bg-soft);
  border:1px solid var(--border-strong); border-radius:var(--r-pill);
}

/* Auswahlgruppen und die Einwilligung. */
.ticketbox .ff-fs { border:0; margin:0; padding:0; display:grid; gap:var(--sp-2); }
.ticketbox .ff-lg {
  padding:0; font-size:.875rem; font-weight:600; color:var(--text-strong);
}
.ticketbox .ff-opt,
.ticketbox .ff-consent {
  display:flex; align-items:start; gap:.6rem;
  font-size:.9375rem; line-height:1.5; cursor:pointer;
}
.ticketbox .ff-opt input,
.ticketbox .ff-consent input {
  margin:.2rem 0 0; width:18px; height:18px; flex:none; accent-color:var(--navy);
}

/* Ein Feld, das der Server bemängelt hat. Rahmen UND Text -- die Farbe allein
   sagt einem Rot-Grün-Auge nichts. */
.ticketbox .ff-bad .ff-in,
.ticketbox .ff-bad .ff-ta,
.ticketbox .ff-bad .ff-sel { border-color:var(--ff-bad); }
.ticketbox .ff-err { font-size:.8125rem; font-weight:600; color:var(--ff-bad); }

/* Die Fehlerübersicht oben. Sie bekommt den Fokus, wenn der Server ablehnt --
   deshalb muss man sehen, wo er gelandet ist. */
.ticketbox .ff-errors {
  border:1px solid var(--ff-bad); border-inline-start-width:4px;
  border-radius:var(--r-sm); padding:var(--sp-3) var(--sp-4);
  font-size:.875rem; color:var(--ff-bad);
}
.ticketbox .ff-errors:focus-visible { outline:3px solid var(--ff-bad); outline-offset:2px; }
.ticketbox .ff-errors ul { margin:var(--sp-2) 0 0; padding-inline-start:1.1rem; }

/* Überschriften und Absätze, die im Formular selbst stehen können. */
.ticketbox .ff-h { font-size:1.05rem; margin:var(--sp-2) 0 0; }
.ticketbox .ff-p { font-size:.9375rem; color:var(--text-muted); }

/* Der Absendeknopf trägt keine .btn-Klasse -- das Markup kommt vom Modul und
   weiss nichts von unseren Klassennamen. Also hier dasselbe Aussehen. */
.ticketbox .ff-send {
  display:inline-flex; align-items:center; justify-content:center; width:100%;
  min-height:52px; padding:.9rem 1.5rem; font:inherit; font-weight:700; font-size:1rem;
  letter-spacing:-.01em; cursor:pointer;
  color:var(--ink); background:var(--lime); border:2px solid transparent;
  border-radius:var(--r-pill); box-shadow:0 6px 20px -8px rgba(161,202,59,.9);
  transition:background-color var(--t) var(--ease),transform var(--t-fast) var(--ease);
}
.ticketbox .ff-send:hover { background:var(--lime-600); transform:translateY(-2px); }
.ticketbox .ff-send:active { transform:translateY(0); }
.ticketbox .ff-send:focus-visible { outline:3px solid var(--navy); outline-offset:3px; }
:root[data-theme="dark"] .ticketbox .ff-send:focus-visible { outline-color:var(--lime); }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .ticketbox .ff-send:focus-visible { outline-color:var(--lime); }
}
/* Während des Sendens: der Knopf ist aus und sagt «Wird gesendet …». Ohne
   sichtbaren Unterschied klickt jemand ein zweites Mal, und dann liegen zwei
   Tickets im Postfach. */
.ticketbox .ff-send:disabled { opacity:.55; cursor:default; }
.ticketbox .ff-send:disabled:hover { background:var(--lime); transform:none; }

/* Die Meldung nach dem Absenden. Bei Erfolg ist sie das EINZIGE, was noch in
   der Box steht -- das Formular ist dann weg. Sie darf also nicht wie eine
   Randnotiz aussehen. */
.ticketbox .ff-msg {
  margin:0; font-size:.9375rem; font-weight:600; line-height:1.6;
  border-radius:var(--r-sm); padding:var(--sp-4);
}
.ticketbox .ff-msg:focus-visible { outline:3px solid var(--navy); outline-offset:2px; }
.ticketbox .ff-msg-ok { color:var(--ff-ok); background:var(--bg-tint); border:1px solid var(--lime); }
.ticketbox .ff-msg-error { color:var(--ff-bad); background:var(--bg-soft); border:1px solid var(--ff-bad); }
/* Der Fehlerfall lässt das Formular STEHEN und schiebt die Meldung davor.
   Getippte Sätze verschwinden dabei nicht -- jemand tippt sie kein zweites
   Mal. Hier nur der Abstand dafür. */
.ticketbox .ff-msg-error { margin-bottom:var(--sp-4); }

/* Der Weg für alle, bei denen das Formular nicht ankommt. */
.ticketbox__weg { font-size:.875rem; }
.ticketbox__weg a { font-weight:600; }

/* ── Anleitungen ────────────────────────────────────────────────── */
/* Der Abschnittskopf ist auf 64ch begrenzt -- fuer Lesetexte richtig, fuer
   eine Ueberschrift zu eng: "Anleitungen zu den Modulen" braucht einzeilig
   737 Pixel bei 680 verfuegbaren, im 1200 breiten Behaelter. Der Einstiegstext
   behaelt seine Lesebreite ueber sein eigenes max-width.

   ZWEI Klassen im Selektor, und das ist nicht Zierde: .section-head steht
   weiter unten im Stilblatt, und bei gleicher Spezifitaet gewinnt die
   spaetere Regel. Mit .section-head--weit allein blieb max-width auf 680 --
   gemessen, nicht vermutet. Dieselbe Falle wie beim Deckel des Hero-Bildes,
   zwei Stunden vorher. */
.section-head.section-head--weit { max-width:none; }

/* Der Schnellstart. Sieht anders aus als die Liste, weil er etwas anderes ist:
   ohne LaStore installiert man kein gekauftes Modul auf Knopfdruck. Akzent
   links, damit die Reihenfolge auch ohne Farbe erkennbar bleibt. */
.schnellstart {
  display:flex; align-items:center; gap:var(--sp-5); text-decoration:none;
  background:var(--bg); border:1px solid var(--border);
  border-inline-start:4px solid var(--lime);
  border-radius:var(--r-md); padding:var(--sp-5);
  margin-bottom:var(--sp-5); box-shadow:var(--shadow-sm);
}
.schnellstart:hover .schnellstart__name { text-decoration:underline; }
.schnellstart:focus-visible { outline:3px solid var(--navy); outline-offset:3px; }
.schnellstart__bild {
  flex:0 0 auto; width:104px; height:104px; border-radius:var(--r-sm);
  object-fit:cover; object-position:center;
  background:var(--bg-soft); border:1px solid var(--border);
}
.schnellstart__bild--leer {
  display:flex; align-items:center; justify-content:center;
  background:var(--bg-tint); color:var(--navy);
}
.schnellstart__bild--leer svg { width:52px; height:52px; }
.schnellstart__wort { min-width:0; }
.schnellstart__eyebrow {
  display:block; font-size:.75rem; font-weight:700; letter-spacing:.08em;
  text-transform:uppercase; color:var(--text-muted);
}
.schnellstart__name {
  display:block; margin-top:.1rem; font-size:1.35rem; font-weight:800;
  letter-spacing:-.01em; color:var(--text-strong);
}
.schnellstart__text {
  display:block; margin-top:.35rem; color:var(--text-muted);
  font-size:.9375rem; line-height:1.55; max-width:64ch;
}
@media (max-width:560px) {
  .schnellstart { align-items:flex-start; gap:var(--sp-3); }
  .schnellstart__bild { width:72px; height:72px; }
  .schnellstart__bild--leer svg { width:38px; height:38px; }
  .schnellstart__name { font-size:1.15rem; }
}

/* Der LaStore-Kasten: im Laden ueber dem Katalog, im Warenkorb und an der
   Kasse als Erstes. Kein Kaufknopf und kein Preis -- es kostet nichts, und
   eine Position in der Bestellung waere es faelschlich. */
.lastorebox {
  display:flex; align-items:flex-start; gap:var(--sp-5);
  background:var(--bg-tint); border:1px solid var(--border);
  border-inline-start:4px solid var(--lime);
  border-radius:var(--r-md); padding:var(--sp-5); margin-bottom:var(--sp-6);
}
.lastorebox__bild {
  flex:0 0 auto; width:88px; height:88px; border-radius:var(--r-sm);
  object-fit:cover; object-position:center;
  background:var(--bg); border:1px solid var(--border);
}
.lastorebox__bild--leer {
  display:flex; align-items:center; justify-content:center;
  background:var(--bg); color:var(--navy);
}
.lastorebox__bild--leer svg { width:44px; height:44px; }
.lastorebox__wort { min-width:0; }
.lastorebox__eyebrow {
  margin:0; font-size:.75rem; font-weight:700; letter-spacing:.08em;
  text-transform:uppercase; color:var(--text-muted);
}
.lastorebox__titel {
  margin:.1rem 0 0; font-size:1.15rem; font-weight:800; letter-spacing:-.01em;
  color:var(--text-strong);
}
.lastorebox__text {
  margin:.35rem 0 0; color:var(--text-muted); font-size:.9375rem;
  line-height:1.55; max-width:64ch;
}
/* Knopf und Verweis nebeneinander, mit Abstand und umbruchfaehig: auf dem
   Telefon stehen sie sonst gequetscht in einer Zeile. */
.lastorebox__wege {
  margin:var(--sp-4) 0 0; display:flex; flex-wrap:wrap;
  align-items:center; gap:var(--sp-4);
}
.lastorebox__wege a:not(.btn) { font-weight:600; font-size:.9375rem; }
@media (max-width:560px) {
  .lastorebox { gap:var(--sp-3); padding:var(--sp-4); }
  .lastorebox__bild { width:64px; height:64px; }
  .lastorebox__bild--leer svg { width:34px; height:34px; }
}
/* Eine Liste und kein Kachelraster: die Einträge sind gleichrangig und werden
   gelesen, nicht verglichen. Ein Raster verspricht einen Unterschied, den es
   hier nicht gibt. */
.anleitungen { list-style:none; margin:0; padding:0; display:grid; gap:var(--sp-3); max-width:56rem; }
.anleitungen__item {
  display:flex; flex-wrap:wrap; align-items:baseline; gap:var(--sp-3);
  background:var(--bg); border:1px solid var(--border); border-radius:var(--r-md);
  padding:var(--sp-4) var(--sp-5);
}
/* Der ganze Block ist der Verweis, nicht nur der Name -- ein Ziel von 40 Pixeln
   Hoehe trifft man auch mit dem Daumen. Das Symbol liegt mit drin: ein Bild,
   das aussieht wie ein Knopf, soll auch einer sein. */
.anleitungen__link {
  flex:1 1 24rem; min-width:0; text-decoration:none;
  display:flex; align-items:center; gap:var(--sp-4);
}
/* Das Symbol traegt die Liste. Mit dem Auge findet man ein Bild schneller als
   eine Zeile Text -- bei acht Modulen ist das bequem, bei dreissig ist es der
   Unterschied zwischen Finden und Suchen.

   QUADRATISCH, obwohl die Vorlagen 640x360 sind. object-fit:cover schneidet
   dafuer links und rechts ab -- das geht, weil die Grafik in allen sieben
   Vorlagen mittig sitzt und in der Hoehe Platz laesst; nachgesehen wurde
   jedes einzelne. object-position bleibt bewusst auf center: waere die
   Grafik in einer neuen Vorlage nicht mittig, faellt es hier auf und nicht
   erst beim Kunden.
   flex-shrink:0, damit ein langer Name das Symbol nicht schmaler zieht. */
.anleitungen__bild {
  flex:0 0 auto; width:88px; height:88px; border-radius:var(--r-sm);
  object-fit:cover; object-position:center;
  background:var(--bg-soft); border:1px solid var(--border);
}
/* Kein Bild hinterlegt: ruhige Flaeche mit dem Anfangsbuchstaben. Eine Luecke
   im Raster sieht nach einem Fehler aus. */
.anleitungen__bild--leer {
  display:flex; align-items:center; justify-content:center;
  font-weight:800; font-size:1.5rem; color:var(--text-muted);
  background:var(--bg-tint);
}
.anleitungen__wort { min-width:0; }
.anleitungen__name { display:block; font-weight:700; color:var(--text-strong); }
.anleitungen__link:hover .anleitungen__name { text-decoration:underline; }
.anleitungen__text { display:block; margin-top:.15rem; color:var(--text-muted); font-size:.9375rem; line-height:1.5; }
/* Auf dem Telefon kleiner, aber nicht weg: es ist der Grund, warum die Liste
   mit dem Auge durchsuchbar ist. */
@media (max-width:560px) {
  .anleitungen__bild { width:64px; height:64px; }
  /* Oben statt mittig: schmal bricht die Beschreibung auf acht Zeilen um, und
     ein mittig ausgerichtetes Symbol schwebt dann irgendwo in der Zeile statt
     neben dem Namen zu stehen. Breit sind es zwei bis drei Zeilen, dort ist
     mittig richtig. */
  .anleitungen__link { gap:var(--sp-3); align-items:flex-start; }
}
.anleitungen__produkt { flex:0 0 auto; font-size:.875rem; font-weight:600; }
/* "Anleitung folgt" ist kein Verweis und sieht auch nicht wie einer aus: der
   Eintrag fuehrt dann auf die Produktseite, und das steht am Namen. Ein
   zweiter Verweis daneben, der aussieht wie einer und keiner ist, waere
   genau die Sorte Knopf, die nichts tut. */
.anleitungen__offen {
  flex:0 0 auto; font-size:.8125rem; color:var(--text-muted);
  border:1px dashed var(--border-strong, var(--border)); border-radius:var(--r-pill);
  padding:.15rem .6rem; white-space:nowrap;
}
.anleitungen__link:focus-visible, .anleitungen__produkt:focus-visible {
  outline:3px solid var(--navy); outline-offset:3px; border-radius:4px;
}

.slide h1 { font-size:clamp(1.9rem,1.3rem + 2.2vw,2.85rem); }
.slide .lead { margin-top:var(--sp-4); max-width:48ch; }
.slide__actions { display:flex; flex-wrap:wrap; gap:var(--sp-3); margin-top:var(--sp-5); align-items:center; }
.slide__price { font-weight:700; color:var(--text-strong); font-size:1.15rem; font-variant-numeric:tabular-nums; }
.slide__price small { font-weight:400; color:var(--text-muted); font-size:.85rem; }
.mark { position:relative; white-space:nowrap; }
.mark::after {
  content:""; position:absolute; inset-inline:-.12em; bottom:.08em; height:.42em;
  background:var(--lime); opacity:.42; z-index:-1; border-radius:2px;
}
.badge-new {
  display:inline-flex; align-items:center; gap:.35rem;
  font-size:.75rem; font-weight:700; letter-spacing:.08em; text-transform:uppercase;
  padding:.25rem .65rem; border-radius:var(--r-sm);
  background:var(--lime-200); color:#31450C; margin-bottom:var(--sp-4);
}
:root[data-theme="dark"] .badge-new { background:rgba(161,202,59,.18); color:var(--lime); }
@media (prefers-color-scheme: dark) { :root:not([data-theme="light"]) .badge-new { background:rgba(161,202,59,.18); color:var(--lime); } }

.slider__bar { display:flex; align-items:center; gap:var(--sp-3); margin-top:var(--sp-4); flex-wrap:wrap; }
.dots { display:flex; gap:.4rem; margin-inline:auto; }
.dot {
  width:44px; height:44px; display:grid; place-items:center;
  border:0; background:none; cursor:pointer; padding:0;
}
.dot::before {
  content:""; width:9px; height:9px; border-radius:50%;
  background:var(--border-strong); transition:background-color var(--t) var(--ease),transform var(--t) var(--ease);
}
.dot[aria-current="true"]::before { background:var(--navy); transform:scale(1.35); }
:root[data-theme="dark"] .dot[aria-current="true"]::before { background:var(--lime); }
@media (prefers-color-scheme: dark) { :root:not([data-theme="light"]) .dot[aria-current="true"]::before { background:var(--lime); } }
.dot:focus-visible { outline:3px solid var(--navy); outline-offset:0; border-radius:var(--r-sm); }

/* ── Katalog ───────────────────────────────────────────────────────── */
.catalog { padding-block:0 var(--section-y); }
.section-head { max-width:64ch; margin-bottom:var(--sp-6); }
/* Ueberschriften haben margin:0, und .lead hatte keinen oberen Abstand -- der
   Einstiegstext klebte damit an der Ueberschrift. Auf einer Zeile faellt das
   kaum auf, bei drei Zeilen sehr: auf der Support-Seite bricht die Ueberschrift
   im Deutschen dreizeilig, und der naechste Satz begann ohne Luecke.
   .slide .lead hatte diesen Abstand seit je -- nur die Abschnittsköpfe nicht. */
.section-head .lead { margin-top:var(--sp-4); }
.chips { display:flex; flex-wrap:wrap; gap:.5rem; margin-bottom:var(--sp-6); }
.chip {
  font:inherit; font-size:.9375rem; cursor:pointer; min-height:44px;
  padding:.5rem 1.1rem; border-radius:var(--r-pill);
  border:1px solid var(--border); background:var(--surface); color:var(--text-muted);
}
.chip[aria-pressed="true"] { border-color:var(--navy); color:var(--text-strong); font-weight:700; background:var(--bg-tint); }
.chip:focus-visible { outline:3px solid var(--navy); outline-offset:2px; }

.grid { display:grid; gap:var(--sp-5); grid-template-columns:repeat(auto-fill,minmax(300px,1fr)); }

/* Produktkarte nach dem Muster von .postcard aus site.css: Bild als
   16:9-Band am oberen Rand, Radius --r-xl, Bild zoomt bei Hover.
   Bewusst dieselbe Form wie die Blogkarten - der Shop bringt kein
   zweites Kartenmuster in die Seite.

   Die ganze Karte ist anklickbar, aber KEIN <a> um die Karte: ein
   <button> in einem <a> ist ungültiges HTML und bricht die Tastatur.
   Stattdessen liegt ein Overlay auf dem Titel-Link, und der
   Warenkorb-Knopf wird darüber gehoben. */
.pcard {
  position:relative; display:flex; flex-direction:column; height:100%; overflow:hidden;
  background:var(--surface); border:1px solid var(--border); border-radius:var(--r-xl);
  transition:border-color var(--t) var(--ease),box-shadow var(--t) var(--ease),transform var(--t) var(--ease);
}
.pcard:hover { border-color:var(--border-strong); box-shadow:var(--shadow-lg); transform:translateY(-4px); }
.pcard:has(.card__link:focus-visible) { outline:3px solid var(--navy); outline-offset:3px; }
:root[data-theme="dark"] .pcard:has(.card__link:focus-visible) { outline-color:var(--lime); }
@media (prefers-color-scheme: dark) { :root:not([data-theme="light"]) .pcard:has(.card__link:focus-visible) { outline-color:var(--lime); } }

.pcard__media { display:block; position:relative; overflow:hidden; aspect-ratio:16/9; flex:none; background:var(--navy-900); }
.pcard__img {
  display:block; width:100%; height:100%;
  background-size:cover; background-position:center; background-repeat:no-repeat;
  transition:transform var(--t-slow) var(--ease);
}
.pcard:hover .pcard__img { transform:scale(1.04); }

.pcard__body { display:flex; flex-direction:column; gap:var(--sp-3); flex:1; padding:clamp(1.15rem,2.2vw,1.5rem); }
.pcard__head { display:flex; align-items:center; justify-content:space-between; gap:var(--sp-3); }
.pcard__cat {
  display:inline-flex; align-items:center; font-size:.75rem; font-weight:700;
  letter-spacing:.06em; text-transform:uppercase; padding:.25rem .6rem;
  border-radius:var(--r-sm); background:var(--bg-tint); color:var(--lime-ink);
}
:root[data-theme="dark"] .pcard__cat { background:rgba(161,202,59,.14); color:var(--lime); }
@media (prefers-color-scheme: dark) { :root:not([data-theme="light"]) .pcard__cat { background:rgba(161,202,59,.14); color:var(--lime); } }
.pcard__ver { color:var(--text-muted); font-size:.875rem; white-space:nowrap; font-variant-numeric:tabular-nums; }
.pcard__title { font-size:1.2rem; }
.card__link { color:inherit; text-decoration:none; }
.card__link::after { content:""; position:absolute; inset:0; border-radius:inherit; }
.card__link:focus-visible { outline:none; }
.pcard__excerpt { color:var(--text-muted); font-size:.9375rem; line-height:1.6; flex:1; }
.pcard__deps { font-size:.8125rem; color:var(--text-muted); display:flex; align-items:center; gap:.4rem; }
.pcard__deps svg { width:14px; height:14px; flex:none; }
.pcard__foot { display:flex; align-items:flex-end; justify-content:space-between; gap:var(--sp-3); flex-wrap:wrap; margin-top:var(--sp-2); }
/* Über das Overlay heben, sonst schluckt der Titel-Link den Klick. */
.pcard__foot .btn { position:relative; z-index:1; }
.pcard__req { font-size:.8125rem; color:var(--text-muted); border-top:1px solid var(--border); padding-top:var(--sp-3); margin-top:var(--sp-1); }
.price { font-weight:700; color:var(--text-strong); font-size:1.3rem; letter-spacing:-.02em; font-variant-numeric:tabular-nums; }
.price small { display:block; font-size:.8125rem; font-weight:400; color:var(--text-muted); letter-spacing:0; }

/* ── Detailseite ───────────────────────────────────────────────────── */
.detail { padding-block:var(--section-y); border-top:1px solid var(--border); background:var(--bg-soft); }
.detail__crumb { margin-bottom:var(--sp-5); font-size:.9375rem; }


/* "Technisches" ist so breit wie die LINKE Spalte darüber, nicht wie die
   ganze Seite — der Kasten soll unter der Beschreibung stehen, nicht unter
   Beschreibung UND Kaufkasten.

   Die Rechnung stammt aus dem Einbettungsskript: `.lead-in` ist dort ein
   Raster `1.4fr .6fr` mit 28px Zwischenraum (resources/embed/v1.js, Suche
   nach ".lead-in{"). Die linke Spalte ist damit (100% - 28px) * 1.4/2.
   Aendert sich das Verhaeltnis dort, muss es hier mit. Fest 764px waere
   einfacher gewesen und beim ersten Fensterwechsel falsch.

   Unter 900px stapelt das Skript auf eine Spalte — dann gilt hier auch die
   volle Breite. */
.detail__tech,
.detail__col { max-width:calc((100% - 28px) * 0.7); }
@media (max-width:899px) {
  .detail__tech,
  .detail__col { max-width:none; }
}
.detail__head { display:flex; gap:var(--sp-5); align-items:center; margin-bottom:var(--sp-5); flex-wrap:wrap; }
.detail__logo { width:80px; height:80px; display:grid; place-items:center; flex:none; }
.detail__logo img { width:66px; height:66px; display:block; }
.prose > * + * { margin-top:var(--sp-4); }
.prose p { color:var(--text-muted); }
.prose h3 { margin-top:var(--sp-6); }
/* Der Rahmen sitzt HIER, um Überschrift und Liste gemeinsam, damit auch
   "Technisches" auf dem weissen Grund steht. Die Liste selbst hat keinen
   eigenen Rahmen mehr — zwei Ringe ineinander waren das Störende. */
.techbox {
  border:1px solid var(--border); border-radius:var(--r-lg); background:var(--surface);
  padding:var(--sp-5); box-shadow:var(--shadow-sm);
}
.speclist { margin:0; }
/* 11rem statt 1fr 1fr: die Beschriftungen sind kurz ("Sprachen"), die Werte
   lang ("Deutsch, English, Français, Italiano"). Eine halbe Spalte fuer
   "Sprachen" verschenkt genau dort Platz, wo er gebraucht wird.

   Kein waagrechter Innenabstand mehr: den trägt jetzt der .techbox. Sonst
   wären die Zeilen doppelt eingerückt und die Trennlinien zu kurz. */
.speclist div { display:grid; grid-template-columns:11rem 1fr; gap:var(--sp-3); padding:.7rem 0; border-bottom:1px solid var(--border); font-size:.9375rem; }
@media (max-width:30rem) { .speclist div { grid-template-columns:1fr; gap:var(--sp-1); } }
.speclist div:first-child { padding-top:0; }
.speclist div:last-child { border-bottom:0; padding-bottom:0; }
.speclist dt { color:var(--text-muted); margin:0; }
.speclist dd { margin:0; color:var(--text-strong); font-weight:500; }
/* Fliesstext im Kasten bleibt schmal, auch wenn der Kasten breit ist:
   ~150 Zeichen je Zeile liest niemand gern. Die Merkmalsliste darf breit
   sein, weil dort nur kurze Werte stehen. */
.techbox p { max-width:68ch; }

/* Der Hinweis auf eine harte Voraussetzung. Bewusst NICHT wie `.techbox`:
   Technisches ist zum Nachschlagen, das hier ist eine Warnung vor dem Kauf und
   darf sich abheben. Grundton und Kante kommen aus den Marken-Merkmalen
   (--bg-tint, --lime), damit es in beiden Themen traegt -- --bg-tint ist im
   dunklen Thema neu gesetzt, eine feste Farbe waere dort unlesbar. */
.hinweisbox {
  border:1px solid var(--border); border-left:4px solid var(--lime);
  border-radius:var(--r-lg); background:var(--bg-tint);
  padding:var(--sp-5); box-shadow:var(--shadow-sm);
}
.hinweisbox h3 { margin:0 0 var(--sp-3); color:var(--text-strong); font-size:1.05rem; }
.hinweisbox p { max-width:68ch; margin:0 0 var(--sp-3); }
.hinweisbox a { color:var(--text-strong); font-weight:600; text-underline-offset:2px; }
.buybox {
  border:1px solid var(--border); border-radius:var(--r-lg); background:var(--surface);
  padding:var(--sp-5); box-shadow:var(--shadow-sm); position:sticky; top:96px;
}
.buybox .price { font-size:1.85rem; }
.buybox .btn { width:100%; margin-top:var(--sp-4); }
.buybox hr { border:0; border-top:1px solid var(--border); margin-block:var(--sp-5); }
.checklist { list-style:none; margin:0; padding:0; display:grid; gap:.6rem; }
.checklist li { display:flex; gap:.6rem; font-size:.9375rem; color:var(--text-muted); line-height:1.5; }
.checklist svg { width:18px; height:18px; flex:none; color:var(--lime-ink); margin-top:2px; }
:root[data-theme="dark"] .checklist svg { color:var(--lime); }
@media (prefers-color-scheme: dark) { :root:not([data-theme="light"]) .checklist svg { color:var(--lime); } }

/* ── Navy-Band ─────────────────────────────────────────────────────── */
.band { background:var(--navy-900); color:var(--on-navy); position:relative; overflow:hidden; padding-block:var(--section-y); }
.band h2 { color:#fff; }
.band .lead { color:var(--on-navy-muted); }
.band .eyebrow { color:var(--lime); }
.band__glow { position:absolute; width:min(50vw,640px); aspect-ratio:1; border-radius:50%; background:rgba(161,202,59,.16); filter:blur(110px); top:-30%; right:-10%; pointer-events:none; }
.band .container { position:relative; z-index:1; }
.band__actions { display:flex; flex-wrap:wrap; gap:var(--sp-3); margin-top:var(--sp-6); }
.btn--onnavy { background:transparent; border-color:rgba(255,255,255,.35); color:#fff; }
.btn--onnavy:hover { border-color:#fff; }
.btn--onnavy:focus-visible { outline-color:var(--lime); }

/* ── Vertrauensband, jetzt direkt über dem Fuss ────────────────────── */
.trust { border-top:1px solid var(--border); background:var(--bg-soft); padding-block:var(--sp-7); }
.trust__grid { display:grid; gap:var(--sp-5); grid-template-columns:repeat(auto-fit,minmax(230px,1fr)); }
.trust__item { display:flex; gap:var(--sp-3); align-items:flex-start; }
.trust__item svg { width:22px; height:22px; flex:none; color:var(--lime-ink); margin-top:2px; }
:root[data-theme="dark"] .trust__item svg { color:var(--lime); }
@media (prefers-color-scheme: dark) { :root:not([data-theme="light"]) .trust__item svg { color:var(--lime); } }
.trust__item b { color:var(--text-strong); display:block; font-size:.9375rem; }
.trust__item span { color:var(--text-muted); font-size:.875rem; line-height:1.5; }

/* Der Hinweis auf Paddle im Fuss. Das Zeichen sitzt auf der Grundlinie des
   Textes: vertical-align:-2px statt middle, weil middle es an der halben
   x-Hoehe ausrichtet und es dadurch zu hoch steht. */
.foot__mor { white-space:nowrap; }
.foot__paddle { height:14px; width:auto; vertical-align:-2px; }

/* ── Häufige Fragen ────────────────────────────────────────────────── */
/* Auf dem hellen Grund und NICHT auf --bg-soft: der Kachelstreifen darüber
   hat den schon, zwei gleiche Baender hintereinander lassen die Trennung
   verschwinden.

   Das Dreieck von <details> wird abgeschaltet und durch ein eigenes Zeichen
   ersetzt -- das voreingestellte ist in jedem Browser anders gross und laesst
   sich nicht ausrichten. list-style: none allein genuegt Safari nicht, dort
   braucht es ::-webkit-details-marker. */
.faq { border-top:1px solid var(--border); padding-block:var(--sp-7); }
.faq__list { max-width:56rem; display:grid; gap:var(--sp-3); }
.faq__item {
  border:1px solid var(--border); border-radius:var(--r-md);
  background:var(--surface); padding:var(--sp-4) var(--sp-5);
  transition:border-color var(--t) var(--ease);
}
.faq__item[open] { border-color:var(--border-strong); }
.faq__item summary {
  display:flex; align-items:center; justify-content:space-between; gap:var(--sp-4);
  cursor:pointer; list-style:none; font-weight:600; color:var(--text-strong);
}
.faq__item summary::-webkit-details-marker { display:none; }
.faq__item summary:focus-visible {
  outline:3px solid var(--lime); outline-offset:4px; border-radius:var(--r-sm);
}
.faq__plus {
  width:20px; height:20px; flex:none; color:var(--text-muted);
  transition:transform var(--t) var(--ease), color var(--t) var(--ease);
}
/* 45 Grad, nicht 90: aus dem Plus wird ein Kreuz, und die Bewegung ist auf
   dem kuerzesten Weg dorthin. Bei 135 Grad landet es gleich, dreht aber
   sichtbar weiter als noetig. */
.faq__item[open] .faq__plus { transform:rotate(45deg); color:var(--text-strong); }
.faq__item summary:hover .faq__plus { color:var(--text-strong); }

/* Sanftes Auf- und Zuklappen, wo der Browser es kann. Ohne
   interpolate-size laesst sich `height: auto` nicht ueberblenden -- und ein
   fester Wert waere geraten und bei langen Antworten falsch.

   Streng in @supports: kennt ein Browser das nicht, klappt es hart auf wie
   bisher. Kein Javascript, keine gemessenen Hoehen. */
@supports (interpolate-size: allow-keywords) {
  .faq__list { interpolate-size: allow-keywords; }
  .faq__item::details-content {
    height:0; overflow:hidden;
    transition:height var(--t) var(--ease), content-visibility var(--t) allow-discrete;
  }
  .faq__item[open]::details-content { height:auto; }
}
.faq__answer { padding-top:var(--sp-3); }
.faq__answer > * + * { margin-top:var(--sp-3); }
/* Nach einer Liste oder Tabelle mehr Luft: mit sp-3 klebte der Absatz
   am letzten Punkt, und der ganze Block las sich als eine Wand. */
.faq__answer > ul + *, .faq__answer > .tabellenrahmen + * { margin-top:var(--sp-4); }
.faq__answer > * + ul, .faq__answer > * + .tabellenrahmen { margin-top:var(--sp-4); }
.faq__answer p { margin:0; color:var(--text-muted); max-width:68ch; line-height:1.65; }
.faq__answer ul { margin:0; padding-left:1.15rem; color:var(--text-muted); line-height:1.65; }
.faq__answer li + li { margin-top:.25rem; }
/* Die Tabelle rollt in ihrem EIGENEN Rahmen. Sonst schiebt sie auf dem Telefon
   die ganze Seite seitwaerts — und das faellt am Schreibtisch nie auf. */
.tabellenrahmen { overflow-x:auto; }

/* AM RAHMEN und nicht an .faq__answer.
   Diese Regeln standen unter .faq__answer, weil Fliesstext-Tabellen bis zum
   08.09.2026 nur in FAQ-Antworten vorkamen. Seit die Anleitungen denselben
   Wandler benutzen, stehen dort ebenfalls Tabellen — und bekamen KEINE
   einzige Regel ab: der Browser zeichnete seine Vorgaben, Zeilenkoepfe
   zentriert, ohne Innenabstand und ohne Trennlinien. Gemeldet mit einem
   Bildschirmabzug, und es war genau das.
   `.tabellenrahmen` ist der richtige Anker: den Rahmen erzeugt der Wandler
   immer, also gilt die Gestaltung ueberall, wo eine Tabelle aus ihm kommt. */
.tabellenrahmen table {
  border-collapse:collapse; font-size:.875rem; color:var(--text-muted);
  min-width:34rem; width:100%;
}
.tabellenrahmen th, .tabellenrahmen td {
  text-align:left; padding:.55rem .8rem; border-bottom:1px solid var(--border);
  vertical-align:top;
}
.tabellenrahmen thead th { color:var(--text-strong); font-weight:600; white-space:nowrap; }
.tabellenrahmen tbody th { color:var(--text-strong); font-weight:600; }
.tabellenrahmen tbody tr:last-child th,
.tabellenrahmen tbody tr:last-child td { border-bottom:0; }
/* Die Kopfzeile abgesetzt: bei vier Spalten sucht das Auge sonst, wo die
   Ueberschriften aufhoeren. */
.tabellenrahmen thead th { border-bottom:2px solid var(--border-strong, var(--border)); }
/* Im Dokument braucht sie Luft wie ein Absatz -- .rechtstext gibt p und ul
   einen unteren Abstand, der Tabelle bisher keinen. */
.rechtstext .tabellenrahmen { margin:0 0 var(--sp-4); }
@media (prefers-reduced-motion: reduce) {
  .faq__item, .faq__plus { transition:none; }
  .faq__item::details-content, .faq__item[open]::details-content { transition:none; }
}

/* ── Warenkorb als Dialog ──────────────────────────────────────────── */
/* Natives <dialog> mit showModal(): Fokus bleibt drin, Escape schliesst,
   der Fokus kehrt beim Schliessen zum Auslöser zurück. Alles ohne
   eigenen Fokus-Käfig, der genau daran meist scheitert. */
dialog.cart {
  border:0; padding:0; background:transparent; max-width:min(560px,calc(100vw - 2rem));
  width:100%; margin:auto; color:var(--text);
}
dialog.cart::backdrop { background:rgba(12,31,71,.55); backdrop-filter:blur(2px); }
/* Der Bildkasten ist dasselbe <dialog>, nur breiter: ein Bildschirmabzug
   einer Oberfläche ist auf 560px genauso unlesbar wie auf der Seite. */
dialog.lb { max-width:min(1180px,calc(100vw - 2rem)); }
dialog.lb .cart__panel { padding:clamp(.9rem,2vw,1.25rem); max-height:min(94vh,none); }
dialog.lb img { width:100%; height:auto; display:block; border-radius:var(--r); }
dialog.lb figcaption { margin-top:.6rem; font-size:.84rem; color:var(--text-muted); }
.cart__panel {
  background:var(--surface); border:1px solid var(--border); border-radius:var(--r-lg);
  box-shadow:var(--shadow-lg); padding:clamp(1.35rem,3vw,1.85rem);
  max-height:min(86vh,780px); overflow:auto;
}
.cart__head { display:flex; align-items:center; justify-content:space-between; gap:var(--sp-4); margin-bottom:var(--sp-4); }
.cart__head h2 { font-size:1.35rem; }
.line { display:grid; grid-template-columns:1fr auto auto; gap:var(--sp-4); align-items:center; padding-block:var(--sp-4); border-bottom:1px solid var(--border); }
.line:last-of-type { border-bottom:0; }
.line b { color:var(--text-strong); display:block; font-size:.9375rem; }
.line__logo { width:34px; height:34px; display:grid; place-items:center; flex:none; }
.line__logo img { width:28px; height:28px; }
.line__main { display:flex; gap:var(--sp-3); align-items:center; min-width:0; }
.qty { width:74px; font:inherit; font-size:.9375rem; padding:.5rem .6rem; text-align:right; border:1px solid var(--border); border-radius:var(--r-sm); background:var(--bg-soft); color:var(--text); min-height:44px; font-variant-numeric:tabular-nums; }
.qty:focus-visible { outline:3px solid var(--navy); outline-offset:2px; }
.sum { display:flex; justify-content:space-between; align-items:baseline; border-top:2px solid var(--border-strong); margin-top:var(--sp-4); padding-top:var(--sp-4); }
.sum b { font-size:1.35rem; color:var(--text-strong); font-variant-numeric:tabular-nums; letter-spacing:-.02em; }
.vatnote { color:var(--text-muted); font-size:.8125rem; margin-top:var(--sp-3); }
.cart__actions { display:flex; gap:var(--sp-3); flex-wrap:wrap; margin-top:var(--sp-5); }
.cart__actions .btn { flex:1 1 auto; }

/* ── Anmerkungen ───────────────────────────────────────────────────── */
.notes { padding-block:var(--section-y); border-top:1px solid var(--border); }
.notes ol { margin:0; padding-inline-start:1.3rem; display:grid; gap:var(--sp-4); max-width:74ch; }
.notes li { color:var(--text-muted); font-size:.9375rem; line-height:1.6; }
.notes li b { color:var(--text-strong); }
.notes code { font-family:ui-monospace,"SF Mono",monospace; font-size:.85em; background:var(--bg-soft); border:1px solid var(--border); border-radius:4px; padding:.05em .35em; }
.foot { border-top:1px solid var(--border); padding-block:var(--sp-6); color:var(--text-muted); font-size:.875rem; }

@media (max-width:760px) {
  .top__in { flex-wrap:wrap; padding-block:var(--sp-4); min-height:0; }
  .top nav { margin-inline-start:0; width:100%; }
  .top nav ul { gap:var(--sp-4); flex-wrap:wrap; }
  .line { grid-template-columns:1fr auto; }
  .line .price { grid-column:1 / -1; text-align:right; }
}
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation:none !important; transition:none !important; }
  .btn:hover, .card:hover { transform:none; }
}
/* ══════════════════════════════════════════════════════════════════════
   Tokenbrücke zum Einbettungsskript.

   Das Skript zeichnet in einen Schattenbaum, und dort greift unser
   Stilblatt nicht. Eigene Eigenschaften (--foo) sind die einzige Art von
   Deklaration, die die Schattengrenze überquert — auch durch das
   :host{all:initial} des Skripts hindurch, weil `all` eigene
   Eigenschaften ausdrücklich nicht zurücksetzt.

   Sie heissen --lastore-* und nicht wie unsere Tokens: das Skript läuft
   auch auf fremden Seiten, und dort soll es nicht zufällig ein --navy
   einer anderen Marke erben. Wer den Shop einbettet, setzt diese sieben
   Werte — und nur diese.
   ══════════════════════════════════════════════════════════════════════ */
:root {
  --lastore-accent:var(--lime);
  --lastore-accent-ink:var(--navy-900);
  --lastore-accent-strong:var(--lime-ink);
  --lastore-text:var(--text);
  --lastore-text-strong:var(--text-strong);
  --lastore-muted:var(--text-muted);
  --lastore-surface:var(--surface);
  --lastore-ground:var(--bg-soft);
  --lastore-border:var(--border);
  --lastore-radius:var(--r-md);
  --lastore-radius-sm:var(--r-sm);
  --lastore-shadow:var(--shadow-sm);
  --lastore-shadow-hover:var(--shadow-md);
  --lastore-font:"Aeonik","Inter",system-ui,-apple-system,"Segoe UI",sans-serif;
}


/* ══════════════════════════════════════════════════════════════════════
   Kopf: sechs Menüpunkte, ein Auswahlfeld, zwei Knöpfe.

   Der Entwurf hatte drei Menüpunkte, der echte Shop hat sechs — und damit
   brach "Moduli FreeScout" auf zwei Zeilen und der Kopf wurde ausgefranst.
   Zwei Regeln dagegen: kein Umbruch innerhalb eines Punkts, und unter
   1100px wandert die Navigation in eine eigene Zeile, statt sich
   zusammenzuquetschen.
   ══════════════════════════════════════════════════════════════════════ */
.top nav a { white-space: nowrap; }
.top nav ul { gap: var(--sp-4); }

@media (max-width: 1320px) {
  .top__in { flex-wrap: wrap; row-gap: var(--sp-3); }
  .top nav { order: 3; flex-basis: 100%; margin-inline-start: 0; }
  .top nav ul { gap: var(--sp-5); }
  .top__tools { margin-inline-start: auto; }
}

@media (max-width: 560px) {
  /* Auf dem Telefon zählt der Warenkorb, nicht die Beschriftung daneben. */
  .top__tools .btn span.count:not([hidden]) { margin-inline-start: 0; }
  .top nav ul { gap: var(--sp-4); font-size: .9rem; }
}

/* Das Bild im Hero und in der Galerie füllt seinen Rahmen. */
img.shot { object-fit: cover; }
/* Nur die Breite, KEIN eigener Deckel mehr.
   Hier stand max-width:520px, und weil dieser Selektor spezifischer ist und
   weiter unten steht, gewann er gegen die Regel bei .shot. Beim Vergrössern
   des Rahmens habe ich die dort gehoben, gemessen und gesehen: das Bild blieb
   bei 520 stehen. Zwei Stellen für dieselbe Grenze ist eine zu viel — die
   Grenze steht jetzt allein bei .shot. */
.slide__art img.shot { width: 100%; }


/* Ein <img> mit position:absolute und inset:0 wird NICHT gestreckt — bei
   einem ersetzten Element bestimmt die Eigengrösse die Breite, und inset
   allein ändert daran nichts. Das YouTube-Vorschaubild ist 480 breit und
   sprengte damit den Rahmen um 84px nach rechts. */
img.vid__poster { width:100%; height:100%; object-fit:cover; }

/* Nichts darf die Seite waagrecht schieben. Die Regel ist die Netzsperre
   gegen genau die Klasse Fehler oben — sie behebt sie nicht, aber sie
   verhindert, dass eine unbemerkte Variante die ganze Seite verrutscht. */
html, body { overflow-x: clip; }


/* ── Verzicht auf das Widerrufsrecht ────────────────────────────────
   Gross genug zum Lesen und nicht kleingedruckt: eine Zustimmung, die
   man überliest, ist im Streitfall keine. */
.waiver {
  display:flex; gap:.7rem; align-items:flex-start; margin-top:var(--sp-4);
  padding:var(--sp-4); border:1px solid var(--border); border-radius:var(--r-sm);
  background:var(--bg-soft); font-size:.9375rem; line-height:1.5; cursor:pointer;
}
.waiver input { margin-top:.2rem; width:18px; height:18px; flex:none; accent-color:var(--navy); }
.waiver:hover { border-color:var(--border-strong); }
.waiver input:focus-visible { outline:3px solid var(--navy); outline-offset:2px; }


/* ── Gesperrte Bedienelemente müssen gesperrt AUSSEHEN ──────────────
   Der Bezahlknopf ist gesperrt, bis der Verzicht auf das Widerrufsrecht
   serverseitig festgehalten ist. Ohne diese Regel sah er unverändert aus:
   opacity 1, cursor pointer. Wer draufdrückt und nichts passiert, hält den
   Shop für kaputt — und genau an der Kasse ist das der teuerste Eindruck.

   :where() an dieser Stelle NICHT: die Regel soll die Farben der Varianten
   überstimmen, nicht ihnen nachgeben. */
.btn:disabled,
.btn[disabled] {
  opacity: .5;
  cursor: not-allowed;
  filter: grayscale(.4);
  box-shadow: none;
}
.btn:disabled:hover,
.btn[disabled]:hover { transform: none; }

.iconbtn:disabled { opacity: .5; cursor: not-allowed; }


/* Produktbilder: echte Dateien, keine eingebetteten Daten. */
.pcard__img--bexio { background-image:url("/img/products/bexio-band.png"); }
.pcard__img--bexiosubscriptions { background-image:url("/img/products/bexiosubscriptions-band.png"); }
.pcard__img--invoicing { background-image:url("/img/products/invoicing-band.png"); }
.pcard__img--shurl { background-image:url("/img/products/shurl-band.png"); }
.shot__badge--bexio { background-image:url("/img/products/bexio-mark.png"); }
.shot__badge--bexiosubscriptions { background-image:url("/img/products/bexiosubscriptions-mark.png"); }
.shot__badge--invoicing { background-image:url("/img/products/invoicing-mark.png"); }
.shot__badge--shurl { background-image:url("/img/products/shurl-mark.png"); }

/* Widerrufsbelehrung an der Kasse.
   Zurückhaltend gehalten: sie steht direkt über dem Häkchen und darf den
   Bezahlknopf nicht überschreien - aber sie muss auffindbar sein, sonst ist
   die Belehrung nur behauptet. */
.belehrung {
  margin: 0 0 var(--la-raum-3, 1rem);
  border: 1px solid var(--lastore-rand, #ddd);
  border-radius: 8px;
  background: var(--lastore-flaeche-leise, transparent);
}

.belehrung > summary {
  cursor: pointer;
  padding: .6rem .85rem;
  font-size: .875rem;
  font-weight: 600;
  color: var(--lastore-text-leise, inherit);
  list-style: none;
}

.belehrung > summary::-webkit-details-marker { display: none; }

.belehrung > summary::before {
  content: "＋";
  display: inline-block;
  width: 1.1em;
  font-weight: 400;
  color: var(--lastore-text-still, inherit);
}

.belehrung[open] > summary::before { content: "－"; }

.belehrung > summary:hover { color: var(--lastore-text, inherit); }

.belehrung > summary:focus-visible {
  outline: 2px solid var(--lastore-akzent, currentColor);
  outline-offset: 2px;
  border-radius: 6px;
}

.belehrung > p {
  margin: 0 .85rem .7rem;
  font-size: .84rem;
  line-height: 1.6;
  color: var(--lastore-text-leise, inherit);
}

.belehrung > p:first-of-type { margin-top: .2rem; }

/* ── Rechtstexte ─────────────────────────────────────────────────────────
 *
 * Die AGB haben 167 Abschnitte. Was einen langen Rechtstext lesbar macht,
 * ist nicht Gestaltung, sondern Ruhe: eine schmale Spalte, klare Stufen und
 * genug Luft zwischen den Abschnitten, damit das Auge die Gliederung sieht,
 * ohne sie zu suchen.
 */
.rechtstext { max-width: 46em; }
.rechtstext h1 { margin-bottom: var(--sp-2); }
.rechtstext h2 {
    margin-top: var(--sp-7);
    padding-top: var(--sp-4);
    border-top: 1px solid var(--rule);
}
.rechtstext h3 { margin-top: var(--sp-5); font-size: 1.05rem; }
/* Jede Ziffer ist ein eigener Gedanke -- sie braucht Luft davor, sonst
 * verschwimmen 131 Klauseln zu einer Wand. Vorher trugen die Ziffern
 * <h3>-Abstand; seit sie Absaetze sind, muss der Abstand hierher. */
.rechtstext p { line-height: 1.65; margin: 0 0 var(--sp-4); }
.rechtstext ul { line-height: 1.65; margin: 0 0 var(--sp-4); }

/* Die Ziffer steht vorn und bleibt vorn: ein haengender Einzug laesst den
 * Fliesstext an einer Kante beginnen, sodass das Auge beim Nachschlagen die
 * Nummernspalte hinunterlaufen kann.
 *
 * Die Klasse setzt der Renderer (Fliesstext), nicht ein :has()-Selektor --
 * wo :has fehlt, haette die Ausnahme nicht gegriffen und JEDER Absatz waere
 * eingerueckt worden. */
.rechtstext p.ziffer { padding-left: 2.6em; text-indent: -2.6em; }

/* Fassung und Stand: sichtbar, aber nicht laut. */
.rechtstext__stand {
    color: var(--soft);
    font-size: .9rem;
    margin-bottom: var(--sp-6);
}

.rechtstext__hinweis {
    background: var(--ground);
    border: 1px solid var(--rule);
    border-radius: var(--r);
    padding: 10px 14px;
    font-size: .9rem;
}

.rechtstext__fuss {
    margin-top: var(--sp-7);
    padding-top: var(--sp-4);
    border-top: 1px solid var(--rule);
    color: var(--soft);
    font-size: .9rem;
}

/* ── Sprungmarken der Rechtstexte ─────────────────────────────────────────

   Der Browser scrollt ein Sprungziel an den oberen Rand des Fensters -- und
   genau dort klebt .top. Ohne Abstand landet die angesprungene Ziffer also
   HINTER der Kopfzeile: der Link antwortet mit 200, springt, und der Leser
   sieht die Fundstelle nicht.

   --kopfhoehe setzt shop.js aus der wirklichen Hoehe. Sie ist nicht konstant:
   gemessen 89px ab 761px Fensterbreite, 121px bei 640px und 204px bei 375px,
   weil die Navigation in zwei oder drei Reihen umbricht. Ein festgeschriebener
   Wert waere auf zwei von drei Breiten falsch. Der Ausweichwert deckt den
   Fall, dass das Skript nicht laeuft.

   Dazu drei Zeilen Luft (Zeilenhoehe 22px), damit ueber der Ziffer noch der
   Schluss des vorigen Abschnitts steht -- so sieht man, dass man mitten in
   ein Dokument gesprungen ist und nicht an dessen Anfang. */
.rechtstext [id^="ziff-"] { scroll-margin-top: calc(var(--kopfhoehe, 89px) + 4rem); }

/* ── Anleitung als Dokument ──────────────────────────────────────────
   Bauart wie die mitgelieferten HTML-Anleitungen von Vault, Calendar und
   Scratchpad: Augenbraue, Titel, Kennzahlen als Karten, Inhaltskasten,
   Abschnitte. Sie lesen sich deutlich besser als eine Wand aus Absaetzen,
   und es gibt keinen Grund, im Laden etwas Schlechteres zu zeigen als im
   Paket. */
.anl { max-width:52rem; }
.anl__augenbraue {
  font-family:var(--mono, ui-monospace, monospace); font-size:.6875rem;
  font-weight:600; letter-spacing:.08em; text-transform:uppercase;
  color:var(--navy); margin:0 0 .6rem;
}
.anl h1 { font-size:clamp(1.75rem,1.2rem + 1.8vw,2.35rem); margin:0 0 var(--sp-4); }
.anl h2 {
  font-size:1.3rem; margin:var(--sp-7) 0 var(--sp-3);
  scroll-margin-top:calc(var(--kopfhoehe, 89px) + 2rem);
}
.anl h3 { font-size:1.05rem; margin:var(--sp-5) 0 var(--sp-2); }
.anl p { line-height:1.65; margin:0 0 var(--sp-4); max-width:64ch; color:var(--text-muted); }
.anl ul { line-height:1.65; margin:0 0 var(--sp-4); padding-inline-start:1.15rem; max-width:64ch; color:var(--text-muted); }
.anl li + li { margin-top:.3rem; }
.anl code {
  font-family:var(--mono, ui-monospace, monospace); font-size:.85em;
  background:var(--bg-tint); color:var(--navy);
  padding:.1em .4em; border-radius:5px;
}
.anl strong { color:var(--text-strong); font-weight:700; }

/* Kennzahlen: ein Blick, der "was kann das" vorwegnimmt. auto-fit, damit aus
   vier Karten auf dem Telefon zwei Reihen werden und nicht vier Zeilen. */
.anl__kennzahlen {
  display:grid; gap:var(--sp-3); margin:0 0 var(--sp-6);
  grid-template-columns:repeat(auto-fit,minmax(9.5rem,1fr));
}
.anl__kennzahl {
  background:var(--bg-soft); border:1px solid var(--border);
  border-radius:var(--r-md); padding:var(--sp-4);
}
.anl__kennzahl-wert { display:block; font-size:1.2rem; font-weight:800; color:var(--text-strong); letter-spacing:-.01em; }
.anl__kennzahl-was { display:block; margin-top:.2rem; font-size:.8125rem; line-height:1.45; color:var(--text-muted); }

.anl__inhalt {
  background:var(--bg-soft); border:1px solid var(--border);
  border-radius:var(--r-md); padding:var(--sp-4) var(--sp-5); margin:0 0 var(--sp-6);
}
.anl__inhalt-titel {
  margin:0 0 .5rem; font-size:.6875rem; font-weight:700; letter-spacing:.06em;
  text-transform:uppercase; color:var(--text-muted);
}
.anl__inhalt-liste { margin:0; max-width:none; font-size:.875rem; line-height:1.9; }
.anl__inhalt-liste a { color:var(--navy); text-decoration:none; }
.anl__inhalt-liste a:hover { text-decoration:underline; }

/* Karten statt Liste: eine Liste sagt "eins nach dem anderen", Karten sagen
   "waehle eines davon". */
.anl__karten {
  display:grid; gap:var(--sp-3); margin:0 0 var(--sp-5);
  grid-template-columns:repeat(auto-fit,minmax(15rem,1fr));
}
.anl__karte {
  background:var(--bg); border:1px solid var(--border);
  border-radius:var(--r-md); padding:var(--sp-4);
}
.anl__karte-titel { display:block; font-weight:700; color:var(--text-strong); font-size:.9375rem; }
.anl__karte-text { display:block; margin-top:.25rem; color:var(--text-muted); font-size:.875rem; line-height:1.55; }

/* Bild mit Unterschrift. Der Rahmen macht aus einem Bildschirmabzug ein Bild
   und nicht einen Fleck: die Abzuege haben oft einen weissen Rand, der ohne
   Kante in die Seite ausblutet. */
.anl__bild { margin:0 0 var(--sp-5); }
.anl__bild img {
  display:block; width:100%; height:auto; border-radius:var(--r-md);
  border:1px solid var(--border); background:var(--bg-soft);
}
.anl__bild figcaption {
  margin-top:.6rem; font-size:.8125rem; line-height:1.5; color:var(--text-muted);
}

.anl__tabelle { overflow-x:auto; margin:0 0 var(--sp-5); }
.anl__tabelle table { border-collapse:collapse; width:100%; min-width:30rem; font-size:.875rem; }
.anl__tabelle th, .anl__tabelle td {
  text-align:left; padding:.55rem .8rem; border-bottom:1px solid var(--border);
  vertical-align:top; color:var(--text-muted);
}
.anl__tabelle thead th {
  font-size:.6875rem; font-weight:700; letter-spacing:.06em; text-transform:uppercase;
  color:var(--text-muted); border-bottom:2px solid var(--border-strong); white-space:nowrap;
}
.anl__tabelle tbody th { color:var(--text-strong); font-weight:600; }
.anl__tabelle tbody tr:last-child th, .anl__tabelle tbody tr:last-child td { border-bottom:0; }

.anl__hinweis {
  background:var(--bg-tint); border:1px solid var(--border);
  border-inline-start:4px solid var(--lime);
  border-radius:var(--r-md); padding:var(--sp-3) var(--sp-4);
  margin:0 0 var(--sp-5); font-size:.9375rem;
}
.anl__fuss {
  margin-top:var(--sp-7); padding-top:var(--sp-4);
  border-top:1px solid var(--border); font-size:.875rem;
}

/* Der Weg vom Lesen zum Kaufen, am Ende jeder Anleitung. Deutlicher als der
   Textverweis vorher, aber ohne Preis: der steht auf der Produktseite und
   waere hier eine zweite Wahrheit. */
.anlcta {
  display:flex; align-items:center; gap:var(--sp-5); flex-wrap:wrap;
  margin-top:var(--sp-7);
  background:var(--bg-tint); border:1px solid var(--border);
  border-inline-start:4px solid var(--lime);
  border-radius:var(--r-md); padding:var(--sp-4) var(--sp-5);
}
.anlcta__wort { flex:1 1 18rem; min-width:0; }
.anlcta__eyebrow {
  margin:0; font-size:.75rem; font-weight:700; letter-spacing:.08em;
  text-transform:uppercase; color:var(--text-muted);
}
.anlcta__titel {
  margin:.15rem 0 0; font-weight:700; font-size:1.0625rem;
  color:var(--text-strong);
}
.anlcta__text {
  margin:.35rem 0 0; color:var(--text-muted); font-size:.9375rem; line-height:1.55;
}
/* flex:0 0 auto, damit der Knopf nicht schmaler wird als seine Aufschrift.
   Ohne das bricht "Paket herunterladen" auf engen Fenstern mitten im Wort. */
.anlcta__knopf { flex:0 0 auto; }
@media (max-width:34rem) {
  .anlcta { flex-direction:column; align-items:stretch; }
  .anlcta__knopf { text-align:center; }
}

/* Changelog (/shop/changelog/{alias}) — im Rahmen der Anleitung. Die Fassung
   als Überschrift, das Datum leise daneben; eine Linie trennt die Fassungen,
   damit eine lange Liste nicht zu einem Textblock zusammenläuft. */
.anl__fassung { border-top:1px solid var(--border); padding-top:var(--sp-2); }
.anl__fassung h2 { margin-top:var(--sp-5); font-size:1.75rem; }
.anl__fassung-datum {
  font-size:.875rem; font-weight:400;
  color:var(--text-muted); margin-inline-start:.6rem;
}
.anl__fassung-leer { font-style:italic; }
.anl__fassung h3 {
  font-size:1rem; font-weight:700;
  color:var(--text-strong); margin:var(--sp-4) 0 var(--sp-2);
}

/* Die Rubrik als farbiges Etikett: man sieht beim Überfliegen, ob eine
   Fassung etwas Neues bringt oder nur Fehler behebt. Die Farbe trägt die
   Bedeutung nie allein — das Wort steht immer drin. Text und Grund sind je
   Rubrik auf mindestens 4.5:1 abgestimmt, im dunklen Modus eigens. */
.anl__fassung h3.anl__rubrik {
  display:inline-block; font-size:.8125rem; font-weight:700; letter-spacing:.02em;
  padding:.2rem .65rem; border-radius:var(--r-pill);
  background:var(--rubrik-bg); color:var(--rubrik-ink);
}
.anl__rubrik--neu        { --rubrik-bg:#DDECB4; --rubrik-ink:#3D5410; }
.anl__rubrik--geaendert  { --rubrik-bg:#DCE6FA; --rubrik-ink:#12316F; }
.anl__rubrik--behoben    { --rubrik-bg:#FCEBC7; --rubrik-ink:#6E4300; }
.anl__rubrik--entfernt   { --rubrik-bg:#E8EBF0; --rubrik-ink:#3F4757; }
.anl__rubrik--sicherheit { --rubrik-bg:#FADADA; --rubrik-ink:#8A1C1C; }
:root[data-theme="dark"] .anl__rubrik--neu        { --rubrik-bg:rgba(161,202,59,.18); --rubrik-ink:#C6E37A; }
:root[data-theme="dark"] .anl__rubrik--geaendert  { --rubrik-bg:rgba(96,140,230,.22); --rubrik-ink:#B3C9F6; }
:root[data-theme="dark"] .anl__rubrik--behoben    { --rubrik-bg:rgba(230,170,60,.2);  --rubrik-ink:#F2C97A; }
:root[data-theme="dark"] .anl__rubrik--entfernt   { --rubrik-bg:rgba(160,170,190,.18); --rubrik-ink:#C9D0DC; }
:root[data-theme="dark"] .anl__rubrik--sicherheit { --rubrik-bg:rgba(230,90,90,.22);  --rubrik-ink:#F6AFAF; }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .anl__rubrik--neu        { --rubrik-bg:rgba(161,202,59,.18); --rubrik-ink:#C6E37A; }
  :root:not([data-theme="light"]) .anl__rubrik--geaendert  { --rubrik-bg:rgba(96,140,230,.22); --rubrik-ink:#B3C9F6; }
  :root:not([data-theme="light"]) .anl__rubrik--behoben    { --rubrik-bg:rgba(230,170,60,.2);  --rubrik-ink:#F2C97A; }
  :root:not([data-theme="light"]) .anl__rubrik--entfernt   { --rubrik-bg:rgba(160,170,190,.18); --rubrik-ink:#C9D0DC; }
  :root:not([data-theme="light"]) .anl__rubrik--sicherheit { --rubrik-bg:rgba(230,90,90,.22);  --rubrik-ink:#F6AFAF; }
}
.anl__fassung ul { margin-bottom:var(--sp-3); }

/* Ältere Fassungen im Changelog, eingeklappt. Der Knopf sieht aus wie ein
   Verweis, nicht wie ein Formularelement: er öffnet nur, er tut nichts. */
.anl__aeltere { border-top:1px solid var(--border); margin-top:var(--sp-5); padding-top:var(--sp-4); }
.anl__aeltere > summary {
  cursor:pointer; font-weight:600; color:var(--navy); list-style:none;
  display:inline-flex; align-items:center; gap:.4rem;
}
.anl__aeltere > summary::-webkit-details-marker { display:none; }
.anl__aeltere > summary::before { content:"▸"; transition:transform var(--t-fast) var(--ease); }
.anl__aeltere[open] > summary::before { transform:rotate(90deg); }
:root[data-theme="dark"] .anl__aeltere > summary { color:var(--lime); }
@media (prefers-color-scheme: dark) { :root:not([data-theme="light"]) .anl__aeltere > summary { color:var(--lime); } }
