/* Component vocabulary — Wave 2. design-system.md §4.3.
   Chrome (C1–C6, C12, C25 base) lives in chrome.css / buttons.css and is not duplicated here.
   Grown task by task (3.1 → 3.2 → 3.3); each component is labelled with its design-system id. */

@layer components {

  /* ===================================================================
     C6 · Page header `.page-header` — §4.2 C6
     Every page's title block: eyebrow → h1 → lede → optional meta row.
     The rhythm is `.flow`'s (the macro adds the class); only the slot
     spacing and the surface variants live here. The --deep state
     composes `.section--deep` rather than restating its surface rules.
     =================================================================== */

  .page-header {
    padding-block: var(--section-y-tight);
  }
  .page-header--plain {
    background: var(--paper);
  }
  .page-header--deep {
    padding-block: var(--section-y);
  }
  .page-header__meta {
    font-size: var(--fs-sm);
    color: var(--ink-muted);
    max-width: var(--measure-lede);
  }
  .page-header--deep .page-header__meta {
    color: var(--on-deep-muted);
  }
  /* Titelblock und erste Sektion tragen beide ihren vollen Bandabstand. Wechselt
     dazwischen die Fläche (paper/tint/cool/deep), ist das richtig — der doppelte
     Abstand trennt dann zwei sichtbare Bänder. Bleibt die Fläche gleich, addieren
     sich die beiden Polster zu bis zu 152 px leerem Weiß, deutlich mehr als jeder
     andere Abstand der Seite. Dort trägt der Titelblock den Abstand allein. */
  .page-header + .section:not(.section--paper):not(.section--tint):not(.section--cool):not(.section--deep) {
    padding-block-start: 0;
  }

  /* ===================================================================
     C7 · Hero — three variants — §4.2 C7
     =================================================================== */

  /* <picture> is a layout no-op here. base.css resets it to `height: auto`, so
     without this the `height: 100%` below resolves against an auto-height parent
     and the photo silently stops filling its aspect-ratio box — it keeps its own
     ratio and leaves a gap. Applies to every media block with a crop box. */
  .hero__media picture,
  .kurs-card__media picture {
    display: contents;
  }

  .hero__media {
    position: relative;
    margin-inline: calc(50% - 50vw);
    aspect-ratio: var(--ar-band);
    overflow: hidden;
  }
  .hero__media img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    object-position: var(--focal, 50% 62%);
    border-radius: var(--radius-photo);
  }
  @media (min-width: 45rem) {
    .hero__media {
      margin-inline: auto;
      max-width: min(100%, var(--nat, var(--photo-max)));
      box-shadow: var(--photo-frame);
    }
  }

  /* Solid caption bar, flush against the photo's bottom edge. Never a gradient. */
  .hero__unterschrift {
    position: absolute;
    inset-inline: 0;
    inset-block-end: 0;
    margin: 0;
    background: var(--deep);
    color: var(--on-deep);
    padding: var(--space-2) var(--space-4);
    font-size: var(--fs-2xs);
    font-weight: var(--fw-bold);
    letter-spacing: var(--ls-caps);
    text-transform: uppercase;
  }

  .hero--band {
    padding-block-start: var(--space-5);
  }

  .hero--plain {
    background: var(--paper);
    padding-block: var(--section-y-tight);
  }

  /* ===================================================================
     C8 · kursfakten (design-system's .steckbrief) — §4.3 C8
     =================================================================== */

  .kursfakten {
    background: var(--brand-wash);
    border-inline-start: var(--border-accent) solid var(--brand);
    padding: var(--space-5);
  }

  .kursfakten__liste {
    margin-block-start: var(--space-2);
  }
  .kursfakten__zeile {
    padding-block: var(--space-3);
    border-block-end: 1px solid var(--rule);
  }
  .kursfakten__zeile:last-child {
    border-block-end: 0;
  }
  .kursfakten__zeile dt {
    font-size: var(--fs-2xs);
    font-weight: var(--fw-bold);
    letter-spacing: var(--ls-caps);
    text-transform: uppercase;
    color: var(--brand-ink);
  }
  .kursfakten__zeile dd {
    margin-inline-start: 0;
    margin-block-start: var(--space-1);
    color: var(--ink);
  }
  /* Der Faktenkasten steht auf /weiterbildung/ mitten in einem .prose-Block.
     Dessen Listenregel (base.css) würde hier disc-Marker und einen Einzug
     ergänzen — zusammen mit dem eigenen "– " wären das zwei Marker. Die
     Komponente setzt ihre Marker selbst, also hier explizit abbestellen.
     @layer components gewinnt gegen @layer base, unabhängig von Spezifität. */
  .kursfakten__zeile dd ul {
    margin-block-start: var(--space-1);
    list-style: none;
    padding-inline-start: 0;
  }
  .kursfakten__zeile dd li {
    padding-block: var(--space-1);
  }
  .kursfakten__zeile dd li::before {
    content: "– ";
  }
  .kursfakten__zusatz {
    display: inline-block;
    margin-block-start: var(--space-1);
    font-size: var(--fs-xs);
    color: var(--ink-muted);
  }
  .kursfakten__weitere {
    color: var(--ink-muted);
    font-size: var(--fs-xs);
  }

  @media (min-width: 45rem) {
    .kursfakten__zeile {
      display: grid;
      grid-template-columns: minmax(11rem, 14rem) minmax(0, 1fr);
      gap: var(--space-4);
      align-items: baseline;
    }
    .kursfakten__zeile dd {
      margin-block-start: 0;
    }
  }

  .kursfakten__aktionen {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-3);
    margin-block-start: var(--space-5);
  }

  /* Der Kursauftakt: Faktenkasten und Ausbildungsweg unter dem Bandhero. Zwei
     eigenständige Blöcke, die mehr als den Absatzabstand von `.flow` brauchen. */
  .kursblock {
    --flow: var(--space-7);
  }

  /* ===================================================================
     C9 · Course card `.kurs-card` — §4.3 C9
     =================================================================== */

  /* §4.3 C9 Responsive — 1 col, 2 from --bp-sm, 3 from --bp-lg. One rule, no
     breakpoints: auto-fit does the counting. */
  .kurs-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(17rem, 1fr));
    gap: var(--space-5);
    align-items: stretch;
  }

  .kurs-card {
    position: relative;
    isolation: isolate;
    display: flex;
    flex-direction: column;
    background: var(--surface);
    border: var(--border-hair);
    transition: box-shadow var(--dur-base) var(--ease);
  }
  .kurs-card:hover {
    box-shadow: var(--shadow-md);
  }
  .kurs-card:has(a:focus-visible) {
    outline: var(--focus-width) solid var(--focus);
    outline-offset: var(--focus-offset);
  }
  .kurs-card__titel a:focus-visible {
    outline: none;
  }

  .kurs-card__media {
    aspect-ratio: var(--ar-photo);
    overflow: hidden;
    /* §6.1 rule 1 — never wider than the source. The cap has to land on the
       aspect-ratio box, not the img: object-fit would otherwise just crop
       inside an oversized box. --nat comes from the macro. */
    max-width: min(100%, var(--nat, var(--photo-max)));
  }
  .kurs-card__media img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    object-position: var(--focal, 50% 55%);
    transition: transform var(--dur-base) var(--ease);
  }
  .kurs-card:hover .kurs-card__media img {
    transform: scale(1.03);
  }

  .kurs-card__body {
    padding: var(--space-4);
    flex-grow: 1;
  }
  .kurs-card__titel {
    font-size: var(--fs-lg);
    margin-block: var(--space-2) 0;
  }
  .kurs-card__titel a {
    text-decoration: none;
    color: inherit;
  }
  .kurs-card__titel a::after {
    content: "";
    position: absolute;
    inset: 0;
  }
  .kurs-card:hover .kurs-card__titel a {
    text-decoration: underline;
  }
  .kurs-card__text {
    margin-block-start: var(--space-2);
    font-size: var(--fs-sm);
    color: var(--ink-muted);
    display: -webkit-box;
    -webkit-line-clamp: 3;
    -webkit-box-orient: vertical;
    overflow: hidden;
  }

  .kurs-card__fuss {
    display: flex;
    flex-wrap: wrap;
    justify-content: space-between;
    gap: var(--space-2);
    padding: var(--space-3) var(--space-4);
    border-block-start: var(--border-hair);
    font-size: var(--fs-xs);
  }
  .kurs-card__meta {
    font-variant-numeric: tabular-nums;
    font-feature-settings: "tnum" 1;
    break-inside: avoid;
  }
  .kurs-card__termin {
    color: var(--ink-muted);
  }

  .kurs-card--featured {
    background: var(--deep);
    color: var(--on-deep);
    border-color: var(--rule-on-deep);
  }
  .kurs-card--featured .kurs-card__titel a {
    color: var(--brand);
  }
  .kurs-card--featured .kurs-card__text {
    color: var(--on-deep-muted);
  }
  .kurs-card--featured .kurs-card__fuss {
    border-block-start-color: var(--rule-on-deep);
  }
  .kurs-card--featured .kurs-card__termin {
    color: var(--on-deep-muted);
  }

  /* ===================================================================
     C10 · Termin-Tabelle `.termine` — §4.3 C10
     =================================================================== */

  .termine__zeile {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: var(--space-1) var(--space-3);
    min-height: var(--tap);
    padding-block: var(--space-2);
    border-block-end: 1px solid var(--rule);
    font-variant-numeric: tabular-nums;
    font-feature-settings: "tnum" 1;
  }
  .termine__zeile:last-child {
    border-block-end: 0;
  }
  .termine__kurs {
    flex-basis: 100%;
    font-weight: var(--fw-medium);
    color: var(--ink);
    text-decoration: none;
  }
  .termine__kurs:hover {
    color: var(--brand-ink);
    text-decoration: underline;
  }
  .termine__datum {
    min-width: 13ch;
    font-weight: var(--fw-semi);
  }
  .termine__notiz {
    color: var(--ink-muted);
    font-size: var(--fs-sm);
  }
  .termine__ausweich {
    flex-basis: 100%;
    font-size: var(--fs-xs);
    color: var(--ink-muted);
  }
  .termine__leer {
    color: var(--ink-muted);
    font-style: italic;
  }
  .termine__zeile:has(.status--voll) .termine__datum {
    text-decoration: line-through;
  }

  /* §4.3 C10 Responsive — a 15-row list reads as a timetable, not a scroll.
     Only on `.termine--spalten` (date-only rows): a row carrying a course name
     is too wide for a column and wraps into nonsense. See termine.njk. */
  @media (min-width: 45rem) {
    .termine--spalten {
      columns: 2;
      column-gap: var(--space-6);
    }
    .termine__kurs {
      flex-basis: auto;
      min-width: 12rem;
    }
    .termine__ausweich {
      flex-basis: auto;
      margin-inline-start: auto;
    }
  }
  @media (min-width: 75rem) {
    .termine--spalten {
      columns: 3;
    }
  }

  /* ===================================================================
     C11 · Preisblock `.preise` — §4.3 C11
     =================================================================== */

  .preise__zeile {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: var(--space-2);
    padding-block: var(--space-2);
    border-block-end: 1px solid var(--rule);
  }
  .preise__zeile:last-of-type {
    border-block-end: 0;
  }
  .preise__label {
    flex: 1 1 auto;
    color: var(--ink);
  }
  .preise__hinweis {
    color: var(--ink-muted);
    font-size: var(--fs-xs);
  }
  .preise__betrag {
    margin-inline-start: auto;
    font-size: var(--fs-lg);
    font-weight: var(--fw-bold);
    letter-spacing: var(--ls-tight);
    font-variant-numeric: tabular-nums;
    font-feature-settings: "tnum" 1;
    white-space: nowrap;
  }
  .preise__erm {
    font-size: var(--fs-sm);
    font-weight: var(--fw-regular);
    color: var(--ink-muted);
  }
  .preise__zeile--gesamt {
    border-block-start: 1px solid var(--rule-strong);
    margin-block-start: var(--space-1);
    padding-block-start: var(--space-3);
  }
  .preise__zeile--gesamt .preise__label,
  .preise__zeile--gesamt .preise__betrag {
    color: var(--brand-ink);
  }
  .preise__zusatz {
    padding-block-start: var(--space-2);
    font-size: var(--fs-xs);
    color: var(--ink-muted);
  }

  @media (min-width: 30rem) {
    .preise__label {
      display: flex;
      align-items: baseline;
      gap: var(--space-2);
    }
    .preise__label::after {
      content: "";
      flex: 1 1 auto;
      border-block-end: 1px dotted var(--rule);
      margin-inline: var(--space-2);
      align-self: end;
      margin-block-end: 0.35em;
    }
  }

  /* ===================================================================
     C14 · Tag / level pill `.tag` — §4.3 C14
     =================================================================== */

  .tag {
    display: inline-flex;
    align-items: center;
    padding: var(--space-1) var(--space-2);
    border-radius: var(--radius-pill);
    background: var(--brand-wash);
    color: var(--brand-ink);
    font-size: var(--fs-3xs);
    font-weight: var(--fw-bold);
    letter-spacing: var(--ls-caps);
    text-transform: uppercase;
  }
  .section--deep .tag,
  .kurs-card--featured .tag {
    background: var(--deep-raised);
    color: var(--brand);
  }

  /* ===================================================================
     C15 · Status pill `.status` — §4.3 C15
     =================================================================== */

  .status {
    display: inline-flex;
    align-items: center;
    padding: var(--space-1) var(--space-2);
    border-radius: var(--radius-pill);
    font-size: var(--fs-3xs);
    font-weight: var(--fw-bold);
    letter-spacing: var(--ls-caps);
    text-transform: uppercase;
  }
  .status--frei {
    background: var(--state-ok-fill);
    color: var(--state-ok);
  }
  .status--voll {
    background: var(--state-full-fill);
    color: var(--state-full);
  }
  .status--anfrage {
    background: var(--cool-tint);
    color: var(--ink-muted);
  }

  /* ===================================================================
     C18 · Callout `.hinweis` — §4.3 C18
     =================================================================== */

  .hinweis {
    border-inline-start: var(--border-accent) solid;
    padding: var(--space-4) var(--space-5);
  }
  .hinweis__inhalt > :first-child { margin-block-start: 0; }
  .hinweis__inhalt > :last-child { margin-block-end: 0; }
  .hinweis__inhalt > * + * { margin-block-start: var(--space-3); }

  .hinweis--info {
    background: var(--cool-tint);
    border-inline-start-color: var(--ink);
  }
  .hinweis--brand {
    background: var(--brand-wash);
    border-inline-start-color: var(--brand);
  }
  .hinweis--wichtig {
    background: var(--state-full-fill);
    border-inline-start-color: var(--state-full);
  }

  @media (max-width: 30rem) {
    .hinweis {
      margin-inline: calc(-1 * var(--gutter));
      border-radius: 0;
    }
  }

  /* ===================================================================
     C22 · Ausbildungsweg stepper `.weg` — §4.3 C22
     =================================================================== */

  .weg__liste {
    display: flex;
    flex-direction: column;
    gap: var(--space-5);
    border-inline-start: 2px solid var(--rule-strong);
    padding-inline-start: var(--space-5);
  }
  .weg__schritt {
    position: relative;
    display: flex;
    align-items: flex-start;
    gap: var(--space-3);
  }
  .weg__nummer {
    position: absolute;
    inset-inline-start: calc(-1 * var(--space-5) - 0.85rem);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 1.7rem;
    height: 1.7rem;
    border-radius: 50%;
    background: var(--brand);
    color: var(--ink);
    font-weight: var(--fw-bold);
    font-size: var(--fs-sm);
    flex-shrink: 0;
  }
  .weg__schritt--aktuell .weg__nummer {
    background: var(--deep);
    color: var(--on-deep);
  }
  .weg__inhalt {
    display: flex;
    flex-direction: column;
    gap: var(--space-1);
  }
  .weg__titel {
    font-weight: var(--fw-semi);
    color: var(--ink);
    text-decoration: none;
  }
  a.weg__titel:hover {
    color: var(--brand-ink);
    text-decoration: underline;
  }
  .weg__meta {
    font-size: var(--fs-xs);
    color: var(--ink-muted);
    font-variant-numeric: tabular-nums;
    font-feature-settings: "tnum" 1;
  }

  @media (min-width: 45rem) {
    .weg__liste {
      flex-direction: row;
      border-inline-start: 0;
      border-block-start: 2px solid var(--rule-strong);
      padding-inline-start: 0;
      padding-block-start: var(--space-5);
      gap: var(--space-6);
    }
    .weg__schritt {
      flex: 1 1 0;
      flex-direction: column;
    }
    .weg__nummer {
      position: absolute;
      inset-block-start: calc(-1 * var(--space-5) - 0.85rem);
      inset-inline-start: 0;
    }
  }

  /* ===================================================================
     `.vorteile` — the four short claims ("Warum bei uns", ux-ia.md §4.1 block 5).
     Not a numbered design-system component: §4.3 has none for a list of
     arguments, and letting each page invent its own markup is exactly the
     duplication v2 removes. Reused by the course pages in wave 4.
     =================================================================== */

  /* Four claims want 2x2, not auto-fit: auto-fit lands on three columns at
     --container width and orphans the fourth. */
  .vorteile {
    display: grid;
    gap: var(--space-4) var(--space-6);
  }
  @media (min-width: 45rem) {
    .vorteile {
      grid-template-columns: 1fr 1fr;
    }
  }
  .vorteile li {
    padding-inline-start: var(--space-4);
    border-inline-start: var(--border-accent) solid var(--brand);
    line-height: var(--lh-snug);
  }
  .vorteile strong {
    display: block;
    font-weight: var(--fw-semi);
  }
  .vorteile span {
    color: var(--ink-muted);
    font-size: var(--fs-sm);
  }
  .section--deep .vorteile span {
    color: var(--on-deep-muted);
  }

  /* ===================================================================
     `.uebersicht` — the comparison table at the top of /weiterbildung/
     (ux-ia.md §4.4 block 3). It is a table of contents as much as a table:
     every course name is an anchor into its own section below. Scrolls
     inside its own container on mobile and re-flows to stacked definition
     blocks below 600px, where five columns cannot survive.
     =================================================================== */

  .uebersicht-scroll {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
  }
  .uebersicht {
    inline-size: 100%;
    border-collapse: collapse;
    line-height: var(--lh-snug);
    text-align: start;
  }
  .uebersicht th,
  .uebersicht td {
    padding: var(--space-2) var(--space-3);
    border-block-end: var(--border-hair);
    text-align: start;
    vertical-align: top;
  }
  .uebersicht thead th {
    border-block-end-color: var(--rule-strong);
    font-size: var(--fs-sm);
    font-weight: var(--fw-semi);
    color: var(--ink-muted);
    white-space: nowrap;
  }
  .uebersicht tbody th {
    font-weight: var(--fw-semi);
  }
  .uebersicht__preis {
    white-space: nowrap;
  }

  /* /termine/ renders one table per month. Left to themselves they size their
     columns independently and the months no longer line up as one calendar,
     which is the whole point of the page. Fixed widths make them one grid.
     Vier Spalten seit dem Wegfall der Anmelden-Spalte: Datum · Kurs · Dauer ·
     Preis, wobei Dauer (3) den Rest bekommt. */
  @media (min-width: 37.5rem) {
    .uebersicht--kalender {
      table-layout: fixed;
    }
    .uebersicht--kalender th:nth-child(1) { inline-size: 15rem; }
    .uebersicht--kalender th:nth-child(2) { inline-size: 11rem; }
    .uebersicht--kalender th:nth-child(4) { inline-size: 8rem; }
  }

  /* Die Notizen unter dem Datum — Feiertag, "Kurs läuft bereits",
     Ausweichtermin — sind eigene Zeilen, keine Fortsetzung des Datums.
     Vorher stimmte das nur zufällig: die Spans sind inline und brachen bloß
     deshalb um, weil "Allerheiligen" neben einem 15rem breiten Datum keinen
     Platz mehr fand. Der kürzere Statushinweis fand ihn und las sich als
     "18.09.–04.10.2026 Kurs läuft bereits" (Daniel, 17.09.2026). */
  .uebersicht--kalender .termine__notiz,
  .uebersicht--kalender .termine__ausweich {
    display: block;
  }

  /* Ohne diese Regel klebt die Überschrift des nächsten Monats direkt auf der
     Unterkante der vorigen Tabelle: .termin-liste ist kein .flow, und die
     .termin-monat-Kästen bringen selbst keinen Außenabstand mit — ihr eigenes
     .flow greift erst zwischen h3 und Tabelle, nicht davor (Daniel, 17.09.2026).
     var(--space-7) ist derselbe Abstand, den .flow einer h2 gibt: die Monate
     sind auf dieser Seite die Gliederungsebene. */
  .termin-monat + .termin-monat {
    margin-block-start: var(--space-7);
  }

  /* Below 600px the grid stops being a grid: each row becomes its own block
     and every cell carries its column name from `data-label`. */
  @media (max-width: 37.4375rem) {
    .uebersicht thead {
      position: absolute;
      inline-size: 1px;
      block-size: 1px;
      overflow: hidden;
      clip-path: inset(50%);
      white-space: nowrap;
    }
    .uebersicht tr {
      display: block;
      padding-block: var(--space-3);
      border-block-end: 1px solid var(--rule-strong);
    }
    .uebersicht th,
    .uebersicht td {
      display: block;
      padding-inline: 0;
      border-block-end: 0;
    }
    .uebersicht td::before {
      content: attr(data-label) ": ";
      color: var(--ink-muted);
      font-size: var(--fs-sm);
    }
    .uebersicht tbody th {
      font-size: var(--fs-md);
      padding-block-end: var(--space-1);
    }
  }

  /* ===================================================================
     `.sprungliste` and `.faq__eintrag` — /faq/ (ux-ia.md §4.9). Deliberately
     no accordion: an accordion hides text from Ctrl-F and from search
     engines, and twenty-odd entries do not need one. A jump list at the top
     is the whole navigation.
     =================================================================== */

  .sprungliste {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-2);
  }
  .faq__eintrag + .faq__eintrag {
    margin-block-start: var(--space-5);
    padding-block-start: var(--space-5);
    border-block-start: var(--border-hair);
  }
  /* The anchor target must not land under the header when it is jumped to. */
  .faq__eintrag h3 {
    scroll-margin-block-start: var(--space-5);
  }

  /* ===================================================================
     `.team-grid` and `.urkunden` — the two photo grids on /flugschule/.
     Both are `.plate` layouts, not new components: the plate does the mat
     and the caption, these only do the counting. `.urkunden` deliberately
     keeps the certificates small — four full-page scans is a museum, one
     row of thumbnails is evidence (ux-ia.md §7).
     =================================================================== */

  .team-grid,
  .urkunden {
    display: grid;
    gap: var(--space-4);
    list-style: none;
  }
  /* Die Portraits sind 300 px breit — mehr gibt es nicht. Die Spalte muss also
     mindestens so breit sein, sonst rendert ein 300er Foto bei 131 px und sieht
     schlicht kaputt aus. 19rem Mindestbreite ergibt drei Spalten im Container
     und lässt jedes Foto seine native Größe erreichen. */
  .team-grid {
    grid-template-columns: repeat(auto-fit, minmax(19rem, 1fr));
  }
  .urkunden {
    grid-template-columns: repeat(auto-fit, minmax(9rem, 1fr));
  }
  .team-grid figure,
  .urkunden figure {
    margin: 0;
  }
  /* Innerhalb der Raster trägt die Fläche schon das Raster selbst: die großzügige
     Passepartout-Polsterung von `.plate--klein` (48/32 px) fräße hier bis zu 40 %
     der Spaltenbreite weg. */
  .team-grid .plate--klein,
  .urkunden .plate--klein {
    padding: var(--space-3);
    margin-block: 0;
  }
  .team-grid .plate img {
    width: 100%;
  }

  /* ===================================================================
     `.termin-filter` — the /termine/ filter chips (ux-ia.md §4.5 block 2).
     Radio inputs plus `:has()`, so there is no JavaScript to fail and no
     "show all" fallback to build: with `:has()` unsupported every row simply
     stays visible, which is the fallback. The inputs are visually hidden but
     focusable — the label is the chip.
     =================================================================== */

  .termin-filter {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-2);
    border: 0;
    padding: 0;
    margin-block-end: var(--space-4);
  }
  .termin-filter input {
    position: absolute;
    inline-size: 1px;
    block-size: 1px;
    opacity: 0;
  }
  .termin-filter label {
    display: inline-flex;
    align-items: center;
    min-block-size: var(--tap);
    padding-inline: var(--space-3);
    border: 1px solid var(--rule-strong);
    border-radius: var(--radius-pill);
    color: var(--ink);
    font-size: var(--fs-sm);
    font-weight: var(--fw-medium);
    cursor: pointer;
  }
  .termin-filter label:hover {
    border-color: var(--brand-ink);
    color: var(--brand-ink);
  }
  .termin-filter input:checked + label {
    background: var(--deep);
    border-color: var(--deep);
    color: var(--on-deep);
  }
  .termin-filter input:focus-visible + label {
    outline: var(--focus-width) solid var(--focus);
    outline-offset: var(--focus-offset);
  }

  /* One rule per chip. The filter and the table are siblings inside
     `.termin-liste`, which is what makes the `:has()` selector reachable. */
  .termin-liste:has(#filter-einstieg:checked) tr[data-level]:not([data-level="einstieg"]),
  .termin-liste:has(#filter-lizenz:checked) tr[data-level]:not([data-level="lizenz"]),
  .termin-liste:has(#filter-weiterbildung:checked) tr[data-level]:not([data-level="weiterbildung"]) {
    display: none;
  }
  /* A month whose every row is filtered out would otherwise leave a heading
     standing over an empty table. */
  .termin-liste:has(#filter-einstieg:checked) .termin-monat:not(:has(tr[data-level="einstieg"])),
  .termin-liste:has(#filter-lizenz:checked) .termin-monat:not(:has(tr[data-level="lizenz"])),
  .termin-liste:has(#filter-weiterbildung:checked) .termin-monat:not(:has(tr[data-level="weiterbildung"])) {
    display: none;
  }

  /* ===================================================================
     `.ablauf` — the day-by-day narrative on a course page (ux-ia.md §4.2
     block 7: "a short ordered list with prose under each item, not one wall
     of text"). Like `.vorteile`, not a numbered design-system component:
     §4.3 has no list-with-prose, and letting each course page invent its own
     is the duplication v2 removes. Reuses the `.weg` numeral vocabulary so
     the two numbered things on a course page look related.
     =================================================================== */

  .ablauf {
    list-style: none;
    /* The numerals are drawn by ::before, so undo the prose list indent that
       base.css adds to every ol inside a .prose block. */
    padding-inline-start: 0;
    counter-reset: ablauf;
    display: grid;
    gap: var(--space-4);
  }
  .ablauf li {
    counter-increment: ablauf;
    position: relative;
    padding-inline-start: calc(var(--space-6) + var(--space-2));
    line-height: var(--lh-snug);
  }
  .ablauf li::before {
    content: counter(ablauf);
    position: absolute;
    inset-inline-start: 0;
    inset-block-start: 0;
    display: grid;
    place-items: center;
    inline-size: var(--space-6);
    block-size: var(--space-6);
    border-radius: 50%;
    background: var(--brand);
    color: var(--ink);           /* --ink on --brand is 6.97:1 — see tokens.css */
    font-size: var(--fs-sm);
    font-weight: var(--fw-semi);
    font-variant-numeric: tabular-nums;
  }
  .section--deep .ablauf li::before {
    background: var(--deep-raised, var(--deep));
    color: var(--on-deep);
  }
  .ablauf strong {
    display: block;
    font-weight: var(--fw-semi);
  }

  /* ===================================================================
     C27 · Section band `.section` — §4.3 C27
     =================================================================== */

  .section {
    padding-block: var(--section-y);
  }
  .section--tight {
    padding-block: var(--section-y-tight);
  }
  .section--paper {
    background: var(--paper);
  }
  .section--tint {
    background: var(--brand-tint);
  }
  .section--cool {
    background: var(--cool-tint);
  }
  .section--deep {
    background: var(--deep);
    color: var(--on-deep);
  }
  .section--deep h1,
  .section--deep h2,
  .section--deep h3,
  .section--deep h4 {
    color: var(--on-deep);
  }
  .section--deep a:not(.btn) {
    color: var(--brand);
  }
  .section--deep .lede {
    color: var(--on-deep-muted);
  }

  /* ===================================================================
     C19 · Figure / plate `.plate` — §4.3 C19, §6.3
     =================================================================== */

  .plate img {
    max-width: min(100%, var(--nat, var(--photo-max)));
    height: auto;
    box-shadow: var(--photo-frame);
    border-radius: var(--radius-photo);
  }
  .plate figcaption {
    margin-block-start: var(--space-2);
    font-size: var(--fs-xs);
    color: var(--ink-muted);
  }

  .plate--klein {
    display: grid;
    justify-items: center;
    background: var(--cool-tint);
    padding: var(--space-6) var(--space-5);
    margin-block: var(--section-y-tight);
  }
  .plate--klein figcaption {
    max-width: var(--measure-lede);
    text-align: center;
  }

  .plate--doc {
    display: grid;
    justify-items: center;
    background: var(--cool-tint);
    padding: var(--space-4);
  }
  /* `max-width: 200px` allein hat das `min(100%, …)` aus `.plate img` überschrieben
     (gleiche Spezifität, spätere Regel) — die Urkunde kannte danach die Breite
     ihrer Matte nicht mehr und stand auf /flugschule/ über deren Rand hinaus im
     Nachbarfeld. Und weil `width: auto` bei einer 150-px-Quelle 150 px und bei
     einer 629-px-Quelle die 200-px-Deckelung ergab, war außerdem jede Urkunde
     anders groß. Beides behebt eine Breite, die immer die Matte füllt: gleich
     große Kästen, gleiche Höhe über --ar-doc, Bildunterschriften auf einer Linie.
     `contain` lässt den Scan darin unbeschnitten. */
  .plate--doc img {
    aspect-ratio: var(--ar-doc);
    width: 100%;
    max-width: min(100%, 200px);
    height: auto;
    object-fit: contain;
    background: var(--surface);
  }

  .plate__zoom {
    display: block;
    transition: box-shadow var(--dur-base) var(--ease);
  }
  /* Der Link ist ein Block und im zentrierten Raster damit fit-content breit —
     das ist die Eigenbreite der Quelle (554 px bei der Urkunde 2023), nicht die
     des gedeckelten Bildes (200 px). Die Urkunde saß deshalb am linken Rand
     ihres eigenen Links statt in der Mitte der Matte. `justify-items` greift
     hier nicht: zentriert wird der Link, nicht sein Inhalt, und `img`/`picture`
     sind laut base.css Blöcke, also hilft auch `text-align` nicht. */
  .plate--doc .plate__zoom {
    width: 100%;
  }
  .plate--doc picture,
  .plate--doc img {
    margin-inline: auto;
  }
  .plate__zoom:hover {
    box-shadow: var(--shadow-sm);
  }

  /* ===================================================================
     C21 · Video facade `.video` — §4.3 C21
     =================================================================== */

  .video {
    max-width: 640px;
  }
  /* The pre-click data-protection notice. Small, but never hidden and never
     below the fold of the component — the click above it is only informed
     consent if this has been readable first. */
  .video__hinweis {
    margin-block-start: var(--space-2);
    font-size: var(--fs-xs);
    line-height: var(--lh-snug);
    color: var(--ink-muted);
  }
  .section--deep .video__hinweis {
    color: var(--on-deep-muted);
  }
  .video__facade {
    position: relative;
    display: block;
  }
  .video__facade img {
    width: 100%;
    height: auto;
  }
  .video__play {
    position: absolute;
    inset: 0;
    margin: auto;
    width: 4rem;
    height: 4rem;
    border-radius: 50%;
    background: var(--brand);
    display: flex;
    align-items: center;
    justify-content: center;
    transition: background-color var(--dur-base) var(--ease),
                transform var(--dur-base) var(--ease);
  }
  .video__play::before {
    content: "";
    width: 0;
    height: 0;
    border-style: solid;
    border-width: 0.85rem 0 0.85rem 1.4rem;
    border-color: transparent transparent transparent var(--ink);
    margin-inline-start: 0.3rem;
  }
  .video__facade:hover .video__play {
    background: var(--brand-fill-alt);
    transform: scale(1.06);
  }
  .video__facade:focus-visible {
    outline: var(--focus-width) solid var(--focus);
    outline-offset: var(--focus-offset);
  }
  .video iframe {
    width: 100%;
    aspect-ratio: 640 / 300;
    border: 0;
  }
  .video__caption {
    margin-block-start: var(--space-2);
    font-size: var(--fs-xs);
    color: var(--ink-muted);
  }
  /* Both videos on the site sit on a --deep band, where --ink-muted (#5C5C5C)
     is effectively invisible. The sibling .video__hinweis already flips; the
     caption never did, because until now nothing rendered it there. */
  .section--deep .video__caption {
    color: var(--on-deep-muted);
  }
  @media (prefers-reduced-motion: reduce) {
    .video__facade:hover .video__play { transform: none; }
  }
}
