/* =========================================================================
   QUADRONET Layout - Mikrodesign
   -------------------------------------------------------------------------
   Quelle: Projektinformationen/qn-mikrodesign.html (Bibliothek, 09/2026).
   Uebernommen sind NUR die 39 Varianten aus Dirks Auswahl vom 21.10.2026
   plus die Hilfsklassen, ohne die sie nicht funktionieren:

     Absatz      qp-schritt (im qp-schritte), qp-passer, qp-auszug,
                 qp2-terminal, qp2-licht
     Liste ul    ql-quadrat, ql-haken, ql-strich, ql-strahl, ql-plus, ql-minus
     Liste ol    qo-quadrat, qo-null, qo-stufen, qo-kette, qo-balken
     Ueberschr.  qh-wuerfel, qh-tor, qh-kicker, qh-kapitel,
                 qh2-reihe, qh2-walze, qh2-flip, qh2-rahmen
     Tabelle     qtb-linie, qtb-daten, qtb-fixkopf, qtb-preis (+ qtb-rollen)
     Block       qb-zitat, qb-zwischenruf, qb-hinweis, qb-warnung, qb-erfolg,
                 qb-aufklapper, qb-fakten
     Karte       qk-tafel, qk-kachel, qk-zeile, qk-zahl (+ qk-raster)
     Links       .qt-Regeln: Linktyp am href erkannt, gelten im Fliesstext
     Wortstile   qt-akzent, qt-leise, small, kbd; Textmarker mark.marker-*; code, pre

   UMBAU GEGENUEBER DER BIBLIOTHEK
   - Keine Grundklassen (.qp, .ql, .qtb ...) mehr noetig: EINE Klasse am
     Element reicht. Schrift, Farbe und Lesebreite kommen aus dem Theme
     (20-marke.css, 40-abschnitte.css), nicht aus der Variante.
   - system-ui -> IBM Plex Sans bzw. Bebas Neue (Zwischenruf, Kennzahlen,
     Wasserzeichen). Plex gibt es in 300/400/500/600 - 700/800 wuerde der
     Browser fett rechnen, deshalb hoechstens 600.
   - Farben laufen ueber --md-*. Die Tokens kippen auf Papier
     (.frame-m-paper) automatisch: Orange als SCHRIFT wird dort zu
     --orange-ink (4,9:1), Gruen/Rot/Blau werden dunkler. Orange als
     FLAECHE (Quadrate, Kanten) bleibt #FF8800 - Schmuck, keine Information.
   - Ringe um Punkte (Zeitstrahl, Kette) nehmen den Abschnittsgrund
     (--md-grund), sonst steht auf Papier ein dunkler Kringel.
   - .wuerfel ist im Theme schon das Hauszeichen (50-bausteine.css). Der
     Wuerfel der Ueberschrift heisst deshalb .qh-wuerfel__k.

   LISTEN UND SAFARI: list-style:none nimmt Safari die Listenansage.
   theme.js setzt role="list" an jede ul/ol mit ql-/qo-Klasse. Ohne
   Skript bleibt die Liste trotzdem lesbar.
   ========================================================================= */

@layer qn.theme {

  /* ----- Tokens -------------------------------------------------------- */
  :root {
    --md-stark:        #fff;
    --md-akzent:       var(--orange);        /* Orange als Schrift */
    --md-kicker:       var(--orange-hell);   /* kleine Schrift, 6,6:1 auf Carbon */
    --md-marke:        var(--orange);        /* Orange als Flaeche */
    --md-flaeche:      rgba(255, 255, 255, .045);
    --md-flaeche-2:    rgba(255, 255, 255, .075);
    --md-linie:        rgba(255, 255, 255, .13);
    --md-linie-2:      rgba(255, 255, 255, .22);
    --md-grund:        var(--carbon);
    --md-deckend:      #3d3d3d;              /* deckend, fuer klebende Tabellenkoepfe */
    --md-kachel:       rgb(52 82 103 / .34);
    --md-ok:           #4FBE8B;
    --md-fehler:       #FF6B57;
    --md-info:         #8FB9D6;
    --md-warn:         #F2A93B;
    --md-auf-hell:     #141A1F;              /* Schrift auf Orange */
    --md-auf-ton:      #141A1F;              /* Zeichen auf Hinweis-/Warn-/Erfolgston */
  }
  .frame-m-anthrazit {
    --md-grund:   var(--anthrazit);
    --md-deckend: #26394a;
  }
  .frame-m-paper {
    --md-stark:     var(--ink);
    --md-akzent:    var(--orange-ink);
    --md-kicker:    var(--orange-ink);
    --md-flaeche:   rgba(22, 36, 47, .045);
    --md-flaeche-2: rgba(22, 36, 47, .075);
    --md-linie:     rgba(22, 36, 47, .16);
    --md-linie-2:   rgba(22, 36, 47, .28);
    --md-grund:     var(--paper);
    --md-deckend:   #ECE8E2;
    --md-kachel:    rgba(22, 36, 47, .06);
    --md-ok:        #1E7A50;
    --md-fehler:    #B83A2B;
    --md-info:      #3D6E8F;
    --md-warn:      #A86200;
    --md-auf-ton:   #fff;
  }

  /* ======================================================================
     ABSATZFORMATE - eine Klasse am <p>
     ====================================================================== */

  /* Schritt: zaehlt sich selbst. Der Zaehler laeuft ueber den ganzen
     Abschnitt - ein qp-schritte-Container ist nicht noetig, der Abschnitt
     (.frame) setzt ihn zurueck. */
  .frame { counter-reset: qp-schritt; }
  .qp-schritte { counter-reset: qp-schritt; }
  .qp-schritt {
    counter-increment: qp-schritt;
    position: relative;
    padding-left: 3.6em;
    min-height: 2.6em;
  }
  .qp-schritt::before {
    content: counter(qp-schritt, decimal-leading-zero);
    position: absolute; left: 0; top: -.12em;
    display: grid; place-content: center;
    width: 2.5em; height: 2.5em;
    font: 600 .82em/1 var(--qn-schriftfamilie);
    letter-spacing: .02em;
    color: #fff;
    background: linear-gradient(145deg, rgb(52 82 103 / .95), rgba(13, 22, 30, .95));
    box-shadow: inset 0 0 0 2px var(--md-marke), 4px 4px 0 rgba(0, 0, 0, .3);
  }

  /* Passermarken: vier Eckwinkel, acht Verlaeufe in einer Angabe */
  .qp-passer {
    --_e: 14px;
    --_s: 2px;
    padding: 1.7em 1.9em;
    background:
      linear-gradient(var(--md-marke) 0 0) 0 0 / var(--_e) var(--_s),
      linear-gradient(var(--md-marke) 0 0) 0 0 / var(--_s) var(--_e),
      linear-gradient(var(--md-marke) 0 0) 100% 0 / var(--_e) var(--_s),
      linear-gradient(var(--md-marke) 0 0) 100% 0 / var(--_s) var(--_e),
      linear-gradient(var(--md-marke) 0 0) 0 100% / var(--_e) var(--_s),
      linear-gradient(var(--md-marke) 0 0) 0 100% / var(--_s) var(--_e),
      linear-gradient(var(--md-marke) 0 0) 100% 100% / var(--_e) var(--_s),
      linear-gradient(var(--md-marke) 0 0) 100% 100% / var(--_s) var(--_e);
    background-repeat: no-repeat;
  }

  /* Auszug: geviertes Quadrat statt Anfuehrungszeichen */
  .qp-auszug {
    position: relative;
    padding-top: 1.5em;
    font-size: clamp(1.25rem, 1.1rem + .7vw, 1.55rem);
    line-height: 1.42;
    font-weight: 300;
    color: var(--md-stark);
    max-width: 34rem;
  }
  .qp-auszug::before {
    content: "";
    position: absolute; top: 0; left: 0;
    width: 1.1em; height: 1.1em;
    background: conic-gradient(var(--md-marke) 0 25%, transparent 0 50%, var(--md-marke) 0 75%, transparent 0);
  }
  .qp-auszug::after {
    content: "";
    display: block;
    width: 3.2em; height: 2px;
    margin-top: .7em;
    background: var(--md-linie-2);
  }

  /* Terminal: Prompt und Schreibmarke */
  .qp2-terminal {
    font-family: var(--qn-schriftfamilie-fest, ui-monospace, Consolas, monospace);
    font-size: .94rem;
    line-height: 1.7;
    color: #CFEEE0;
    background: #1A1F23;
    padding: 1.2em 1.4em;
    max-width: 40rem;
    box-shadow: inset 3px 0 0 #4FBE8B, inset 0 0 0 1px rgba(255, 255, 255, .07);
  }
  .qp2-terminal::before { content: "\203A  " / ""; color: #4FBE8B; font-weight: 600; }
  .qp2-terminal::after {
    content: "\258C" / "";
    margin-left: .12em;
    color: #4FBE8B;
    animation: qp2-blinken 1.15s steps(2, jump-none) infinite;
  }
  @keyframes qp2-blinken { 50% { opacity: 0; } }

  /* Licht: Streiflicht von oben links. Nur auf dunklem Grund sinnvoll -
     auf Papier wird daraus ein heller Kasten mit dunkler Schrift. */
  .qp2-licht {
    position: relative;
    padding: 2.3em 2.1em;
    color: #fff;
    max-width: 40rem;
    background:
      radial-gradient(120% 95% at 18% -10%, rgba(255, 255, 255, .17) 0%, transparent 58%),
      linear-gradient(180deg, rgba(255, 255, 255, .05), rgba(0, 0, 0, .3));
    box-shadow: inset 0 1px 0 rgba(255, 255, 255, .22);
  }
  .qp2-licht::before {
    content: "";
    position: absolute; left: 0; top: 0;
    width: 38%; height: 2px;
    background: linear-gradient(90deg, rgba(255, 255, 255, .75), transparent);
  }
  .frame-m-paper .qp2-licht {
    color: var(--ink);
    background:
      radial-gradient(120% 95% at 18% -10%, #fff 0%, transparent 58%),
      linear-gradient(180deg, rgba(22, 36, 47, .02), rgba(22, 36, 47, .08));
    box-shadow: inset 0 1px 0 #fff, 0 10px 30px -18px rgba(0, 0, 0, .35);
  }

  /* ======================================================================
     LINKS IM FLIESSTEXT - Typ wird am href erkannt (.qt der Bibliothek)
     Gilt fuer Links in Absaetzen, Listen, Tabellen und Kennzahlen.
     Nicht fuer Knoepfe (.gt, .b) und Kartentitel.
     ====================================================================== */
  .frame :is(p, li, td, th, dd, blockquote) a:not(.gt, .b, .qk__titel a) {
    text-decoration-thickness: 2px;
    text-underline-offset: .22em;
    text-decoration-color: color-mix(in srgb, currentColor 50%, transparent);
    transition: text-decoration-color .18s ease, color .18s ease;
  }
  .frame :is(p, li, td, th, dd, blockquote) a:not(.gt, .b, .qk__titel a):hover { text-decoration-color: currentColor; }
  .frame :is(p, li, td, th, dd, blockquote) a:not(.gt, .b, .qk__titel a)::after {
    display: inline-block;
    margin-left: .28em;
    font-size: .88em;
    font-weight: 400;
    text-decoration: none;
    white-space: nowrap;
  }
  /* Extern - eigene Domains zaehlen nicht. :where() haelt die Spezifitaet
     niedrig, sonst ueberstimmt diese Regel die fuer target=_blank. */
  .frame :is(p, li, td, th, dd, blockquote) a:not(.gt, .b, .qk__titel a)[href^="http"]:not(:where([href*="quadronet."], [href*="1qn.de"], [href*="derfotorabe."]))::after {
    content: "\2197" / "";
  }
  .frame :is(p, li, td, th, dd, blockquote) a:not(.gt, .b, .qk__titel a)[target="_blank"]::after {
    content: "\2197" / "öffnet in neuem Fenster";
  }
  .frame :is(p, li, td, th, dd, blockquote) a:not(.gt, .b, .qk__titel a)[href^="#"] { text-decoration-style: dotted; text-decoration-thickness: 1.5px; }
  .frame :is(p, li, td, th, dd, blockquote) a:not(.gt, .b, .qk__titel a)[href^="#"]::after { content: "\2193" / ""; }
  .frame :is(p, li, td, th, dd, blockquote) a:not(.gt, .b, .qk__titel a)[href^="tel:"] { white-space: nowrap; }
  .frame :is(p, li, td, th, dd, blockquote) a:not(.gt, .b, .qk__titel a):is([href^="mailto:"], [href^="javascript:linkTo_UnCryptMailto"])::after { content: "\2709" / ""; }
  .frame :is(p, li, td, th, dd, blockquote) a:not(.gt, .b, .qk__titel a):is([href$=".pdf"], [href$=".docx"], [href$=".xlsx"], [href$=".zip"])::after {
    padding: .1em .45em;
    margin-left: .4em;
    font: 600 .68em/1.5 var(--qn-schriftfamilie);
    letter-spacing: .08em;
    color: var(--md-auf-hell);
    background: var(--md-marke);
    vertical-align: .08em;
  }
  .frame :is(p, li, td, th, dd, blockquote) a:not(.gt, .b, .qk__titel a)[href$=".pdf"]::after  { content: "PDF" / "PDF-Datei"; }
  .frame :is(p, li, td, th, dd, blockquote) a:not(.gt, .b, .qk__titel a)[href$=".docx"]::after { content: "DOC" / "Word-Datei"; }
  .frame :is(p, li, td, th, dd, blockquote) a:not(.gt, .b, .qk__titel a)[href$=".xlsx"]::after { content: "XLS" / "Excel-Datei"; }
  .frame :is(p, li, td, th, dd, blockquote) a:not(.gt, .b, .qk__titel a)[href$=".zip"]::after  { content: "ZIP" / "ZIP-Archiv"; }

  /* ======================================================================
     WORTSTILE - im RTE-Menue "Stile" fuer markierte Woerter
     Klassen statt style="color:..." (CSP ohne unsafe-inline). Die Farbe
     waehlt der Abschnitt: --md-akzent ist auf Carbon #FF8800 (5,3:1),
     auf Papier #A35700 (4,9:1).
     ====================================================================== */
  .qt-akzent { color: var(--md-akzent); }
  .qt-leise  { color: var(--qn-schrift-leise); }
  /* Textmarker (RTE-Knopf): <mark class="marker-orange|marker-blau">.
     Halbdeckend, damit die Schrift ihre Farbe behaelt - auf Carbon hell,
     auf Papier dunkel. */
  .frame mark {
    padding: .05em .25em;
    color: inherit;
    background: rgb(255 136 0 / .3);
    box-decoration-break: clone;
    -webkit-box-decoration-break: clone;
  }
  .frame mark.marker-blau { background: rgb(143 185 214 / .32); }
  .frame small { font-size: .84em; color: var(--qn-schrift-leise); }
  .frame kbd {
    display: inline-block;
    padding: .3em .55em;
    font: 600 .8em/1 var(--qn-schriftfamilie);
    color: #fff;
    background: linear-gradient(180deg, #4a4a4a, #222);
    border-radius: 3px;
    box-shadow: inset 0 1px 0 rgba(255, 255, 255, .25), 0 2px 0 rgba(0, 0, 0, .5);
    vertical-align: .05em;
  }

  /* Code im Fliesstext (Knopf "Code") */
  .frame :not(pre) > code {
    padding: .1em .35em;
    font-family: var(--qn-schriftfamilie-fest);
    font-size: .88em;
    color: var(--md-stark);
    background: var(--md-flaeche-2);
    box-shadow: inset 0 0 0 1px var(--md-linie);
    box-decoration-break: clone;
    -webkit-box-decoration-break: clone;
  }

  /* Codeblock (Knopf "Codeblock"): CKEditor schreibt
     <pre data-language="PHP"><code class="language-php">.
     Die Sprachen legt Configuration/RTE/Quadronet.yaml fest (codeBlock.
     languages) - wer dort eine ergaenzt, ergaenzt sie hier mit.
     Jede Sprache hat ihre Farbe: Kante links, Schild rechts oben und ein
     Hauch davon in der Flaeche (9 %). Erkannt wird sie an der Klasse am
     <code>, nicht an data-language - so bleibt sie auch, falls TYPO3 das
     Attribut beim Speichern verwirft. Die Schildschrift ist je Farbe
     gewaehlt (hell oder dunkel), jeweils mind. 4,5:1.
     pre-wrap statt Rollbalken: Ein rollender Kasten braucht tabindex,
     sonst erreicht ihn niemand per Tastatur - und den kann der RTE nicht
     setzen. "Plain text" bekommt kein Schild. */
  .frame pre {
    --_farbe: #8A97A3;
    --_auf: #141A1F;
    position: relative;
    max-width: 100%;
    padding: 1.1em 1.3em;
    font-family: var(--qn-schriftfamilie-fest);
    font-size: .88rem;
    line-height: 1.6;
    color: #E6EDF3;
    background: color-mix(in srgb, var(--_farbe) 9%, #1A1F23);
    box-shadow: inset 4px 0 0 var(--_farbe), inset 0 0 0 1px rgba(255, 255, 255, .07);
    white-space: pre-wrap;
    overflow-wrap: anywhere;
    tab-size: 4;
  }
  .frame pre code { font: inherit; color: inherit; background: none; padding: 0; box-shadow: none; }
  .frame pre:has(> code[class*="language-"]:not(.language-plaintext)) { padding-top: 1.9em; }
  .frame pre:has(> code[class*="language-"]:not(.language-plaintext))::after {
    /* --_name je Sprache; unbekannte Sprache: was CKEditor in data-language schreibt */
    content: var(--_name, attr(data-language));
    position: absolute; top: 0; right: 0;
    padding: .25em .65em;
    font: 600 .68rem/1.4 var(--qn-schriftfamilie);
    letter-spacing: .1em;
    text-transform: uppercase;
    color: var(--_auf);
    background: var(--_farbe);
  }
  .frame pre:has(> code.language-apache) { --_farbe: #D22128; --_auf: #fff; --_name: "Apache (.htaccess)"; }
  .frame pre:has(> code.language-c) { --_farbe: #A8B9CC; --_auf: #141A1F; --_name: "C"; }
  .frame pre:has(> code.language-cs) { --_farbe: #9B4F96; --_auf: #fff; --_name: "C#"; }
  .frame pre:has(> code.language-cpp) { --_farbe: #00599C; --_auf: #fff; --_name: "C++"; }
  .frame pre:has(> code.language-css) { --_farbe: #2965F1; --_auf: #fff; --_name: "CSS"; }
  .frame pre:has(> code.language-diff) { --_farbe: #8A97A3; --_auf: #141A1F; --_name: "Diff"; }
  .frame pre:has(> code.language-fluid) { --_farbe: #F49700; --_auf: #141A1F; --_name: "Fluid"; }
  .frame pre:has(> code.language-go) { --_farbe: #00ADD8; --_auf: #141A1F; --_name: "Go"; }
  .frame pre:has(> code.language-html) { --_farbe: #E34F26; --_auf: #141A1F; --_name: "HTML"; }
  .frame pre:has(> code.language-java) { --_farbe: #E76F00; --_auf: #141A1F; --_name: "Java"; }
  .frame pre:has(> code.language-javascript) { --_farbe: #F7DF1E; --_auf: #141A1F; --_name: "JavaScript"; }
  .frame pre:has(> code.language-json) { --_farbe: #C9A227; --_auf: #141A1F; --_name: "JSON"; }
  .frame pre:has(> code.language-php) { --_farbe: #8892BF; --_auf: #141A1F; --_name: "PHP"; }
  .frame pre:has(> code.language-python) { --_farbe: #3776AB; --_auf: #fff; --_name: "Python"; }
  .frame pre:has(> code.language-ruby) { --_farbe: #CC342D; --_auf: #fff; --_name: "Ruby"; }
  .frame pre:has(> code.language-scss) { --_farbe: #CD6799; --_auf: #141A1F; --_name: "SCSS"; }
  .frame pre:has(> code.language-bash) { --_farbe: #4EAA25; --_auf: #141A1F; --_name: "Shell"; }
  .frame pre:has(> code.language-sql) { --_farbe: #00758F; --_auf: #fff; --_name: "SQL"; }
  .frame pre:has(> code.language-typescript) { --_farbe: #3178C6; --_auf: #fff; --_name: "TypeScript"; }
  .frame pre:has(> code.language-typoscript) { --_farbe: #FF8700; --_auf: #141A1F; --_name: "TypoScript"; }
  .frame pre:has(> code.language-xml) { --_farbe: #0060AC; --_auf: #fff; --_name: "XML"; }
  .frame pre:has(> code.language-yaml) { --_farbe: #CB171E; --_auf: #fff; --_name: "YAML"; }

  /* ======================================================================
     LISTEN - eine Klasse am <ul>/<ol>
     .frame vorne: schlaegt die Grundeinrueckung aus 40-abschnitte.css.
     ====================================================================== */
  .frame :is(ul[class*="ql-"], ol[class*="qo-"]) {
    list-style: none;
    padding-inline-start: 0;
    margin-inline: 0;
  }
  .frame :is(ul[class*="ql-"], ol[class*="qo-"]) > li + li { margin-block-start: .7em; }

  /* Markenquadrat */
  .frame .ql-quadrat > li { position: relative; padding-left: 1.8em; }
  .frame .ql-quadrat > li::before {
    content: "";
    position: absolute; left: 0; top: .58em;
    width: .55em; height: .55em;
    background: var(--md-marke);
  }

  /* Haken - Checkliste */
  .frame .ql-haken > li { position: relative; padding-left: 2.1em; }
  .frame .ql-haken > li::before {
    content: "";
    position: absolute; left: 0; top: .32em;
    width: 1.05em; height: 1.05em;
    background: var(--md-ok);
    clip-path: polygon(14% 46%, 0 60%, 40% 100%, 100% 22%, 86% 8%, 39% 71%);
  }

  /* Strich */
  .frame .ql-strich > li { position: relative; padding-left: 2.2em; }
  .frame .ql-strich > li::before {
    content: "";
    position: absolute; left: 0; top: .82em;
    width: 1.35em; height: 2px;
    background: var(--md-marke);
  }

  /* Zeitstrahl - Punkte haengen ueber die Linie hinaus */
  .frame ul.ql-strahl { margin-left: .55em; }
  .frame .ql-strahl > li {
    position: relative;
    padding: 0 0 1.5em 2.1em;
    border-left: 2px solid var(--md-linie);
  }
  .frame ul.ql-strahl > li + li { margin-block-start: 0; }
  .frame .ql-strahl > li:last-child { border-left-color: transparent; padding-bottom: 0; }
  .frame .ql-strahl > li::before {
    content: "";
    position: absolute; left: -.42em; top: .5em;
    width: .72em; height: .72em;
    background: var(--md-marke);
    box-shadow: 0 0 0 4px var(--md-grund);
  }

  /* Zusagen und Ausschluesse. Das Minus ist ein Halbgeviertstrich. */
  .frame :is(.ql-plus, .ql-minus) > li { position: relative; padding-left: 2em; }
  .frame :is(.ql-plus, .ql-minus) > li::before {
    position: absolute; left: 0; top: 0;
    font-weight: 600;
    font-size: 1.05em;
    line-height: 1.55;
  }
  .frame .ql-plus > li::before  { content: "+" / ""; color: var(--md-ok); }
  .frame .ql-minus > li::before { content: "\2013" / ""; color: var(--md-fehler); }
  .frame .ql-minus > li { color: var(--qn-schrift-leise); }

  /* Zahl im Quadrat */
  .frame ol.qo-quadrat { counter-reset: qo; }
  .frame .qo-quadrat > li {
    counter-increment: qo;
    position: relative;
    padding-left: 3.3em;
    min-height: 2.3em;
  }
  .frame .qo-quadrat > li::before {
    content: counter(qo, decimal-leading-zero);
    position: absolute; left: 0; top: .05em;
    display: grid; place-content: center;
    width: 2.3em; height: 2.3em;
    font: 600 .78em/1 var(--qn-schriftfamilie);
    color: var(--md-stark);
    background: var(--md-flaeche-2);
    box-shadow: inset 0 0 0 2px var(--md-marke);
  }

  /* Fuehrende Null ueber ::marker - die schlankeste Variante */
  .frame ol.qo-null {
    list-style: decimal-leading-zero;
    padding-inline-start: 2.6em;
  }
  .frame .qo-null > li::marker {
    color: var(--md-akzent);
    font-weight: 600;
    font-variant-numeric: tabular-nums;
  }

  /* Mehrstufig 1. / 1.1 / 1.1.1 */
  .frame :is(ol.qo-stufen, ol.qo-stufen ol) { list-style: none; counter-reset: stufe; padding-inline-start: 0; }
  .frame ol.qo-stufen ol { margin: .6em 0 .2em 1.6em; }
  .frame .qo-stufen li { counter-increment: stufe; position: relative; padding-left: 3.4em; }
  .frame .qo-stufen li::before {
    content: counters(stufe, ".") " ";
    position: absolute; left: 0; top: 0;
    font: 600 .92em/1.75 var(--qn-schriftfamilie-fest, ui-monospace, monospace);
    color: var(--md-akzent);
    font-variant-numeric: tabular-nums;
  }
  .frame .qo-stufen ol li { padding-left: 4.2em; }

  /* Prozesskette */
  .frame ol.qo-kette { counter-reset: qo; margin-left: 1.1em; }
  .frame .qo-kette > li {
    counter-increment: qo;
    position: relative;
    padding: 0 0 1.7em 3.2em;
    border-left: 2px solid var(--md-linie);
  }
  .frame ol.qo-kette > li + li { margin-block-start: 0; }
  .frame .qo-kette > li:last-child { border-left-color: transparent; padding-bottom: 0; }
  .frame .qo-kette > li::before {
    content: counter(qo);
    position: absolute; left: -1.02em; top: 0;
    display: grid; place-content: center;
    width: 2em; height: 2em;
    font: 600 .8em/1 var(--qn-schriftfamilie);
    color: var(--md-auf-hell);
    background: var(--md-marke);
    box-shadow: 0 0 0 4px var(--md-grund);
  }

  /* Zahl auf dem Balken */
  .frame ol.qo-balken { counter-reset: qo; }
  .frame .qo-balken > li {
    counter-increment: qo;
    position: relative;
    padding: .8em 1.1em .8em 3.6em;
    background: var(--md-flaeche);
  }
  .frame ol.qo-balken > li + li { margin-block-start: .5em; }
  .frame .qo-balken > li::before {
    content: counter(qo, decimal-leading-zero);
    position: absolute; left: 0; top: 0; bottom: 0;
    width: 2.7em;
    display: grid; place-content: center;
    font: 600 .82em/1 var(--qn-schriftfamilie);
    color: var(--md-auf-hell);
    background: var(--md-marke);
  }

  /* ======================================================================
     UEBERSCHRIFTEN - kommen aus Partials/Header/All.html, nicht aus dem RTE
     Schrift (Bebas, Versalien) bleibt die des Themes.
     ====================================================================== */

  /* Kicker-Zeile ueber der Ueberschrift: das .label aus 50-bausteine.css.
     Die Nummer zaehlt sich selbst ueber die ganze Seite (Abschnitte 01-08),
     solange "Kapitelnummer" gewaehlt ist. */
  .qn-inhalt { counter-reset: qh-kap; }
  .label--kapitel { counter-increment: qh-kap; }
  .label--kapitel .nr::before { content: counter(qh-kap, decimal-leading-zero) " \00B7"; }

  /* Kapitel: Nummer als Marke VOR der Ueberschrift */
  .qh-kapitel {
    counter-increment: qh-kap;
    display: flex;
    align-items: flex-start;
    gap: .45em;
  }
  .qh-kapitel::before {
    content: counter(qh-kap, decimal-leading-zero);
    flex: 0 0 auto;
    display: grid; place-content: center;
    width: 2.2em; height: 2.2em;
    margin-top: .1em;
    font: 600 max(.38em, .72rem)/1 var(--qn-schriftfamilie);
    letter-spacing: .04em;
    color: var(--md-auf-hell);
    background: var(--md-marke);
  }

  /* Kicker IM Ueberschriftelement (Variante der Bibliothek). Fuer
     Abschnittskoepfe ist das .label oben die bessere Wahl - es steht
     ausserhalb des h2 und gehoert damit nicht zum Ueberschrifttext. */
  .qh-kicker .kicker {
    display: block;
    margin-bottom: .6em;
    font: 600 max(.32em, .72rem)/1 var(--qn-schriftfamilie);
    letter-spacing: .24em;
    text-transform: uppercase;
    color: var(--md-kicker);
  }
  .qh-kicker .kicker::after {
    content: "";
    display: inline-block;
    vertical-align: middle;
    width: 2.6em; height: 2px;
    margin-left: 1em;
    background: linear-gradient(90deg, var(--md-marke), transparent);
  }

  /* Wuerfel: echter Koerper aus sechs Flaechen */
  .qh-wuerfel {
    display: flex;
    align-items: center;
    gap: .5em;
    perspective: 700px;
  }
  .qh-wuerfel__k {
    --_w: .72em;
    position: relative;
    flex: 0 0 auto;
    width: var(--_w); height: var(--_w);
    transform-style: preserve-3d;
    transform: rotateX(-22deg) rotateY(-38deg);
    animation: qh-dreh 14s linear infinite;
  }
  .qh-wuerfel__k > span {
    position: absolute;
    inset: -1px;   /* 1 px Ueberstand gegen Schlitze an den Kanten */
    background: linear-gradient(145deg, var(--orange), #B35F00);
    box-shadow: inset 0 0 0 1px rgba(0, 0, 0, .3);
  }
  .qh-wuerfel__k > span:nth-child(1) { transform: translateZ(calc(var(--_w) / 2)); }
  .qh-wuerfel__k > span:nth-child(2) { transform: rotateY(180deg) translateZ(calc(var(--_w) / 2)); background: linear-gradient(145deg, #B35F00, #7A4100); }
  .qh-wuerfel__k > span:nth-child(3) { transform: rotateY(90deg) translateZ(calc(var(--_w) / 2)); background: linear-gradient(145deg, #4a4a4a, #222); }
  .qh-wuerfel__k > span:nth-child(4) { transform: rotateY(-90deg) translateZ(calc(var(--_w) / 2)); background: linear-gradient(145deg, #3a3a3a, #161616); }
  .qh-wuerfel__k > span:nth-child(5) { transform: rotateX(90deg) translateZ(calc(var(--_w) / 2)); background: linear-gradient(145deg, #FFA94D, #E07800); }
  .qh-wuerfel__k > span:nth-child(6) { transform: rotateX(-90deg) translateZ(calc(var(--_w) / 2)); background: linear-gradient(145deg, #2a2a2a, #0d0d0d); }
  @keyframes qh-dreh {
    from { transform: rotateX(-22deg) rotateY(0deg); }
    to   { transform: rotateX(-22deg) rotateY(360deg); }
  }
  .qh-wuerfel:hover .qh-wuerfel__k { animation-duration: 2.6s; }

  /* Tor: halbdeckende Klappe schwingt weg - fuer Ueberschriften, die
     eine Antwort ankuendigen */
  .qh-tor {
    position: relative;
    display: inline-block;
    perspective: 900px;
    padding: .25em .5em;
    isolation: isolate;
  }
  .qh-tor::before {
    content: "";
    position: absolute; inset: 0; z-index: 2;
    background: linear-gradient(160deg, rgb(255 136 0 / .42), rgb(140 72 0 / .5));
    transform-origin: top center;
    transform: rotateX(0deg);
    transition: transform .8s cubic-bezier(.34, 1.25, .5, 1);
    box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .2);
    pointer-events: none;
  }
  .qh-tor:hover::before,
  .qh-tor:focus-within::before { transform: rotateX(-96deg); }
  .qh-tor::after {
    content: "";
    position: absolute; inset: 0; z-index: -1;
    background: rgba(0, 0, 0, .3);
    box-shadow: inset 0 3px 14px rgba(0, 0, 0, .6);
  }
  .frame-m-paper .qh-tor::after { background: rgba(22, 36, 47, .07); box-shadow: inset 0 3px 14px rgba(22, 36, 47, .18); }
  /* Touch-Geraete kennen kein Hover: Klappe steht offen */
  @media (hover: none) { .qh-tor::before { transform: rotateX(-96deg); } }

  /* Quaderreihe: vier Wuerfel rollen als Welle */
  .qh2-reihe { display: flex; align-items: center; gap: .55em; perspective: 900px; }
  .qh2-reihe__q { display: flex; gap: .26em; flex: 0 0 auto; transform-style: preserve-3d; }
  .qh2-reihe__q > span {
    --_w: .5em;
    position: relative;
    width: var(--_w); height: var(--_w);
    transform-style: preserve-3d;
    animation: qh2-rollen 5.5s cubic-bezier(.5, 0, .2, 1) infinite;
  }
  .qh2-reihe__q > span:nth-child(2) { animation-delay: .22s; }
  .qh2-reihe__q > span:nth-child(3) { animation-delay: .44s; }
  .qh2-reihe__q > span:nth-child(4) { animation-delay: .66s; }
  .qh2-reihe__q i {
    position: absolute; inset: -1px; display: block;
    background: linear-gradient(145deg, var(--orange), #A85A00);
  }
  .qh2-reihe__q i:nth-child(1) { transform: translateZ(calc(var(--_w) / 2)); }
  .qh2-reihe__q i:nth-child(2) { transform: rotateX(90deg) translateZ(calc(var(--_w) / 2)); background: linear-gradient(145deg, #FFA94D, #E07800); }
  .qh2-reihe__q i:nth-child(3) { transform: rotateX(180deg) translateZ(calc(var(--_w) / 2)); background: linear-gradient(145deg, #4a4a4a, #1c1c1c); }
  .qh2-reihe__q i:nth-child(4) { transform: rotateX(-90deg) translateZ(calc(var(--_w) / 2)); background: linear-gradient(145deg, #333, #0d0d0d); }
  @keyframes qh2-rollen {
    0%, 55%   { transform: rotateX(0deg); }
    70%, 100% { transform: rotateX(-360deg); }
  }

  /* Walze: vier Woerter auf einem Quader. ALLE Woerter stehen im
     Quelltext - Suchmaschinen und Vorlesesoftware lesen die ganze Zeile.
     Die sichtbare Walze ist aria-hidden, der Text dafuer steht einmal
     als .qn-nur-vorlesen daneben. Breite fest, sonst springt die Zeile
     bei jedem Wortwechsel - sie kommt aus dem laengsten Wort (--_b,
     setzt das Partial als Klasse). */
  .qh2-walze { display: flex; align-items: baseline; flex-wrap: wrap; column-gap: .35em; }
  .qh2-walze__w {
    --_h: 1.05em;
    position: relative;
    display: inline-block;
    height: var(--_h);
    width: var(--_b, 8em);
    perspective: 900px;
    perspective-origin: 0 50%;
    vertical-align: baseline;
  }
  .qh2-walze__w > span {
    position: absolute; inset: 0;
    transform-style: preserve-3d;
    animation: qh2-walzen 13s cubic-bezier(.6, 0, .25, 1) infinite;
  }
  .qh2-walze__w b {
    position: absolute; inset: 0;
    display: grid; place-content: center start;
    font-weight: inherit;
    color: var(--md-akzent);
    white-space: nowrap;
    backface-visibility: hidden;
  }
  .qh2-walze__w b:nth-child(1) { transform: rotateX(0deg) translateZ(calc(var(--_h) / 2)); }
  .qh2-walze__w b:nth-child(2) { transform: rotateX(-90deg) translateZ(calc(var(--_h) / 2)); }
  .qh2-walze__w b:nth-child(3) { transform: rotateX(-180deg) translateZ(calc(var(--_h) / 2)); }
  .qh2-walze__w b:nth-child(4) { transform: rotateX(-270deg) translateZ(calc(var(--_h) / 2)); }
  .qh2-walze__w.b-10 { --_b: 5.6em; }
  .qh2-walze__w.b-12 { --_b: 6.6em; }
  .qh2-walze__w.b-14 { --_b: 7.6em; }
  .qh2-walze__w.b-16 { --_b: 8.6em; }
  .qh2-walze__w.b-20 { --_b: 10.6em; }
  @keyframes qh2-walzen {
    0%, 18%  { transform: rotateX(0deg); }
    25%, 43% { transform: rotateX(90deg); }
    50%, 68% { transform: rotateX(180deg); }
    75%, 93% { transform: rotateX(270deg); }
    100%     { transform: rotateX(360deg); }
  }

  /* Wendekarte: Frage vorn, Antwort hinten. Die Rueckseite ist
     aria-hidden - was nur dort steht, liest keine Vorlesesoftware.
     Deshalb steht die Antwort im Partial zusaetzlich als Untertitel. */
  .qh2-flip { perspective: 1200px; display: inline-block; max-width: none; }
  .qh2-flip__karte {
    position: relative;
    display: grid;
    transform-style: preserve-3d;
    transition: transform .75s cubic-bezier(.34, 1.15, .4, 1);
  }
  .qh2-flip:hover .qh2-flip__karte,
  .qh2-flip:focus-within .qh2-flip__karte { transform: rotateX(180deg); }
  .qh2-flip__karte > span { grid-area: 1 / 1; padding: .35em .6em; backface-visibility: hidden; }
  .qh2-flip__vorn { background: var(--md-flaeche-2); box-shadow: inset 3px 0 0 var(--md-marke); }
  .qh2-flip__hinten {
    transform: rotateX(180deg);
    background: linear-gradient(120deg, var(--orange), #A85A00);
    color: var(--md-auf-hell);
  }

  /* Leuchtrahmen: @property macht den Winkel animierbar */
  .qh2-rahmen {
    position: relative;
    display: inline-block;
    max-width: none;
    padding: .5em .85em;
    background: var(--md-flaeche-2);
  }
  .qh2-rahmen::before {
    content: "";
    position: absolute; inset: 0;
    padding: 2px;
    pointer-events: none;
    background: conic-gradient(from var(--qh2-winkel),
      transparent 0 62%, var(--orange) 74%, #fff 80%, var(--orange) 86%, transparent 94%);
    -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
            mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
    -webkit-mask-composite: xor;
            mask-composite: exclude;
    animation: qh2-umlauf 4.5s linear infinite;
  }
  @keyframes qh2-umlauf { to { --qh2-winkel: 360deg; } }

  /* ======================================================================
     TABELLEN - eine Klasse am <table> (Feld "Tabellenklasse")
     Template ContentElements/Table.html setzt qtb + qtb-<wert> und legt
     IMMER den Rollrahmen qtb-rollen darum (tabindex="0", role="region").
     ====================================================================== */
  .qtb-rollen {
    overflow: auto;
    overscroll-behavior-x: contain;
  }
  .qtb-rollen:focus-visible { outline: 3px solid var(--qn-fokus); outline-offset: 3px; }
  .qtb-rollen--hoch { max-height: 17.5rem; }
  .qtb { width: 100%; font-size: .98rem; line-height: 1.5; }
  .qtb-rollen > .qtb { min-width: 34rem; }
  .qtb caption {
    caption-side: top;
    text-align: left;
    padding: 0 0 .85em;
    font: 600 .72rem/1.4 var(--qn-schriftfamilie);
    letter-spacing: .2em;
    text-transform: uppercase;
    color: var(--md-kicker);
  }
  .qtb :is(th, td) { padding: .72em 1.05em; text-align: left; vertical-align: top; border-block-end: 1px solid var(--md-linie); }
  .qtb th { font-weight: 600; color: var(--md-stark); }
  .qtb thead th { font-size: .78em; letter-spacing: .14em; text-transform: uppercase; color: var(--qn-schrift-leise); }

  /* Linie: nur Horizontale, viel Luft - zum Lesen, nicht zum Ablesen */
  .qtb-linie :is(th, td) { padding: .95em 1.5em .95em 0; }
  .qtb-linie tr > :last-child { padding-right: 0; }
  .qtb-linie thead th { border-block-end: 2px solid var(--md-marke); }
  .qtb-linie tbody tr:last-child > * { border-block-end: 0; }

  /* Daten: Zahlen rechtsbuendig, Ziffern gleich breit */
  .qtb-daten { font-variant-numeric: tabular-nums lining-nums; }
  .qtb-daten :is(th, td):not(:first-child) { text-align: right; }
  .qtb-daten td:not(:first-child) { color: var(--md-stark); }
  .qtb-daten thead th { border-block-end: 2px solid var(--md-marke); }
  .qtb-daten tbody tr:last-child > * { border-block-end: 0; }
  .qtb-daten tfoot :is(th, td) {
    border-block-start: 2px solid var(--md-marke);
    border-block-end: 0;
    padding-top: .95em;
    font-weight: 600;
    color: var(--md-stark);
  }

  /* Fixkopf: Kopf und erste Spalte bleiben stehen. sticky gehoert ans
     <th>, der Hintergrund muss DECKEND sein, und collapse verbietet sich -
     zusammengefasste Rahmen scrollen weg. Linie deshalb als Schatten. */
  .qtb-fixkopf { border-collapse: separate; border-spacing: 0; }
  .qtb-fixkopf thead th {
    position: sticky; top: 0; z-index: 2;
    background: var(--md-deckend);
    box-shadow: inset 0 -2px 0 var(--md-marke);
  }
  .qtb-fixkopf tbody th {
    position: sticky; left: 0; z-index: 1;
    background: var(--md-deckend);
    box-shadow: inset -1px 0 0 var(--md-linie);
  }
  .qtb-fixkopf thead tr > :first-child { z-index: 3; left: 0; }

  /* Preisliste: zwei Spalten, punktierte Trennlinie */
  .qtb-preis :is(th, td) { padding: .9em 0; border-block-end: 1px dotted var(--md-linie-2); }
  .qtb-preis tr > :last-child {
    text-align: right;
    white-space: nowrap;
    font-weight: 600;
    color: var(--md-akzent);
    font-variant-numeric: tabular-nums;
  }
  .qtb-preis thead th { border-block-end: 2px solid var(--md-marke); }
  .qtb-preis tbody tr:last-child > * { border-block-end: 0; }
  .qtb-preis td small { display: block; margin-top: .25em; font-size: .84em; color: var(--qn-schrift-leise); }
  .qtb-preis.qtb { min-width: 0; }

  /* ======================================================================
     BLOCKFORMATE
     Einteilig (eine Klasse am <p>): zwischenruf, hinweis, warnung, erfolg.
     Mehrteilig aus dem Template: zitat (<blockquote>), aufklapper
     (<details>), fakten (<dl>).
     ====================================================================== */

  /* Zitat mit Markenquadrat. Im RTE als Blockzitat mit Klasse. */
  .qb-zitat {
    position: relative;
    margin: 0;
    padding: .15em 0 0 3.7em;
    font-size: 1.15rem;
    line-height: 1.6;
    color: var(--md-stark);
    max-width: 42rem;
  }
  .qb-zitat::before {
    content: "";
    position: absolute; left: 0; top: .35em;
    width: 2.35em; height: 2.35em;
    background: conic-gradient(var(--md-marke) 0 25%, var(--md-linie-2) 0 50%, var(--md-marke) 0 75%, var(--md-linie-2) 0);
  }
  .qb-zitat > p + p { margin-block-start: .8em; }
  .qb-zitat :is(footer, cite) {
    display: block;
    margin-top: .95em;
    font: 600 .74rem/1.4 var(--qn-schriftfamilie);
    letter-spacing: .18em;
    text-transform: uppercase;
    font-style: normal;
    color: var(--md-kicker);
  }

  /* Zwischenruf: der Satz, der herausbricht */
  /* Linien so breit wie der Text (Dirk, 21.10.2026): fit-content laesst den
     Kasten auf den Text schrumpfen, ein kurzes Wort bekommt kurze Linien.
     text-wrap:balance faellt dafuer weg - ausgewogene Zeilen machen den Text
     schmaler, der Kasten bliebe aber breit, und die Linien stuenden wieder
     ueber. pretty verhindert stattdessen ein einzelnes Wort in der letzten Zeile.
     Abstand fest in rem, nicht in em - sonst waechst er mit der grossen Schrift. */
  .frame .qb-zwischenruf {
    width: fit-content;
    max-width: min(100%, 30ch);
    margin-block: 2rem;
    padding: .55em 0 .45em;
    border-block: 2px solid var(--md-marke);
    font: 400 clamp(1.7rem, 4vw, 2.6rem)/1.02 var(--qn-schriftfamilie-ueberschrift);
    font-synthesis: none;
    text-transform: uppercase;
    letter-spacing: .015em;
    color: var(--md-stark);
    text-wrap: pretty;
  }

  /* Meldungen: ein Bauplan, drei Toene. Das Zeichen bekommt einen LEEREN
     Textersatz - die Bedeutung steht im Text ("Hinweis:"), nicht in der Farbe. */
  :is(.qb-hinweis, .qb-warnung, .qb-erfolg) {
    --_ton: var(--md-info);
    --_zeichen: "i";
    position: relative;
    padding: 1.05em 1.3em 1.05em 3.7em;
    background: var(--md-flaeche);
    box-shadow: inset 4px 0 0 var(--_ton), inset 0 0 0 1px var(--md-linie);
    max-width: 42rem;
  }
  :is(.qb-hinweis, .qb-warnung, .qb-erfolg)::before {
    content: var(--_zeichen) / "";
    position: absolute; left: 1.15em; top: 1.15em;
    width: 1.55em; height: 1.55em;
    display: grid; place-items: center;
    background: var(--_ton);
    color: var(--md-auf-ton);
    font: 600 .92em/1 var(--qn-schriftfamilie);
  }
  .qb-warnung { --_ton: var(--md-warn); --_zeichen: "!"; }
  .qb-erfolg  { --_ton: var(--md-ok);   --_zeichen: "\2713"; }
  /* Warnstreifen aus der Werkstatt - das Gelb ist die einzige Farbe
     ausserhalb der Marke. Signalfarben duerfen das. */
  .qb-warnung {
    padding-top: 1.5em;
    background:
      repeating-linear-gradient(45deg, rgba(242, 169, 59, .9) 0 9px, rgba(20, 26, 31, .9) 9px 18px) 0 0 / 100% 5px no-repeat,
      var(--md-flaeche);
  }
  .qb-warnung::before { top: 1.6em; }

  /* Aufklapper: Akkordeon ohne JavaScript. <details> mit gemeinsamem
     name schliesst die anderen - fuer FAQ-Listen bewusst OHNE name,
     damit man zwei Antworten nebeneinander offen halten kann. */
  .qb-aufklapper {
    max-width: 48rem;
    background: var(--md-flaeche);
    box-shadow: inset 0 0 0 1px var(--md-linie);
  }
  .qb-aufklapper + .qb-aufklapper { margin-block-start: .55em; }
  .qb-aufklapper > summary {
    list-style: none;
    cursor: pointer;
    position: relative;
    padding: .95em 3.4em .95em 1.25em;
    font-weight: 600;
    line-height: 1.4;
    color: var(--md-stark);
  }
  .qb-aufklapper > summary::-webkit-details-marker { display: none; }
  .qb-aufklapper > summary:hover { background: var(--md-flaeche); }
  .qb-aufklapper > summary:focus-visible { outline: 3px solid var(--qn-fokus); outline-offset: -3px; }
  .qb-aufklapper > summary::after {
    content: "";
    position: absolute; right: 1.25em; top: 50%;
    width: .78em; height: .78em;
    transform: translateY(-50%);
    background:
      linear-gradient(var(--md-marke) 0 0) 50% 50% / 100% 2px no-repeat,
      linear-gradient(var(--md-marke) 0 0) 50% 50% / 2px 100% no-repeat;
    transition: background-size .25s ease;
  }
  .qb-aufklapper[open] > summary::after { background-size: 100% 2px, 2px 0; }
  .qb-aufklapper__antwort { padding: .15em 1.25em 1.15em; }
  .qb-aufklapper__antwort > * + * { margin-block-start: .8em; }
  @supports (interpolate-size: allow-keywords) {
    .qb-aufklapper { interpolate-size: allow-keywords; }
    .qb-aufklapper::details-content {
      block-size: 0;
      overflow: hidden;
      transition: block-size .3s ease, content-visibility .3s allow-discrete;
    }
    .qb-aufklapper[open]::details-content { block-size: auto; }
  }

  /* Kennzahlen am <dl>: je Paar ein <div>. column-reverse stellt die Zahl
     nach oben, ohne die Reihenfolge im Quelltext zu drehen - <dt> steht
     vor <dd>, so liest es auch die Vorlesesoftware. */
  .qb-fakten {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(100%, 12rem), 1fr));
    gap: 10px;
    margin: 0;
  }
  .qb-fakten > div {
    display: flex;
    flex-direction: column-reverse;
    justify-content: flex-end;
    gap: .55em;
    padding: 1.3em 1.25em;
    background: var(--md-flaeche);
    box-shadow: inset 0 0 0 1px var(--md-linie);
  }
  .qb-fakten dt {
    margin: 0;
    font-size: .92rem;
    line-height: 1.5;
    color: var(--qn-schrift);
    max-width: none;
  }
  .qb-fakten dd {
    margin: 0;
    font: 400 clamp(2.2rem, 4.6vw, 3.1rem)/.95 var(--qn-schriftfamilie-ueberschrift);
    font-synthesis: none;
    letter-spacing: .01em;
    color: var(--md-akzent);
    font-variant-numeric: tabular-nums;
  }

  /* ======================================================================
     KARTEN - nur aus Fluid-Templates. Festes Innengeruest:
       .qk__bild  .qk__kicker  .qk__titel  .qk__text  .qk__fuss
     Der Link sitzt IM TITEL und deckt ueber ::after die ganze Karte ab.
     Ein Raster ist eine Liste: <ul class="qk-raster" role="list">.
     ====================================================================== */
  .qk-raster {
    display: grid;
    gap: 14px;
    grid-template-columns: repeat(auto-fit, minmax(min(100%, 17rem), 1fr));
    margin: 0;
    padding: 0;
    list-style: none;
    counter-reset: qk;
  }
  .qk-raster--breit { grid-template-columns: repeat(auto-fit, minmax(min(100%, 22rem), 1fr)); }
  .qk-raster--vier  { grid-template-columns: repeat(auto-fit, minmax(min(100%, 12.5rem), 1fr)); }
  .qk-raster > li { max-width: none; }
  .qk-raster > li + li { margin-block-start: 0; }

  /* Gleichlauf ueber subgrid - zum ANSCHALTEN, nicht Grundzustand.
     Bedingung: jede Karte hat gleich viele Zeilen (5 mit, 4 ohne Bild). */
  .qk-raster--gleichlauf { --qk-zeilen: 5; }
  .qk-raster--ohnebild   { --qk-zeilen: 4; }
  @supports (grid-template-rows: subgrid) {
    .qk-raster--gleichlauf > .qk { grid-row: span var(--qk-zeilen); grid-template-rows: subgrid; row-gap: 0; }
  }

  .qk {
    --qk-luft: 1.3rem;
    position: relative;
    display: grid;
    align-content: start;
    background: var(--md-flaeche);
    box-shadow: inset 0 0 0 1px var(--md-linie);
    transition: transform .28s ease, box-shadow .28s ease, background .28s ease;
  }
  .qk > * { margin: 0; }
  .qk > :last-child { padding-bottom: var(--qk-luft); }
  .qk__bild { display: block; width: 100%; aspect-ratio: 16 / 10; object-fit: cover; }
  .qk__kicker {
    padding: var(--qk-luft) var(--qk-luft) 0;
    font: 600 .7rem/1.3 var(--qn-schriftfamilie);
    letter-spacing: .2em;
    text-transform: uppercase;
    color: var(--md-kicker);
  }
  .qk__titel {
    padding: .5em var(--qk-luft) 0;
    font-size: clamp(1.3rem, 1.1rem + .8vw, 1.7rem);
    line-height: 1.05;
    color: var(--md-stark);
    text-wrap: balance;
  }
  .qk__titel a { color: inherit; text-decoration: none; }
  .qk__titel a::after { content: ""; position: absolute; inset: 0; }
  .qk__titel a:focus-visible { outline: none; }
  .qk__text {
    padding: .6em var(--qk-luft) 0;
    font-size: .95rem;
    line-height: 1.6;
    color: var(--qn-schrift);
  }
  .qk__fuss {
    padding: var(--qk-luft);
    align-self: end;
    font-size: .8rem;
    line-height: 1.45;
    color: var(--qn-schrift-leise);
  }
  /* Teile, die ueber der Klickflaeche liegen muessen (z. B. ein zweiter Link) */
  .qk__fuss a { position: relative; z-index: 1; }
  .qk:has(.qk__titel a):hover {
    background: var(--md-flaeche-2);
    transform: translateY(-3px);
    box-shadow: inset 0 0 0 1px rgb(255 136 0 / .55), var(--sch-blatt);
  }
  /* Fokus sichtbar an der KARTE, nicht an drei Woertern Titel */
  .qk:has(a:focus-visible) { outline: 3px solid var(--qn-fokus); outline-offset: 3px; }

  /* Tafel: Grundform mit abgesetzter Fusszeile */
  .qk-tafel .qk__fuss {
    margin: var(--qk-luft) var(--qk-luft) 0;
    padding: .8em 0 var(--qk-luft);
    border-top: 1px solid var(--md-linie);
  }

  /* Kachel: quadratisch, Nummer zaehlt sich selbst. Steht bewusst NICHT
     im subgrid-Gleichlauf - Seitenverhaeltnis und gemeinsame Zeilen
     schliessen sich aus. Auf schmalen Schirmen wird sie hoeher als breit,
     statt Text abzuschneiden. */
  .qk-kachel {
    min-height: 0;
    aspect-ratio: 1;
    align-content: end;
    background: var(--md-kachel);
    counter-increment: qk;
  }
  @supports not (aspect-ratio: 1) { .qk-kachel { min-height: 16rem; } }
  .qk-kachel::before {
    content: counter(qk, decimal-leading-zero);
    position: absolute; left: var(--qk-luft); top: calc(var(--qk-luft) - .1em);
    font: 600 .9rem/1 var(--qn-schriftfamilie);
    letter-spacing: .12em;
    color: var(--md-akzent);
  }
  .qk-kachel .qk__titel { hyphens: auto; }
  .qk-kachel > :first-child { padding-top: 3.2rem; }
  .qk-kachel .qk__fuss { padding-top: .8em; }
  .qk-kachel:has(.qk__titel a):hover { background: rgb(52 82 103 / .5); }
  .frame-m-paper .qk-kachel:has(.qk__titel a):hover { background: rgba(22, 36, 47, .1); }
  @media (max-width: 520px) { .qk-kachel { aspect-ratio: auto; } }

  /* Zeile: der waagerechte Teaser. Feste Rasterfelder - fehlt ein Teil,
     bleibt sein Feld leer, statt dass alles verrutscht. */
  .qk-zeile {
    grid-template-columns: minmax(0, 13rem) minmax(0, 1fr);
    grid-template-rows: auto auto 1fr auto;
    grid-template-areas: "bild kicker" "bild titel" "bild text" "bild fuss";
  }
  .qk-zeile:not(:has(.qk__bild)) { grid-template-columns: 0 minmax(0, 1fr); }
  .qk-zeile .qk__bild   { grid-area: bild; height: 100%; aspect-ratio: auto; }
  .qk-zeile .qk__kicker { grid-area: kicker; }
  .qk-zeile .qk__titel  { grid-area: titel; }
  .qk-zeile .qk__text   { grid-area: text; }
  .qk-zeile .qk__fuss   { grid-area: fuss; padding-top: .7em; }
  @media (max-width: 600px) {
    .qk-zeile {
      grid-template-columns: 1fr;
      grid-template-rows: auto auto auto 1fr auto;
      grid-template-areas: "bild" "kicker" "titel" "text" "fuss";
    }
    .qk-zeile .qk__bild { aspect-ratio: 16 / 9; }
  }

  /* Zahl: Ablauf in Schritten, Zahl als Wasserzeichen unten. Wasserzeichen
     brauchen pointer-events:none, sonst fangen sie den Klick der Karte. */
  .qk-zahl { counter-increment: qk; overflow: hidden; align-content: space-between; }
  .qk-zahl::before {
    content: counter(qk, decimal-leading-zero) / "";
    position: absolute; right: .04em; bottom: -.18em;
    pointer-events: none;
    font: 400 6rem/1 var(--qn-schriftfamilie-ueberschrift);
    color: rgb(255 136 0 / .16);
  }
  .qk-zahl .qk__fuss { padding-right: 3em; }

  /* ======================================================================
     BEWEGUNG REDUZIEREN - alles steht still, nichts verschwindet
     ====================================================================== */
  @media (prefers-reduced-motion: reduce) {
    .qp2-terminal::after { animation: none; }
    .qh-wuerfel__k { animation: none; }
    .qh-tor::before { transition: none; }
    .qh2-reihe__q > span,
    .qh2-walze__w > span,
    .qh2-rahmen::before { animation: none !important; }
    .qh2-flip__karte { transition: none; }
    .qb-aufklapper::details-content { transition: none; }
    .qk { transition: none; }
    .qk:hover { transform: none !important; }
  }
}

/* @property darf nicht in einer Ebene stehen - sie gilt dokumentweit. */
@property --qh2-winkel {
  syntax: "<angle>";
  initial-value: 0deg;
  inherits: false;
}
