%<*driver>
\def\nameofplainTeX{plain}
\ifx\fmtname\nameofplainTeX
\input l3docstrip.tex
\keepsilent
\askforoverwritefalse
\preamble

========================================================================
 ltxtalk-theme - themes for ltxtalk

 (C) 2026 Matthias Werner
 E-mail: matthias.werner@informatik.tu-chemnitz.de

 Released under the LaTeX Project Public License v1.3c or later
 See http://www.latex-project.org/lppl.txt
======================================================================== 

\endpreamble
\postamble

 This work is "maintained" (as per LPPL maintenance status) by
 Matthias Werner.
\endpostamble

\generate{
  \file{ltxtalk-theme.sty}{\from{lttheme.dtx}{pkg}}
  \file{ltxtalk-theme-minimal.sty}{\from{lttheme.dtx}{minimal}}
  \file{ltxtalk-theme-magpie.sty}{\from{lttheme.dtx}{magpie}}
  \file{ltxtalk-theme-hawk.sty}{\from{lttheme.dtx}{hawk}}
  \file{ltxtalk-theme-sparrow.sty}{\from{lttheme.dtx}{sparrow}}
  \file{ltxtalk-theme-bluebird.sty}{\from{lttheme.dtx}{bluebird}}
  \file{ltxtalk-theme-goose.sty}{\from{lttheme.dtx}{goose}}
  \file{ltxtalk-theme-anchovy.sty}{\from{lttheme.dtx}{anchovy}}
  \file{ltxtalk-theme-carp.sty}{\from{lttheme.dtx}{carp}}
  \file{ltxtalk-theme-font-sans.sty}{\from{lttheme.dtx}{font-sans}}
  \file{ltxtalk-theme-font-serif.sty}{\from{lttheme.dtx}{font-serif}}
  \file{ltxtalk-theme-font-mixed.sty}{\from{lttheme.dtx}{font-mixed}}
  \file{ltxtalk-theme-font-libertinus.sty}{\from{lttheme.dtx}{font-libertinus}}
  \file{ltxtalk-theme-font-newcm.sty}{\from{lttheme.dtx}{font-newcm}}
  \file{ltxtalk-theme-font-texgyre.sty}{\from{lttheme.dtx}{font-texgyre}}
  }
  \expandafter\endbatchfile
\fi
 \documentclass[
load-preamble+,add-bib=false
]{osgdoc}

\usepackage{enumitem}
\usepackage{microtype}
\usepackage{needspace}
\setlength{\emergencystretch}{3em}
\usepackage[
languages={de,en},
map={de=german,en=english},
targetlang={job=2},
load babel
]{langselect}

\newpackagename{\lttheme}{ltxtalk-theme}
\newpackagename{\lttalk}{ltx-talk}
\newpackagename{\beamer}{beamer}

\makeindex
\setcnltx{
  name  =  ltxtalk-theme,
  version  = \UseVersionOf{ltxtalk-theme.sty},
  date     = \UseDateOf{ltxtalk-theme.sty},
  title    = {\ldeen{Das \lttheme\ Paket}{The \lttheme\ Package}},
  info     = {\ldeen{Themen-}{Theme }Engine \ldeen{für}{for} \lttalk},
  authors  = {Matthias Werner[matthias.werner@informatik.tu-chemnitz.de]},
  abstract={
    \ldeen{Das Paket gestaltet Präsentationen der Klasse \lttalk.
    Es bietet fertige Layout-, Farb- und Schriftthemes sowie Befehle zum
    Anpassen und Entwickeln eigener Themes. Es gehört zum
    \pkg*{osglecture}-Bundle und ist unabhängig von dessen Dokumentklasse
    nutzbar.}{The package styles presentations made with \lttalk.
    It provides bundled layout, colour, and font themes, together with
    commands for customizing and developing themes. It belongs to the
    \pkg*{osglecture} bundle and works independently of its document class.}
  },
  url      =https://github.com/werner-matthias/osglecture,
  build-title
}
\begin{document}
% --------------------------------------------------------------------------
% Documentation
% --------------------------------------------------------------------------
\section{\ldeen{Einführung}{Introduction}}

\ldeen{
\lttheme\ gestaltet Präsentationen der Klasse \lttalk: Kopf- und Fußzeilen,
Randspalten, Titel, Farben, Schriften, Blöcke und Listenmarken.
Wie bei Beamer können Sie ein fertiges Theme auswählen und Farb- oder
Schriftthemes ergänzen. Eigene Themes beschreiben Bereiche und darin
angeordnete Elemente, die hier \emph{Slots} heißen.
}{
\lttheme\ styles presentations made with \lttalk: headers and footers,
sidebars, titles, colours, fonts, blocks, and list markers. As with Beamer,
you can select a bundled theme and add colour or font themes. Custom themes
describe areas and the elements placed in them, called \emph{slots} here.
}
\ldeen{
Verwenden Sie für die Beispiele Lua\LaTeX\ und eine aktuelle Installation
des Bundles einschließlich \pkg*{osgstyler}. Das Paket ist zuletzt mit
\cls{ltx-talk}~v0.6.10 vom 13.~Oktober~2026 getestet und setzt mindestens
v0.5.3 vom 5.~August~2026 voraus. Ältere Klassenstände führen zu einem Fehler,
neuere als der getestete zu einer Kompatibilitätswarnung. Die Klasse
und das Themesystem befinden sich noch in Entwicklung. Laden Sie die
Klasse zuerst; Themenpakete ersetzen keine bereits geladene Klasse.
}{
Use Lua\LaTeX\ and a current bundle installation including \pkg*{osgstyler}
for the examples. The package was last tested with \cls{ltx-talk}~v0.6.10
dated 13~October~2026 and requires at least v0.5.3 dated 5~August~2026. Older
class releases cause an error; releases newer than the tested one produce a
compatibility warning. Both the class and the theme system are still under
development. Load the class first; theme packages do not replace a class
that has already been loaded.
}

\subsection{\ldeen{Wer sollte diese Dokumentation lesen?}{Who should read this documentation?}}

\ldeen{
Diese Dokumentation richtet sich an zwei Zielgruppen. Anwender möchten
ein vorhandenes Theme nutzen und gegebenenfalls an ihre Anforderungen
anpassen. Themen-Autoren möchten dagegen ein eigenes Theme erstellen oder
ein vorhandenes Theme erweitern.
}{
This documentation addresses two audiences. Users want to select an
existing theme and, where necessary, adapt it to their requirements.
Theme authors, on the other hand, want to create a new theme or extend
an existing one.
}

\ldeen*{
Für erstere Gruppe ist Teil~@1 gedacht.
}{
  Part~@1 is intended for the former group.
}{\ref{part:user}}
\ldeen*{
Wer dagegen ein eigenes Theme erstellen möchte, sollte anschließend auch
den Teil~@1 lesen. Die Referenz (Abschnitt~@2) kann beiden
Gruppen zum gezielten Nachschlagen dienen.
}{
  On the other hand, anyone who wants to create their own theme should also
  read Part~@1. The reference (Section~@2) can serve as a handy reference for both
  groups.
}{\ref{part:develop-themes}}{\ref{ref:reference}}

\part{\ldeen{Nutzerhandbuch}{User Manual}}
\label{part:user}

\section{\ldeen{Schnelleinstieg}{Quick start}}
\label{sec:quick-start}

\ldeen*{
  Das folgende Beispiel zeigt eine kleine, aber vollständige und 
  lauffähige Präsentation.
  Es lädt das mitgelieferte Theme @1, erzeugt eine Titelfolie
  und eine weitere Folie mit einfachem Inhalt.
}{
  The following example demonstrates a small but complete and executable
  presentation. It loads the provided theme @1, generates a title
  slide and an additional slide with simple content.
}{\code{magpie}}

\begin{example}[
  compile,
  program=lualatex,
  runs=2,
  pages={1,2},
  graphics={width=.46\linewidth},
  pre-output={\begin{mdframed}[
    backgroundcolor=white,
    hidealllines=true,
    innerleftmargin=0pt,
    innerrightmargin=0pt,
    innertopmargin=4pt,
    innerbottommargin=4pt
  ]},
  after-output={\end{mdframed}}
]
  \DocumentMetadata{}
  \documentclass{ltx-talk}

  \usepackage{ltxtalk-theme-magpie}
  \useltxtalktheme{magpie}

  \title{My Presentation}
  \author{Joe Doe}
  \date{\today}

  \begin{document}

  \begin{frame}
    \maketitle
  \end{frame}

  \begin{frame}
    \frametitle{Content and appearance}
    \begin{itemize}
      \item A presentation contains the content.
      \item The theme determines how it is displayed.
    \end{itemize}
  \end{frame}

  \end{document}
\end{example}

\section{\ldeen{Themes verwenden}{Using themes}}
\label{sec:use-themes}
\ldeen*{
Ein Theme wird in zwei Schritten ausgewählt. Zunächst lädt
@1 die Themendatei.
Anschließend aktiviert @2 das Thema für die Präsentation. 
}{
A theme is selected in two steps. First,
@1 loads the theme file.
Then, @2 activates the theme for the presentation. 
}{\cs*{usepackage}\Marg{ltxtalk-theme-magpie}}{\cs*{useltxtalktheme}\Marg{magpie}}

\ldeen{
Die Befehle für Titel, Autor und Datum sowie die Umgebung \code{frame}
gehören zur Dokumentklasse \cls{ltx-talk}. 
Das Thema konfiguriert deren
öffentliche Templates und legt damit fest, wo und in welcher Form diese
Angaben auf den Folien erscheinen. Das Setzen und semantische Taggen der
Inhalte bleibt Aufgabe der Klasse. Der eigentliche Inhalt bleibt dadurch
unabhängig vom gewählten Thema.
}{
The commands for title, author, and date and the \code{frame} environment
belong to the \cls{ltx-talk} document class. The theme configures the public
templates of the class and thus determines where and in which form these
details appear on the slides. Typesetting and semantically tagging the content
remain the responsibility of the class. The actual content therefore remains
independent of the selected theme.
}

\ldeen{
Zum Wechseln des Erscheinungsbilds genügt es im einfachsten Fall, ein
anderes mitgeliefertes Theme-Paket zu laden und den zugehörigen Namen an
\cs*{useltxtalktheme} zu übergeben. Welche Themes verfügbar sind und wie
Teilthemes kombiniert werden, beschreibt der folgende Abschnitt.
Wechseln Sie vollständige Themes zwischen zwei Frames; erneutes Aktivieren
setzt die nachträglichen Slot- und Bereichsanpassungen zurück.
}{
In the simplest case, changing the appearance only requires loading another
bundled theme package and passing its name to \cs*{useltxtalktheme}. The
following overview lists the available themes. Section~\ref{sec:extend-themes}
explains how to combine a layout theme with an additive partial theme.
}

\subsection{\ldeen{Reihenfolge und Gültigkeit}{Order and scope}}
\begin{enumerate}
\item \ldeen{Pakete laden und das vollständige Theme aktivieren.}
{Load packages and activate the full theme.}
\item \ldeen{Farb- und Schriftthemes ergänzen.}{Add colour and font themes.}
\item \ldeen{Eigene Anpassungen zuletzt ausführen.}{Apply custom changes last.}
\end{enumerate}
\ldeen{Ein erneutes \cs*{useltxtalktheme} löscht unter anderem Slots,
Bereichsdekorationen, Raster und benannte Layouts. \cs*{addltxtalktheme}
ergänzt die vorhandene Konfiguration. Slotdefinitionen, Slotpositionen und
Rasteränderungen gelten global; eine Gruppe um einen Frame nimmt sie nicht
zurück. Bei Layouts sind die Geometrieschlüssel lokal, ihr Aufbaucode kann
jedoch globale Änderungen ausführen. Definieren Sie für wechselnde Layouts
beide Zustände ausdrücklich und wenden Sie den passenden vor dem Frame an.}
{Calling \cs*{useltxtalktheme} again clears slots, area decorations, grids,
and named layouts, among other settings. \cs*{addltxtalktheme} extends the
existing configuration. Slot definitions, slot positions, and grid changes
are global; grouping a frame does not undo them. Layout geometry keys are
local, but layout setup code may make global changes. For alternating
layouts, define both states explicitly and apply the appropriate one before
the frame.}

\subsection{\ldeen{Mitgelieferte Themes}{Bundled themes}}

\ldeen{
Die sechs Layout-Themes unterscheiden sich vor allem in der Aufteilung der
Seite. \code{minimal} verwendet eine zurückhaltende Kopf- und Fußzeile.
\code{magpie} zeigt den Folientitel in einem farbigen Kopf und Metadaten in
einem dreigeteilten Fuß. \code{hawk} ergänzt eine linke Navigationsspalte;
\code{sparrow} ordnet Abschnitt und Unterabschnitt im Kopf an und setzt den
Folientitel darunter. \code{bluebird} führt im Kopf die Abschnittsliste, eine
Punktreihe und den Fortschritt (siehe Abschnitt~\ref{sec:ref-navigation}) und
bringt ein alternatives Titel-Layout \code{bluebird/band} sowie ein Layout
\code{bluebird/plain} ohne Kopf und Fuß mit. \code{goose} stellt rechts ein
mitlaufendes Inhaltsverzeichnis auf; sein Layout \code{goose/wide} blendet
die Leiste für breite Abbildungen aus. Die Namen der jeweiligen
Theme-Pakete lauten \code{ltxtalk-theme-}\meta{\ldeen{Name}{name}}.
}{
The six layout themes differ mainly in their division of the page.
\code{minimal} uses restrained header and footer areas. \code{magpie} places
the frame title in a coloured header and metadata in a three-part footer.
\code{hawk} adds a navigation area on the left; \code{sparrow} arranges the
section and subsection in the header and places the frame title below them.
\code{bluebird} runs the section list, a row of dots, and a progress readout
(see Section~\ref{sec:ref-navigation}) in the header, and adds an alternative
title layout \code{bluebird/band} plus a chrome-free layout \code{bluebird/plain}.
\code{goose} raises a live table of contents on the right; its
\code{goose/wide} layout drops that sidebar for wide figures. The
corresponding package is named \code{ltxtalk-theme-}\meta{\ldeen{Name}{name}}.
}

\begin{center}
\begin{tabular}{lll}
\hline
\ldeen{Theme}{Theme} & \ldeen{Kennzeichnendes Layout}{Characteristic layout}
  & \ldeen{Anregung}{Inspired by} \\
\hline
\code{minimal}  & \ldeen{schlichte Kopf- und Fußzeile}{plain header and footer} & -- \\
\code{magpie}   & \ldeen{farbiger Kopf und Fuß}{coloured header and footer} & \beamer{} Madrid \\
\code{hawk}     & \ldeen{linker Navigationsbereich}{left navigation area} & \beamer{} Hannover \\
\code{sparrow}  & \ldeen{zweistufige Kopfnavigation}{two-level header navigation} & \beamer{} Szeged \\
\code{bluebird} & \ldeen{Abschnittsnavigation und Fortschritt im Kopf}{header section navigation and progress} & \beamer{} Berlin \\
\code{goose}    & \ldeen{rechtes Inhaltsverzeichnis}{right table of contents} & \beamer{} Goettingen \\
\hline
\end{tabular}
\end{center}

\ldeen{
\code{anchovy} und \code{carp} sind dagegen reine Farbthemes. Sie werden nach
einem Layout-Theme mit \cs*{addltxtalktheme} ergänzt und ändern nur die
semantischen Farben. \code{anchovy} verwendet ein blau-goldenes,
\code{carp} ein rotes Farbschema. Weil sie keine Bereiche oder Slots neu
anlegen, bleibt das zuvor gewählte Layout erhalten.
}{
In contrast, \code{anchovy} and \code{carp} are colour-only themes. Add them
after a layout theme with \cs*{addltxtalktheme}; they change only the semantic
colours. \code{anchovy} uses a blue-and-gold palette, whereas \code{carp}
uses a red palette. Because neither defines areas or slots, the previously
selected layout remains intact.
}

\begin{sourcecode}
  \usepackage{ltxtalk-theme-minimal}
  \usepackage{ltxtalk-theme-anchovy}
  \useltxtalktheme{minimal}
  \addltxtalktheme{anchovy}
\end{sourcecode}

\ldeen{
Font-Themes werden ebenso additiv über ein Layout-Theme gelegt. Neben den
einfachen Varianten \code{font-sans}, \code{font-serif} und
\code{font-mixed} gibt es echte Schrift-Sippen: \code{font-libertinus},
\code{font-newcm} und \code{font-texgyre}. Jede Sippe besetzt semantische
Rollen für Fließtext, Begleittext, Überschriften, Hervorhebungen, Code,
Mathematik und Symbole mit aufeinander abgestimmten Familien. Alle
verwendeten Schriften sind Bestandteil von \TeX\ Live.
}{
Font themes are likewise layered over a layout theme. In addition to the
simple \code{font-sans}, \code{font-serif}, and \code{font-mixed} variants,
proper typeface families are provided: \code{font-libertinus},
\code{font-newcm}, and \code{font-texgyre}. Each family assigns coordinated
faces to semantic roles for body copy, supporting text, headings, emphasis,
code, mathematics, and symbols. All fonts used are distributed with
\TeX\ Live.
}

\begin{sourcecode}
  \usepackage{ltxtalk-theme-sparrow}
  \usepackage{ltxtalk-theme-font-libertinus}
  \useltxtalktheme{sparrow}
  \addltxtalktheme{font-libertinus}
\end{sourcecode}

\ldeen{
Die Rollen heißen \code{body}, \code{support}, \code{heading},
\code{emphasis}, \code{code}, \code{math} und \code{symbol}. Sie können bei
Slots mit \code{font-slot=heading} oder direkt mit
\cs*{UseLTXTalkFont}\Marg{heading} gewählt werden. Die bisherigen portablen
Namen \code{main}, \code{companion}, \code{display}, \code{accent} und
\code{mono} bleiben als kompatible Synonyme erhalten. Der Mathematik-Slot
wird nur als Ressource für eine spätere \pkg*{unicode-math}-Anbindung
registriert und nicht als Textschrift aktiviert.
}{
The roles are named \code{body}, \code{support}, \code{heading},
\code{emphasis}, \code{code}, \code{math}, and \code{symbol}. Select them on
a slot with \code{font-slot=heading}, or directly with
\cs*{UseLTXTalkFont}\Marg{heading}. The existing portable names
\code{main}, \code{companion}, \code{display}, \code{accent}, and
\code{mono} remain available as compatible synonyms. The mathematics slot
is registered only as a resource for a later \pkg*{unicode-math} adapter and
is not activated as a text font.
}

\subsubsection{\ldeen{Vergleich der mitgelieferten Themes}{Comparison of the bundled themes}}

\ldeen{
Die folgenden Beispielfolien verwenden bewusst denselben Inhalt. Dadurch
werden Unterschiede in Satzspiegel, Navigation, Titelplatzierung und
semantischen Farben unmittelbar vergleichbar. Die reinen Farbthemes werden
über einem Layout gezeigt, das ihre Palette sichtbar macht: \code{carp} färbt
\code{primary} um und wirkt daher unter \code{magpie} mit seinen großen
Kopf- und Fußflächen am deutlichsten; \code{anchovy} legt das Gold in die
Akzentslots und braucht ein Layout wie \code{sparrow}, das \code{secondary}
für Nebentext nutzt.
}{
The following example slides deliberately use identical content. This makes
differences in text area, navigation, title placement, and semantic colours
directly comparable. Each colour-only theme is shown over a layout that
surfaces its palette: \code{carp} repaints \code{primary} and reads most
clearly under \code{magpie} with its large header and footer fills;
\code{anchovy} places its gold in the accent slots and needs a layout such as
\code{sparrow} that colours secondary text from \code{secondary}.
}

\begin{example}[
  compile,
  program=lualatex,
  runs=2,
  pages={1,2,3,4,5,6,7,8},
  max-pages=2,
  graphics={width=.90\linewidth},
  pre-output={\begin{mdframed}[
    backgroundcolor=white,
    hidealllines=true,
    innerleftmargin=0pt,
    innerrightmargin=0pt,
    innertopmargin=4pt,
    innerbottommargin=4pt
  ]},
  after-output={\end{mdframed}}
]
  \DocumentMetadata{}
  \documentclass{ltx-talk}

  \usepackage{ltxtalk-theme-minimal}
  \usepackage{ltxtalk-theme-magpie}
  \usepackage{ltxtalk-theme-hawk}
  \usepackage{ltxtalk-theme-sparrow}
  \usepackage{ltxtalk-theme-bluebird}
  \usepackage{ltxtalk-theme-goose}
  \usepackage{ltxtalk-theme-anchovy}
  \usepackage{ltxtalk-theme-carp}

  \title[Theme comparison]{Theme comparison}
  \author[A. Example]{Ada Example}
  \institute{Example Institute}
  \date{2 September 2026}

  \newcommand*\ThemeExampleFrame[1]{
    \begin{frame}
      \frametitle{#1}
      \framesubtitle{The same content in every theme}
      A short paragraph demonstrates type, text colour, and the text area.
      \begin{itemize}
        \item first list item
        \item second item with an \alert{alert}
      \end{itemize}
      \begin{block}{Example block}
        Block content with the formula $a^2+b^2=c^2$.
      \end{block}
    \end{frame}
  }

  \begin{document}
  \section{First topic}
  \subsection{An aspect}
  \useltxtalktheme{minimal}
  \ThemeExampleFrame{minimal}
  \useltxtalktheme{magpie}
  \ThemeExampleFrame{magpie}
  \section{Second topic}
  \useltxtalktheme{hawk}
  \ThemeExampleFrame{hawk}
  \useltxtalktheme{sparrow}
  \ThemeExampleFrame{sparrow}
  \useltxtalktheme{bluebird}
  \ThemeExampleFrame{bluebird}
  \section{Third topic}
  \subsection{Its detail}
  \useltxtalktheme{goose}
  \ThemeExampleFrame{goose}
  \useltxtalktheme{sparrow}
  \addltxtalktheme{anchovy}
  \ThemeExampleFrame{sparrow + anchovy}
  \useltxtalktheme{magpie}
  \addltxtalktheme{carp}
  \ThemeExampleFrame{magpie + carp}
  \end{document}
\end{example}

\section{\ldeen{Themes anpassen}{Customizing themes}}
\label{sec:customizing-themes}
\subsection{\ldeen{Das Layout anpassen}{Customizing the layout}}

\ldeen{
Nach der Aktivierung lassen sich die vom Theme gewählten Abmessungen mit
\cs*{ltxtalksetup} überschreiben. Dabei werden nur die angegebenen
Eigenschaften geändert. Das folgende Beispiel vergrößert Kopf- und Fußbereich
und schaltet den rechten Randbereich ab:
}{
After activation, the dimensions selected by the theme can be overridden with
\cs*{ltxtalksetup}. Only the specified properties are changed. The following
example enlarges the header and footer and disables the right margin area:
}

\begin{sourcecode}
  \useltxtalktheme{hawk}
  \ltxtalksetup{
    header-height = 2.8cm,
    footer-height = 0.8cm,
    right-margin = false
  }
\end{sourcecode}
\ldeen{
Die Schlüssel von \cs*{ltxtalksetup} sind in
Abschnitt~\ref{sec:ref-layout} vollständig aufgeführt. Für einfache
Anpassungen genügen meist die Schalter \code{header}, \code{left-margin},
\code{right-margin} und \code{footer} sowie die Längen
\code{header-height}, \code{footer-height} und \code{margin-width}. Eine
Änderung der Bereichsgröße verschiebt vorhandene Slots nicht automatisch.
Größere Eingriffe sollten deshalb in einem eigenen Theme oder Teiltheme
vorgenommen werden; Abschnitt~\ref{sec:theme-workflow} beschreibt das
Vorgehen.
}{
Section~\ref{sec:ref-layout} lists all keys of \cs*{ltxtalksetup}. For simple
adjustments, the switches \code{header}, \code{left-margin},
\code{right-margin}, and \code{footer} and the dimensions
\code{header-height}, \code{footer-height}, and \code{margin-width} are
usually sufficient. Changing an area's size does not reposition existing
slots automatically. Larger changes should therefore be implemented as a
theme or partial theme; Section~\ref{sec:theme-workflow} describes the
procedure.
}

\ldeen{Ein benanntes Layout kann auch vorübergehend einen Randbereich
abschalten. Im Theme \code{goose} kehren Sie anschließend ausdrücklich
zu \code{goose/standard} zurück:}
{A named layout can temporarily hide a sidebar. With \code{goose},
explicitly return to \code{goose/standard} afterwards:}
\begin{sourcecode}
  % Preamble:
  \usepackage{ltxtalk-theme-goose}
  \useltxtalktheme{goose}
  \title{A presentation}
  \author{A. Author}
  % In the document:
  \UseLTXTalkLayout{goose/wide}
  \begin{frame}
    \frametitle{A wide illustration}
    Content using the extra width.
  \end{frame}
  \UseLTXTalkLayout{goose/standard}
\end{sourcecode}

\subsection{\ldeen{Farben anpassen}{Customizing colours}}

\ldeen{
Die acht semantischen Theme-Farben lassen sich mit
\cs*{setltxtalkcolors} neu belegen. Jeder Wert nennt, wie bei
\cs*{definecolor}, Farbmodell und Farbangabe, hier als
\code{model=...,~value=...}-Paar:
}{
The eight semantic theme colours can be assigned with
\cs*{setltxtalkcolors}. As with \cs*{definecolor}, every value specifies a
colour model and value, here as a \code{model=...,~value=...} pair:
}
\begin{sourcecode}
  \setltxtalkcolors{
    primary    = {model=HTML, value=005B50},
    secondary  = {model=HTML, value=3C7A73},
    accent     = {model=HTML, value=D6A800},
    text       = {model=HTML, value=202020},
    background = {model=HTML, value=FFFFFF},
    structure  = {model=HTML, value=005B50},
    alert      = {model=HTML, value=A00020},
    example    = {model=HTML, value=166534}
  }
\end{sourcecode}

\ldeen{\code{primary} prägt das Theme; \code{secondary} dient ergänzenden Angaben,
\code{accent} hebt Details hervor. \code{text} und \code{background} bilden
Vorder- und Hintergrund. \code{structure}, \code{alert} und \code{example}
gestalten Listen und Blockvarianten. Die Farbnamen tragen das Präfix
\code{ltxtalk-}, mit \code{ltxtalk-bg} für den Hintergrund. Die letzten drei
Farben sind auch als \code{structure}, \code{alert} und \code{example}
verfügbar. Änderungen wirken dort, wo das Theme diese Namen verwendet.}{\code{primary} defines the theme's main colour; \code{secondary} supports
additional information and \code{accent} highlights details. \code{text}
and \code{background} form the foreground/background pair.
\code{structure}, \code{alert}, and \code{example} style lists and block
variants. Colour names carry the \code{ltxtalk-} prefix, with
\code{ltxtalk-bg} for the background. The final three are also available as
\code{structure}, \code{alert}, and \code{example}. Changes take effect
where the theme uses these names.}

\ldeen{
Nicht angegebene Farben werden in einer festen Kette abgeleitet:
\code{secondary}, \code{accent} und \code{structure} erben von
\code{primary}; \code{text} und \code{background} verwenden ihre neutralen
Vorgaben, \code{alert} und \code{example} ihre semantischen Vorgaben. Eine
abgeleitete Farbe wird beim Aufruf festgelegt; spätere Änderungen der
Ausgangsfarbe berechnen sie nicht nachträglich neu.
}{
Unspecified colours are derived along a fixed chain: \code{secondary},
\code{accent}, and \code{structure} inherit from \code{primary};
\code{text} and \code{background} use their neutral defaults, while
\code{alert} and \code{example} use their semantic defaults. A derived colour
is fixed when the command is executed; changing its source later does not
recompute it automatically.
}
\begin{warnbox}{\ldeen{Achtung}{Attention}!}
\ldeen{
\cs*{setltxtalkcolors} ist eine \emph{vollständige} Neudeklaration, kein
inkrementelles Update: Nicht genannte Slots fallen nicht auf ihren
vorherigen Wert zurück, sondern auf die übliche Vererbungskette
(\code{secondary} etc.\ auf \code{primary}). Nur \code{primary} selbst ist
zwingend anzugeben; fehlt es oder ist eine Angabe unvollständig, schlägt
die gesamte Neudeklaration fehl und die zuvor gültigen Farben bleiben
unverändert bestehen -- nicht weil einzelne Slots verschont würden, sondern
weil die fehlgeschlagene Deklaration insgesamt nichts ändert. Wer nur
einen einzelnen Slot anpassen möchte, ohne die anderen erneut aufzuzählen,
sollte deshalb den vollständigen letzten Aufruf wiederholen und nur den
gewünschten Wert ändern.
}{
\cs*{setltxtalkcolors} is a \emph{complete} redeclaration, not an incremental
update. Omitted entries do not retain their previous value but follow the
inheritance rules described above. Only \code{primary} is mandatory. If it is
missing, or if any supplied colour specification is incomplete, the entire
declaration fails and the previously valid palette remains unchanged. To
change a single colour while preserving all others, repeat the complete most
recent declaration and alter the desired entry.
}
\end{warnbox}

\subsection{\ldeen{Titel platzieren}{Positioning titles}}

\ldeen{
Mit \cs*{setltxtalktitleplacement} wird festgelegt, in welchem Bereich ein
Theme Folien- und Abschnittstitel vorsieht. Ein Folientitel kann im
Inhaltsbereich, im Kopf oder in beiden Bereichen erscheinen; ein
Abschnittstitel kann im Kopf ein- oder ausgeblendet werden:
}{
\cs*{setltxtalktitleplacement} declares in which area a theme provides frame
and section titles. A frame title can occur in the content area, the header,
or both; a section title can be shown or hidden in the header:
}

\begin{sourcecode}
  \setltxtalktitleplacement{
    frametitle = both,
    section = header
  }
\end{sourcecode}

\ldeen{
Das Theme muss passende Slots für die gewählte Platzierung enthalten. Fehlt ein solcher
Slot, erzeugt die Option allein kein zusätzliches sichtbares Element.
}{
The theme must provide suitable slots for the selected placement. The option alone does not
create an additional visible element when the corresponding slot is absent.
}

\subsection{
  \ldeen{Abschnittstitel als Frametitel}{Section titles as frame titles}
}

\ldeen{
Mit \cs*{setltxtalkheadingbehavior}\marg{auto-section-title = true} übernimmt
die erste \cs{frametitle}-Folie nach \cs{section} oder \cs{subsection} deren
nummerierte Überschrift automatisch als Titel -- unabhängig davon, ob dasselbe Theme Abschnitte
zusätzlich im Kopf zeigt (\cs*{setltxtalktitleplacement}s Schlüssel
\code{section}). Wird an dieser Folie zusätzlich ein eigener Text angegeben,
wandert er auf den Subtitel-Platz; ein daneben separat gesetzter
\cs{framesubtitle} entfällt dann, weil der eigene Titel den Platz schon
belegt:
}{
With \cs*{setltxtalkheadingbehavior}\marg{auto-section-title = true}, the
first \cs{frametitle} frame after \cs{section} or \cs{subsection}
automatically takes over its numbered heading as the title -- independently of whether
the same theme also shows sections in the header (\cs*
{setltxtalktitleplacement}'s \code{section} key). If that same frame also
gives its own text, it moves to the subtitle slot; a separately given
\cs{framesubtitle} is then dropped, because the supplied title already
occupies that slot:
}

\begin{sourcecode}
  \setltxtalkheadingbehavior{auto-section-title = true}
  ...
  \section{Introduction}
  \begin{frame}
    \frametitle{} % title becomes "1 Introduction"
    ...
  \end{frame}
  \section{Related Work}
  \begin{frame}
    \frametitle{A Short History}   % title becomes "2 Related Work",
                                    % subtitle becomes "A Short History"
    ...
  \end{frame}
\end{sourcecode}

\ldeen{
Der Merker wird von genau einem \cs{frametitle}-Aufruf verbraucht: spätere
Folien desselben Abschnitts sind unbeeinflusst, und folgen \cs{section} und
\cs{subsection} ohne dazwischenliegende Folie aufeinander, gewinnt der
zuletzt genannte (speziellere) Abschnitt. Ohne jeden \cs{frametitle}-Aufruf
bleibt eine Folie wie bisher titellos; ein leeres \cs{frametitle}\marg{}
genügt, um allein den Abschnittstitel zu übernehmen.
}{
The flag is consumed by exactly one \cs{frametitle} call: later frames in the
same section are unaffected, and if \cs{section} and \cs{subsection} follow
each other with no frame in between, the last (more specific) one wins. A
frame with no \cs{frametitle} call at all stays titleless as before; an
empty \cs{frametitle}\marg{} is enough to pick up just the section title.
}

\subsection{\ldeen{Weitere Anpassungen}{Further customizations}}

\ldeen{
Einzelne vorhandene Slots können nach der Theme-Aktivierung mit
\cs*{styleltxtalkslot} umgestaltet werden. Dafür muss der vom Theme
verwendete Slotname bekannt sein; er gehört deshalb zur Schnittstelle des
jeweiligen Themes, nicht zur allgemeinen Anwenderschnittstelle. Ebenso kann
\cs*{decorateltxtalkarea} beispielsweise eine Linie über dem Footer ändern.
}{
Individual slots can be restyled after activating the theme with
\cs*{styleltxtalkslot}. This requires knowing the slot name used by that
theme; slot names are therefore part of a particular theme's interface, not
of the general user interface. Likewise, \cs*{decorateltxtalkarea} can, for
example, change a rule above the footer.
}

\begin{sourcecode}
  \usepackage{ltxtalk-theme-minimal}
  \useltxtalktheme{minimal}
  \styleltxtalkslot{min-ftitle}{
    color = ltxtalk-primary,
    font = \Large\bfseries,
    align = left
  }
  \decorateltxtalkarea{footer}{
    frame = top,
    rule-color = ltxtalk-accent,
    rule-thickness = 0.6pt
  }
\end{sourcecode}

\ldeen{
Solche Anpassungen sollten unmittelbar nach \cs*{useltxtalktheme} stehen,
weil eine spätere erneute Theme-Aktivierung alle Slots und Dekorationen
zurücksetzt. Für wiederverwendbare oder strukturelle Ergänzungen ist ein
Teiltheme mit \cs*{addltxtalktheme} geeigneter.
}{
Place such customizations immediately after \cs*{useltxtalktheme}, because
activating another theme later resets all slots and decorations. For reusable
or structural additions, a partial theme activated with
\cs*{addltxtalktheme} is more appropriate.
}


\subsection{\ldeen{Slotnamen der mitgelieferten Themes}{Slot names in bundled themes}}
\ldeen{Die folgenden Namen können nach Aktivierung des jeweiligen Themes mit \cs*{styleltxtalkslot} gestaltet werden. Kombinieren Sie das Präfix mit dem aufgeführten Suffix, etwa \code{min-ftitle}. Farb- und Schriftthemes fügen keine eigenen Slots hinzu.}{Style the following names with \cs*{styleltxtalkslot} after activating the corresponding theme. Combine the prefix with a listed suffix, for example \code{min-ftitle}. Colour and font themes do not add slots.}
\begin{description}
\item[\code{minimal}] \ldeen{Präfix}{Prefix} \code{min-}: \code{title}, \code{section}, \code{page}, \code{ftitle}, \code{fsubtitle}, \code{author}, \code{footer-page}.
\item[\code{magpie}] \ldeen{Präfix}{Prefix} \code{magpie-}: \code{frametitle}, \code{framesubtitle}, \code{author}, \code{title}, \code{page}.
\item[\code{hawk}] \ldeen{Präfix}{Prefix} \code{hawk-}: \code{title}, \code{author}, \code{section}, \code{subsection}, \code{frametitle}, \code{framesubtitle}.
\item[\code{sparrow}] \ldeen{Präfix}{Prefix} \code{sparrow-}: \code{section}, \code{subsection}, \code{frametitle}, \code{framesubtitle}, \code{institute}, \code{title}, \code{page}.
\item[\code{bluebird}] \ldeen{Präfix}{Prefix} \code{bluebird-}: \code{navband}, \code{titleband}, \code{seclist}, \code{dots}, \code{progress}, \code{ftitle}, \code{fsub}, \code{footline1}, \code{footline2}, \code{fauthor}, \code{finst}, \code{ftitle-foot}, \code{fpage}.
\item[\code{goose}] \ldeen{Präfix}{Prefix} \code{goose-}: \code{sidemeta}, \code{toc}, \code{progress}, \code{subs}, \code{ftitle}, \code{fsub}.
\end{description}

\section{\ldeen{Barrierefreiheit}{Accessibility}}
\label{sec:accessibility}

\ldeen{
Ein Theme verändert die visuelle Darstellung, darf aber die von
\cls{ltx-talk} erzeugte Dokumentstruktur nicht ersetzen. Folientitel sollten
daher mit \cs*{frametitle}, Untertitel mit \cs*{framesubtitle} und
Gliederungsebenen mit \cs*{section} beziehungsweise \cs*{subsection}
ausgezeichnet werden. Rein optisch formatierter Text kann diese semantischen
Befehle nicht ersetzen.
}{
A theme changes visual presentation but must not replace the document
structure created by \cls{ltx-talk}. Mark frame titles with
\cs*{frametitle}, subtitles with \cs*{framesubtitle}, and structural levels
with \cs*{section} and \cs*{subsection}. Merely formatting text visually
cannot replace these semantic commands.
}

\subsection{\ldeen{Lesbare Gestaltung}{Readable design}}

\ldeen{
Bei eigenen Farbanpassungen müssen Vorder- und Hintergrund ausreichend
kontrastieren. Farbe sollte außerdem nie das einzige Mittel sein, um eine
Bedeutung auszudrücken. Kleine Schrift, sehr dünne Linien und dicht belegte
Randbereiche sind auf Projektoren und bei starker Vergrößerung besonders
problematisch. Entscheidend ist nicht nur die Titelfolie, sondern auch eine
inhaltlich volle Standardfolie.
}{
Custom foreground and background colours must provide sufficient contrast.
Colour should never be the only means of conveying meaning. Small type, very
thin rules, and densely filled margin areas are particularly problematic on
projectors and at high magnification. Test not only the title slide but also
a content-heavy standard slide.
}

\ldeen{
Text und wesentliche Grafiken sollten innerhalb der verfügbaren Bereiche
bleiben. Eine Änderung von \code{margin-width}, \code{header-height} oder
\code{footer-height} muss deshalb mit langen Titeln, mehrzeiligen Angaben und
verschiedenen Seitenverhältnissen geprüft werden.
}{
Text and essential graphics should remain within the available areas. Changes
to \code{margin-width}, \code{header-height}, or \code{footer-height} must
therefore be tested with long titles, multi-line metadata, and different
aspect ratios.
}

\subsection{\ldeen{Grafiken und Logos}{Graphics and logos}}

\ldeen{
Für inhaltliche Grafiken gelten die Möglichkeiten von \cls{ltx-talk} und den
verwendeten Grafikpaketen; dort ist ein aussagekräftiger Alternativtext
anzugeben. Wiederkehrende Logos, Farbflächen und Trennlinien sind gewöhnlich
dekorativ und dürfen die Lesereihenfolge nicht mit wiederholten Informationen
belasten. Die Slotrolle \code{artifact} kennzeichnet dekorative Elemente. Für ein inhaltliches Bild in einem Slot geben Sie einen Alternativtext mit \code{alt-text} an; siehe Abschnitt~\ref{sec:ref-accessibility}.
}{
Content graphics use the facilities of \cls{ltx-talk} and the loaded graphics
packages; provide meaningful alternative text there. Repeated logos, colour
fields, and rules are usually decorative and must not burden the reading order
with duplicate information. The slot role \code{artifact} marks decorative elements. For meaningful graphics in a slot, provide alternative text with \code{alt-text}; see Section~\ref{sec:ref-accessibility}.
}

\subsection{\ldeen{Tagging und Prüfung}{Tagging and testing}}

\ldeen{
Für getaggte PDF-Ausgabe sollte die Präsentation mit \cs*{DocumentMetadata}
beginnen. Das eigentliche Tagging von Frame-Inhalt und Überschriften übernimmt
gegenwärtig überwiegend \cls{ltx-talk}. \lttheme{} bewahrt diese Anbindung,
indem Folientitel im Inhaltsbereich über die öffentlichen Klassenbefehle
gesetzt werden. Die Optionen der Slot-Schnittstelle steuern zusätzlich die Rolle und den Alternativtext der Theme-Elemente im getaggten PDF (Abschnitt~\ref{sec:ref-accessibility}).
}{
For tagged PDF output, begin the presentation with \cs*{DocumentMetadata}.
At present, \cls{ltx-talk} performs most tagging of frame content and
headings. \lttheme{} preserves that connection by typesetting frame titles in
the content area through the class's public commands. The slot interface additionally controls the role and alternative text of theme elements in tagged PDF (Section~\ref{sec:ref-accessibility}).
}

\ldeen{
Eine Prüfung sollte deshalb sowohl visuell als auch strukturell erfolgen:
mit langen und leeren Metadaten, mehreren Gliederungsebenen, fortgesetzten
Folien und einem PDF-Prüfwerkzeug. Das Bundle enthält dafür l3build-Tests, die
unter anderem die von \cls{ltx-talk} erzeugte Überschriftenstruktur prüfen.
}{
Testing must therefore cover both visual appearance and structure: use long
and empty metadata, multiple section levels, continuation frames, and a PDF
checking tool. The bundle provides l3build tests that, among other things,
check the heading structure generated by \cls{ltx-talk}.
}


% ==========================================================================
% For theme authors
% ==========================================================================
\part{\ldeen{Eigene Themes entwickeln}{Developing custom themes}}
\label{part:develop-themes}

\section{\ldeen{Das Theme-Modell}{The theme model}}
\label{sec:theme-model}
\ldeen{Ein Theme besteht aus Bereichen, Slots und Gestaltung. Der Slottyp bestimmt den Inhalt; Bereich und Position bestimmen den Ort; die Slotgestaltung bestimmt Schrift, Farbe und Rahmen. Verwenden Sie die vorhandenen Typen für Titel und Metadaten, und \code{custom} für eigenen Inhalt. Die Klasse bleibt für Frames, Overlays und die semantische Struktur des Folieninhalts zuständig. Die semantische Rolle der Theme-Elemente legen Sie mit den Optionen für Barrierefreiheit fest (Abschnitt~\ref{sec:ref-accessibility}).}{A theme consists of areas, slots, and styling. The slot type determines content; area and position determine location; slot styling determines font, colour, and frame. Use existing types for titles and metadata, and \code{custom} for custom content. The class remains responsible for frames, overlays, and the semantic structure of frame content. Specify the semantic role of theme elements through the accessibility options (Section~\ref{sec:ref-accessibility}).}

\subsection{\ldeen{Bereiche}{Areas}}

\ldeen{Ein Theme ordnet Seitenelemente den fünf Bereichen \texttt{header},
\texttt{left}, \texttt{content}, \texttt{right} und \texttt{footer} zu.
Header, Ränder und Footer werden durch den Seitenstil \texttt{lttheme}
ausgegeben. Der Inhaltsbereich bleibt Teil des normalen Frame-Inhalts; dadurch
bleiben Umbruch, Overlays und die semantische Einordnung durch \pkg{ltx-talk}
erhalten.}{A theme assigns page elements to the five areas \code{header},
\code{left}, \code{content}, \code{right}, and \code{footer}. The
\code{lttheme} page style outputs the header, margins, and footer. The content
area remains part of the normal frame content, preserving line breaking,
overlays, and semantic classification by \cls{ltx-talk}.}

\begin{center}
\begin{tabular}{|c|c|c|}
\hline
\multicolumn{3}{|c|}{\code{header}: \ldeen{Titel und Navigation}{titles and navigation}} \\
\hline
\code{left} & \code{content}: \ldeen{Frame-Inhalt}{frame content} & \code{right} \\
\hline
\multicolumn{3}{|c|}{\code{footer}: \ldeen{Metadaten und Foliennummer}{metadata and frame number}} \\
\hline
\end{tabular}
\end{center}

\ldeen{Die Abbildung zeigt nur die räumliche Schachtelung. Ein Theme darf
jeden Bereich leer lassen, und mehrere Slots dürfen denselben Bereich belegen.
Überlappungen werden nicht automatisch verhindert.}{The diagram shows only
the spatial nesting. A theme may leave any area empty, and several slots may
occupy the same area. Overlaps are not prevented automatically.}

\subsection{\ldeen{Slots}{Slots}}

\ldeen{Ein Slot bezeichnet ein Element mit einer Aufgabe, nicht eine fest verdrahtete
Stelle. Erst die Zuordnung zu einem Bereich, seine Position und sein
Darstellungs-Template ergeben das konkrete Layout. Mehrere Slots desselben
Typs sind zulässig. So kann etwa ein Folientitel im Header, im Inhaltsbereich
oder in beiden Bereichen vorkommen.}{A slot represents an element with a
purpose, not a hard-wired location. Its assignment to an area, position, and
rendering template form the concrete layout. Several slots of the same type
are allowed; a frame title may occur in the header, the content area, or both.}

\subsection{\ldeen{Slottypen}{Slot types}}

\ldeen{Vordefinierte Typen liefern unter anderem Dokumenttitel, Autor, Institut,
Abschnitt, Unterabschnitt, Folientitel, Folienuntertitel und Foliennummer.
Der Typ \texttt{custom} bezieht seinen Inhalt aus
\cs{setltxtalkslotcontent}; damit lassen sich beispielsweise Pfad- und
Baumnavigationen oder frei gestaltete Logos ergänzen.}{Predefined types
provide the document title, author, institute, section, subsection, frame
title, frame subtitle, and frame number, among other data. The \code{custom}
type obtains its content from \cs*{setltxtalkslotcontent}; it can therefore
implement breadcrumb or tree navigation and freely designed logos.}

\subsection{\ldeen{Layout}{Layout}}

\ldeen{Jeder Slot besitzt eine
horizontale und vertikale Ankerposition sowie Breite und Höhe. Symbolische
Positionen wie \texttt{left}, \texttt{center}, \texttt{right}, \texttt{top}
und \texttt{bottom} können mit absoluten Längen kombiniert werden. }{Every slot has horizontal and vertical
anchor positions, a width, and a height. Symbolic positions such as
\code{left}, \code{center}, \code{right}, \code{top}, and \code{bottom}
can be combined with absolute dimensions. }

\subsection{\ldeen{Gestaltung}{Styling}}

\ldeen{Für jeden Slot existiert eine Instanz des Templates \texttt{lttheme-slot}.
Themes geben geeignete Vorgaben vor; Anwender können diese Instanzen mit den
üblichen Template-Mitteln weiter bearbeiten. Schrift, Farbe, Hintergrund,
Ausrichtung, Innenabstand und Regeln gehören damit zum Theme, nicht zum
Seitenstil.}{Every slot has an instance of the \code{lttheme-slot} template.
Themes provide suitable defaults, and users can edit the instances through
the public styling command. Font, colour, background, alignment, padding, and
rules thus belong to the theme rather than the page style.}

\subsection{\ldeen{Dekoration von Bereichen}{Area decoration}}

\ldeen{Bereichsdekorationen sind von den Slots unabhängig. Das Template
\texttt{lttheme-area} kann insbesondere Hintergrundflächen und Trennlinien
zeichnen. Eine obere Linie des Footers ist daher eine Eigenschaft des
Footer-Bereichs und kein künstlicher Footer-Slot.}{Area decorations are
independent of slots. In particular, the \code{lttheme-area} template draws
backgrounds and separator rules. A rule above the footer is therefore a
property of the footer area, not an artificial footer slot.}

\ldeen{Der Seitenstil bildet die stabile Verbindung zu \lttalk. Sockets teilen
seine Ausgabe zusätzlich in Hintergrund, die vier Seitenbereiche und
Vordergrund. Ein vollständiges Theme muss diese Sockets nicht anfassen; sie
sind Erweiterungspunkte für austauschbare Layoutphasen, nicht der Ersatz für
die additive Slot-Schnittstelle.}{The page style forms the stable connection
to \lttalk. Sockets additionally split its output into background, the four
peripheral areas, and foreground. A complete theme need not touch these
sockets; they are extension points for replaceable layout phases, not a
replacement for the additive slot interface.}

\section{\ldeen{Ein Theme schrittweise entwickeln}{Developing a theme step by step}}
\label{sec:theme-workflow}

\ldeen{
Die Entwicklung folgt am zuverlässigsten dieser Reihenfolge: zuerst mit
\cs*{ltxtalksetup} die benötigten Bereiche dimensionieren, dann Slots
definieren und mit Testinhalten positionieren, anschließend Slots und Bereiche
gestalten und zuletzt innere Elemente, Titelseite und Farben abstimmen. So
bleiben geometrische und rein visuelle Fehler voneinander unterscheidbar.
}{
The most reliable development order is: first size the required areas with
\cs*{ltxtalksetup}; then define and position slots using test content; next
style slots and areas; finally coordinate inner elements, title page, and
colours. This keeps geometric and purely visual errors distinguishable.
}

\subsection{\ldeen{Theme registrieren und Geometrie wählen}{Registering the theme and choosing its geometry}}

\ldeen{
Ein Theme-Paket lädt zunächst \pkg{ltxtalk-theme}, definiert eine
Setup-Anweisung und registriert diese unter einem eindeutigen Namen. Die
Setup-Anweisung wird nicht beim Laden, sondern erst durch
\cs*{useltxtalktheme} ausgeführt. Dadurch können mehrere Theme-Pakete geladen
und später gezielt aktiviert werden.
}{
A theme package first loads \pkg{ltxtalk-theme}, defines a setup command, and
registers it under a unique name. The setup command is not executed when the
package is loaded but only by \cs*{useltxtalktheme}. Several theme packages
can therefore be loaded and one of them activated later.
}

\begin{sourcecode}
  \RequirePackage{ltxtalk-theme}
  \ExplSyntaxOn
  \cs_new_protected:Npn \__my_theme_setup:
    {
      \ltxtalksetup{header=true,header-height=1.5cm}
      % Slots, Positionen und Gestaltung
    }
  \RegisterLTXTalkTheme{my-theme}{\__my_theme_setup:}
  \ExplSyntaxOff
\end{sourcecode}

\ldeen{
Die Paketlogik kennt den Namen des Themes nicht. Bei der Aktivierung leert
sie den bisherigen Theme-Zustand, führt die registrierte Setup-Anweisung aus,
passt den Textbereich an und wählt den Seitenstil \code{lttheme}. Das Theme
beschreibt daher ausschließlich Bereiche, Slots und deren Erscheinungsbild.
}{
The package logic does not know the name of the theme. On activation it clears
the previous theme state, executes the registered setup command, adjusts the
text area, and selects the \code{lttheme} page style. The theme therefore
describes only areas, slots, and their appearance.
}

\subsection{\ldeen{Bereiche und Slots definieren}{Defining areas and slots}}

\ldeen{
Ein Slot wird mit Name, Bereich, Typ und Angaben zur Barrierefreiheit definiert. Der
Name muss innerhalb des aktiven Themes eindeutig sein. Als Bereiche sind
\code{header}, \code{left}, \code{content}, \code{right} und \code{footer}
vorgesehen.
}{
A slot is defined by name, area, type, and accessibility data. Its name must
be unique within the active theme. The standard areas are \code{header},
\code{left}, \code{content}, \code{right}, and \code{footer}.
}

\begin{sourcecode}
  \defineltxtalkslot{my-section}{header}{section}{
    role = navigation
  }
  \defineltxtalkslot{my-path}{right}{custom}{
    role = navigation
  }
  \setltxtalkslotcontent{my-path}{
    \thesection\quad\thesubsection
  }
\end{sourcecode}

\ldeen{
Die vordefinierten Typen \code{title}, \code{author}, \code{date},
\code{institute}, \code{section}, \code{subsection}, \code{frametitle},
\code{framesubtitle} und \code{pagenumber} beziehen ihren Inhalt aus der
Klasse. Der Typ \code{custom} sowie unbekannte eigene Typen verwenden den mit
\cs*{setltxtalkslotcontent} hinterlegten Inhalt. Auch Logos werden zweckmäßig
auf diese Weise mit explizitem Grafikcode belegt.
}{
The predefined types \code{title}, \code{author}, \code{date},
\code{institute}, \code{section}, \code{subsection}, \code{frametitle},
\code{framesubtitle}, and \code{pagenumber} obtain their content from the
class. The \code{custom} type and unknown custom types use content stored with
\cs*{setltxtalkslotcontent}. Logos are conveniently supplied in the same way
using explicit graphics code.
}

\subsection{\ldeen{Slots positionieren}{Positioning slots}}

\ldeen{
Nach der Definition erhält jeder sichtbare Slot eine Position und eine Größe:
}{
After definition, every visible slot receives a position and a size:
}

\begin{sourcecode}
  \positionltxtalkslot
    {my-section}{left}{center}{0.55\paperwidth}{0.8cm}
  \positionltxtalkslot
    {my-path}{center}{1cm}{2cm}{4cm}
\end{sourcecode}

\ldeen{
Das zweite und dritte Argument bezeichnen die horizontale und vertikale
Position innerhalb des Bereichs. Horizontal sind \code{left}, \code{center}
und \code{right}, vertikal \code{top}, \code{center} und \code{bottom}
zulässig. Stattdessen kann jeweils eine Länge ab der linken beziehungsweise
oberen Bereichskante angegeben werden. Breite und Höhe sind Längen; ein Slot
wird nicht automatisch vor Überlappungen mit anderen Slots geschützt.
}{
The second and third arguments specify horizontal and vertical positions
within the area. Horizontally, \code{left}, \code{center}, and \code{right}
are accepted; vertically, \code{top}, \code{center}, and \code{bottom}.
Alternatively, a dimension is measured from the left or top edge. Width and
height are dimensions; slots are not automatically protected from overlap.
}

\subsection{\ldeen{Slots gestalten}{Styling slots}}

\ldeen{
\cs*{styleltxtalkslot} bearbeitet die für den Slot angelegte Instanz des
Templates \code{lttheme-slot}. So bleiben Inhalt, Position und Gestaltung
voneinander getrennt.
}{
\cs*{styleltxtalkslot} edits the \code{lttheme-slot} template instance created
for a slot. Content, position, and styling therefore remain separate.
}

\begin{sourcecode}
  \styleltxtalkslot{my-section}{
    font = \large\bfseries,
    color = white,
    align = left,
    padding = 2mm,
    frame = box,
    rule-color = ltxtalk-accent,
    rule-thick = 0.8pt
  }
\end{sourcecode}

\ldeen{
Neben \code{font}, \code{color}, \code{align} und \code{padding} stehen
\code{background}, \code{frame}, \code{rule-color}, \code{rule-thick} und
\code{space-after} zur Verfügung. \code{frame} akzeptiert \code{none}, \code{box}, \code{top},
\code{bottom}, \code{left} und \code{right}. Die Schnittstelle kennt außerdem
die Optionen \code{rotate}, \code{opacity}, \code{shadow}, \code{uppercase}
und \code{lowercase}; diese haben derzeit keine sichtbare Wirkung. Auch einzelne Rahmenkanten
werden bei Slots noch nicht gezeichnet; verwenden Sie dort \code{box}
oder dekorieren Sie den gesamten Bereich.
}{
Besides \code{font}, \code{color}, \code{align}, and \code{padding}, the
keys \code{background}, \code{frame}, \code{rule-color}, \code{rule-thick},
and \code{space-after} are available. \code{frame} accepts \code{none},
\code{box}, \code{top}, \code{bottom}, \code{left}, and \code{right}. The
interface also contains \code{rotate}, \code{opacity}, \code{shadow},
\code{uppercase}, and \code{lowercase}; these currently have no visible effect. Individual slot frame edges
are not drawn either; use \code{box} or decorate the entire area instead.
}

\subsection{\ldeen{Bereiche dekorieren}{Decorating areas}}

\ldeen{
Hintergrundflächen und Trennlinien, die einen ganzen Bereich betreffen,
gehören nicht in einen Slot. Sie werden mit \cs*{decorateltxtalkarea} an der
Instanz des Templates \code{lttheme-area} eingestellt:
}{
Backgrounds and separator rules affecting an entire area do not belong in a
slot. Configure them on the \code{lttheme-area} template instance with
\cs*{decorateltxtalkarea}:
}

\begin{sourcecode}
  \decorateltxtalkarea{footer}{
    background = white,
    frame = top,
    rule-color = ltxtalk-primary,
    rule-thickness = 0.5pt,
    artifact-type = decorative
  }
\end{sourcecode}

\ldeen{
Für \code{frame} sind zusätzlich \code{topbottom} und die üblichen Seiten
zulässig. Die Dekoration wird vor den Slots des Bereichs gesetzt. Die Optionen
\code{background-opacity}, \code{shadow}, \code{shadow-color},
\code{shadow-offset}, \code{margin-top} und \code{margin-bottom} sind bereits
Teil der Schnittstelle, werden aber noch nicht vollständig gezeichnet.
}{
For \code{frame}, \code{topbottom} and the usual individual sides are also
accepted. The decoration is drawn before the area's slots. The keys
\code{background-opacity}, \code{shadow}, \code{shadow-color},
\code{shadow-offset}, \code{margin-top}, and \code{margin-bottom} are already
part of the interface but are not yet rendered completely.
}

\subsection{
  \ldeen
    {Vorhandene Themes erweitern}
    {Extending existing themes}
}
\label{sec:extend-themes}

\ldeen{Ein registriertes Theme kann auch nur zusätzliche Slots oder eine einzelne
Dekoration enthalten. Nach der Aktivierung des Basisthemes fügt
\cs{addltxtalktheme}\marg{\ldeen{Name}{name}} ein solches Teiltheme hinzu, ohne vorhandene
Slots zu löschen. Das Beispiel \code{example-switching.tex} ergänzt auf diese
Weise eine eigene Pfadnavigation. Das erneute Aktivieren eines Themes beginnt
dagegen bewusst mit einem leeren Theme-Zustand.}{A registered theme may
contain only additional slots or a single decoration. After activating the
base theme, \cs*{addltxtalktheme}\marg{\ldeen{Name}{name}} adds such a partial theme without
deleting existing slots. The \code{example-switching.tex} example adds
breadcrumb navigation in this way. Activating a full theme again deliberately
starts from an empty theme state.}

\begin{sourcecode}
  \useltxtalktheme{minimal}
  \addltxtalktheme{course-navigation}
\end{sourcecode}

\ldeen{
Ein Teiltheme sollte nur die Eigenschaften definieren, die es tatsächlich
ergänzt. Insbesondere darf es weder den Theme-Zustand leeren noch selbst den
Seitenstil wechseln. Slotnamen sollten einen paketspezifischen Präfix tragen,
damit sie nicht mit denen des Basisthemes kollidieren.
}{
A partial theme should define only the properties it actually adds. In
particular, it must neither clear the theme state nor select the page style
itself. Prefix slot names with a package-specific identifier to avoid
collisions with the base theme.
}

\subsection{\ldeen{Innere Elemente abstimmen}{Coordinating inner elements}}

\ldeen{Ein vollständiges Theme sollte nicht bei Kopf, Rändern und Fuß enden.
\cs*{styleltxtalkblock} stimmt normale, hervorgehobene und Beispielblöcke auf
die semantischen Farben ab; \cs*{setltxtalkitemize} wählt dazu passende
Listenmarken. Beide Befehle ändern nur die Darstellung der von
\cls{ltx-talk} bereitgestellten Strukturen.}{A complete theme should not stop
at the header, margins, and footer. \cs*{styleltxtalkblock} coordinates
normal, alert, and example blocks with the semantic colours, while
\cs*{setltxtalkitemize} selects matching list markers. Both commands change
only the appearance of structures provided by \cls{ltx-talk}.}

\subsection{\ldeen{Vollständiges Beispiel}{Complete example}}
\ldeen{Dieses Dokument fasst die Schritte zu einem kleinen Theme zusammen.
Es setzt den Folientitel im Inhaltsbereich und die Foliennummer im Fuß.
Der Registrierungscode kann später unverändert in ein eigenes Paket
verschoben werden; dieses lädt das Kernpaket mit \cs*{RequirePackage}.}
{This document combines the steps into a small theme. It places the frame
title in the content area and the slide number in the footer. The setup
registration can later move unchanged into a custom package, which loads
the core package with \cs*{RequirePackage}.}
\begin{example}[code-only,gobble=2]
  \DocumentMetadata{}
  \documentclass{ltx-talk}
  \usepackage{ltxtalk-theme}
  \RegisterLTXTalkTheme{my-theme}{
    \ltxtalksetup{footer=true,footer-height=0.7cm}
    \setltxtalkcolors{primary={model=HTML,value=005B50}}
    \defineltxtalkslot{my-title}{content}{frametitle}{}
    \positionltxtalkslot{my-title}{0pt}{0pt}{\textwidth}{1cm}
    \styleltxtalkslot{my-title}{
      font-slot=heading,font=\Large\bfseries,
      color=ltxtalk-primary,align=left
    }
    \defineltxtalkslot{my-page}{footer}{pagenumber}{}
    \DeclareLTXTalkAreaGrid{footer}{*,2cm}{1}
    \PositionLTXTalkSlotInGrid{my-page}{2}{1}{1}{1}
    \decorateltxtalkarea{footer}{
      frame=top,rule-color=ltxtalk-primary
    }
  }
  \useltxtalktheme{my-theme}
  \begin{document}
  \begin{frame}
    \frametitle{A custom theme}
    Content belongs to the presentation.
  \end{frame}
  \end{document}
\end{example}


\subsection{\ldeen{Empfehlungen}{Recommendations}}

\ldeen{
Semantische Slottypen sind eigenen Typen vorzuziehen. Dekorative Elemente
sollten als Artefakt, Navigation als solche und echte Überschriften mit einer
passenden Ebene beschrieben werden. Wiederkehrende Seitenelemente dürfen den
eigentlichen Frame-Inhalt und dessen Lesereihenfolge nicht duplizieren.
}{
Prefer semantic slot types to custom types. Mark decorative elements as
artifacts, navigation as navigation, and genuine headings with the appropriate
level. Repeated page elements must not duplicate the actual frame content or
its reading order.
}

\ldeen{
Themes sollten kurze und lange Inhalte, fehlende Metadaten, mehrzeilige
Kopfzeilen, beide Randbereiche sowie Folien mit und ohne Untertitel abdecken.
Für jedes Theme empfiehlt sich ein l3build-Sichttest; strukturelle Tests sollten
zusätzlich die getaggte Überschriftenhierarchie prüfen. Theme-spezifische
Logik bleibt im Theme-Paket, während \lttheme{} nur die allgemeinen Bereiche,
Slots, Templates und den Seitenstil bereitstellt.
}{
Themes should cover short and long content, missing metadata, multi-line
headers, both margin areas, and frames with and without subtitles. An l3build
visual test is recommended for every theme; structural tests should also check
the tagged heading hierarchy. Theme-specific logic remains in the theme
package, while \lttheme{} provides only the general areas, slots, templates,
and page style.
}


% ==========================================================================
% Reference
% ==========================================================================

\clearpage
\section{\ldeen{Referenz}{Reference}}
\label{ref:reference}
\subsection{\ldeen{Paketoptionen}{Package options}}
\ldeen{Geben Sie Optionen des Kernpakets vor dem ersten Theme-Paket an:}
{Specify core package options before loading the first theme package:}
\begin{sourcecode}
  \usepackage[block-hairlines=true]{ltxtalk-theme}
  \usepackage[shadow=true]{ltxtalk-theme-magpie}
  \useltxtalktheme{magpie}
\end{sourcecode}
\begin{options}
\keybool{outer-only}\Default{false}
\ldeen{Deaktiviert die Schriftpalettenverwaltung des Themes. Die Textrollen verwenden vorhandene LaTeX-Schriftfamilien. Eine Schriftpalette zu aktivieren erzeugt dann nur eine Warnung. Diese Option ist nur beim Laden verfügbar; die Anforderungen der Dokumentklasse gelten weiterhin.}{Disables theme font-palette management. Text roles use existing LaTeX font families. Activating a font palette then only issues a warning. Available at load time only; document-class requirements still apply.}
\keybool{block-hairlines}\Default{false}
\ldeen{Ergänzt bei der nächsten Theme-Aktivierung dünne Blocklinien. Auch über \cs*{ltxtalksetup} vor \cs*{useltxtalktheme} einstellbar.}{Adds thin block rules on the next theme activation. Also settable through \cs*{ltxtalksetup} before \cs*{useltxtalktheme}.}
\keybool{shadow}\Default{false}
\ldeen{Option ausschließlich von \pkg*{ltxtalk-theme-magpie}: aktiviert Schatten unter den Blöcken.}{An option of \pkg*{ltxtalk-theme-magpie} only: enables shadows beneath blocks.}
\end{options}

\subsection{\ldeen{Theme-Verwaltung}{Theme management}}

\begin{commands}
  \command{useltxtalktheme}[\marg{\ldeen{Name}{name}}]
  \ldeen{
    Aktiviert das registrierte Theme \meta{\ldeen{Name}{name}}. Der bisherige Theme-Zustand
    wird vollständig geleert. \code{default} stellt den Seitenstil der Klasse
    ohne lttheme-Slots wieder her.
  }{
    Activates the registered theme \meta{\ldeen{Name}{name}} and completely clears the
    previous theme state. \code{default} restores the class page style
    without lttheme slots.
  }

  \command{addltxtalktheme}[\marg{\ldeen{Name}{name}}]
  \ldeen{
    Führt die Setup-Anweisung eines registrierten Themes zusätzlich zum
    aktiven Theme aus, ohne vorhandene Slots zu löschen. Der Befehl dient vor
    allem zum Hinzufügen von Teilthemes.
  }{
    Executes the setup command of a registered theme in addition to the active
    theme without deleting existing slots. This command primarily adds partial
    themes.
  }

  \command{RegisterLTXTalkTheme}[\marg{\ldeen{Name}{name}}\marg{\ldeen{Setup-Code}{setup code}}]
  \ldeen{
    Registriert \meta{\ldeen{Setup-Code}{setup code}} unter \meta{\ldeen{Name}{name}}. Üblicherweise wird hier
    eine geschützte interne Anweisung des Theme-Pakets übergeben. Eine
    vorhandene Registrierung gleichen Namens wird ersetzt.
  }{
    Registers \meta{Setup code} under \meta{\ldeen{Name}{name}}. This is normally a
    protected internal command of the theme package. An existing registration
    with the same name is replaced.
  }
\end{commands}

\subsection{\ldeen{Layout-Konfiguration}{Layout configuration}}
\label{sec:ref-layout}

\begin{commands}
  \command{ltxtalksetup}[\marg{\ldeen{Optionen}{options}}]
  \ldeen{Ändert nur die angegebenen Eigenschaften und passt den Textbereich an. Die folgenden Vorgaben gelten vor der Theme-Aktivierung; ein Theme setzt eigene Werte.}{Changes only the specified properties and adjusts the text area. The defaults below apply before theme activation; themes set their own values.}

  \command{DeclareLTXTalkLayout}[\marg{\ldeen{Name}{name}}\marg{\ldeen{Optionen}{options}}\oarg{\ldeen{Aufbau-Code}{setup code}}]
  \command{UseLTXTalkLayout}[\marg{\ldeen{Name}{name}}\oarg{Overrides}]
  \ldeen{
    \cs*{DeclareLTXTalkLayout} registriert die Layoutkonfiguration.

    \cs*{UseLTXTalkLayout} aktiviert sie.
    \meta{\ldeen{Optionen}{options}} sind Schlüssel aus \code{ltxtalk / layout}; der optionale
    \meta{\ldeen{Aufbau-Code}{setup code}} kann Slots definieren, Flächen dekorieren oder eine
    Navigation binden. \cs*{UseLTXTalkLayout} wendet erst die gespeicherten
    Optionen an, dann die \meta{Overrides} desselben Schlüsselraums, dann den
    Aufbau-Code -- der Code sieht also die endgültigen Werte (etwa
    \cs*{LTXTalkHeaderRows}). Nicht genannte Schlüssel behalten ihren Wert,
    Layouts sind also additiv. Ein Theme darf mehrere Layouts deklarieren und
    pro Frame zwischen ihnen umschalten; \cs*{UseLTXTalkLayout} darf
    unmittelbar vor einem \env*{frame} oder als erste Anweisung darin stehen.
    Enthält der Aufbau-Code unbalancierte eckige Klammern, ist er zusätzlich
    in geschweifte Klammern einzuschließen.
  }{
    \cs*{DeclareLTXTalkLayout} registers the layout configuration.

    \cs*{UseLTXTalkLayout} activates it. \meta{\ldeen{Optionen}{options}}
    are keys from \code{ltxtalk / layout}; the optional \meta{\ldeen{Aufbau-Code}{setup code}} may
    define slots, decorate areas, or bind a navigation. \cs*{UseLTXTalkLayout}
    applies the stored options first, then the \meta{Overrides} in the same
    key space, then the setup code -- so the code sees the final values (such
    as \cs*{LTXTalkHeaderRows}). Keys not named keep their value, so layouts
    are additive. A theme may declare several layouts and switch between them
    per frame; \cs*{UseLTXTalkLayout} may be used immediately before a
    \env*{frame} or as its first command. If the setup code contains
    unbalanced square brackets, enclose it additionally in braces.
  }

  \command{LTXTalkBaseLeftMargin}
  \command{LTXTalkBaseRightMargin}
  \command{LTXTalkBaseTopMargin}
  \command{LTXTalkBaseBottomMargin}
  \command{LTXTalkCurrentLeftMargin}
  \command{LTXTalkCurrentRightMargin}
  \command{LTXTalkCurrentTopMargin}
  \command{LTXTalkCurrentBottomMargin}
  \ldeen{
    Expandierbare Längen für die ursprünglichen beziehungsweise aktuell
    wirksamen Seitenränder. Theme-Code kann damit ohne Zugriff auf interne
    Variablen an der Textkante ausrichten.
  }{
    Expandable lengths for the original and currently effective page margins.
    Theme code can use them to align content without accessing internals.
  }
\end{commands}

\begin{options}
\keybool{header}\Default{false}
\ldeen{Kopfbereich ein- oder ausschalten.}{Enables or disables the header.}
\keybool{left-margin}\Default{false}
\ldeen{Linker Randbereich ein- oder ausschalten.}{Enables or disables the left sidebar.}
\keybool{right-margin}\Default{false}
\ldeen{Rechter Randbereich ein- oder ausschalten.}{Enables or disables the right sidebar.}
\keybool{footer}\Default{false}
\ldeen{Fußbereich ein- oder ausschalten.}{Enables or disables the footer.}
\keyval{header-height}{\ldeen{Länge}{length}}\Default{1.5cm}
\ldeen{Höhe des Kopfbereichs.}{Height of the header.}
\keyval{footer-height}{\ldeen{Länge}{length}}\Default{1cm}
\ldeen{Höhe des Fußbereichs.}{Height of the footer.}
\keyval{margin-width}{\ldeen{Länge}{length}}\Default{2.5cm}
\ldeen{Setzt beide Randbreiten und beide Inhaltseinzüge gleichzeitig. Nachfolgende Einzelschlüssel überschreiben diese Werte.}{Sets both sidebar widths and both content insets together. Subsequent individual keys override these values.}
\keyval{left-area-width}{\ldeen{Länge}{length}}\Default{2.5cm}
\ldeen{Breite des linken Randbereichs.}{Width of the left sidebar.}
\keyval{right-area-width}{\ldeen{Länge}{length}}\Default{2.5cm}
\ldeen{Breite des rechten Randbereichs.}{Width of the right sidebar.}
\keyval{content-inset-left}{\ldeen{Länge}{length}}\Default{2.5cm}
\ldeen{Linker Inhaltseinzug bei aktivem Randbereich.}{Left content inset when the sidebar is enabled.}
\keyval{content-inset-right}{\ldeen{Länge}{length}}\Default{2.5cm}
\ldeen{Rechter Inhaltseinzug bei aktivem Randbereich.}{Right content inset when the sidebar is enabled.}
\keyval{header-rows}{\ldeen{Ganzzahl}{integer}}\Default{1}
\ldeen{Über \cs*{LTXTalkHeaderRows} abrufbare Zeilenzahl für Layout-Aufbaucode. Ändert ein Bereichsraster nicht von selbst.}{Row count accessible through \cs*{LTXTalkHeaderRows} for layout setup code. Does not change an area grid by itself.}
\keyval{header-columns}{\ldeen{Liste}{list}}\Default{\{0.2,0.6,0.2\}}
\ldeen{Ältere Schnittstelle; ohne Wirkung auf frei positionierte Slots.}{Legacy interface; no effect on freely positioned slots.}
\keyval{footer-columns}{\ldeen{Liste}{list}}\Default{\{0.33,0.34,0.33\}}
\ldeen{Ältere Schnittstelle; verwenden Sie für neue Layouts Bereichsraster.}{Legacy interface; use area grids for new layouts.}
\keybool{block-hairlines}\Default{false}
\ldeen{Globale Voreinstellung für die nächste Theme-Aktivierung, keine Geometrieangabe.}{Global preference for the next theme activation, not a geometry setting.}
\end{options}

\subsection{\ldeen{Metadaten}{Metadata}}

\begin{commands}
  \command{LTXTalkMetadata}[\marg{\ldeen{Feld}{field}}]
  \command{UseLTXTalkMetadata}[\oarg{\ldeen{Optionen}{options}}\marg{\ldeen{Feld}{field}}]
  \ldeen{
    Liefert Präsentationsmetadaten über eine öffentliche Schnittstelle.
    Verfügbare Felder sind \code{title}, \code{short-title}, \code{subtitle},
    \code{short-subtitle}, \code{author}, \code{short-author},
    \code{institute}, \code{short-institute}, \code{date},
    \code{short-date}, \code{section}, \code{subsection},
    \code{frametitle}, \code{framesubtitle}, \code{framenumber} und
    \code{totalframes}. Die zweite Form akzeptiert \code{lines=1}, um
    erzwungene Zeilenumbrüche durch \code{linebreak} (standardmäßig ein
    Leerzeichen) zu ersetzen.
  }{
    Provides presentation metadata through a public interface. Available
    fields are \code{title}, \code{short-title}, \code{subtitle},
    \code{short-subtitle}, \code{author}, \code{short-author},
    \code{institute}, \code{short-institute}, \code{date},
    \code{short-date}, \code{section}, \code{subsection},
    \code{frametitle}, \code{framesubtitle}, \code{framenumber}, and
    \code{totalframes}. The second form accepts \code{lines=1} to replace
    forced line breaks with \code{linebreak}, which defaults to a space.
  }
\end{commands}

\ldeen{\cs*{LTXTalkMetadata} ist expandierbar. Verwenden Sie
\cs*{UseLTXTalkMetadata} zum Setzen mit folgenden Ausgabeoptionen:}
{\cs*{LTXTalkMetadata} is expandable. Use \cs*{UseLTXTalkMetadata} for
output with the following options:}
\begin{options}
\keychoice{lines}{all,1}\Default{all}
\ldeen{Behält Zeilenumbrüche bei oder ersetzt sie für einzeilige Ausgabe.}
{Retains line breaks or replaces them for single-line output.}
\keyval{linebreak}{\ldeen{Ersatz}{replacement}}\Default{\ldeen{Leerzeichen}{space}}
\ldeen{Ersatz für erzwungene Umbrüche bei \code{lines=1}.}
{Replacement for forced breaks with \code{lines=1}.}
\end{options}
\begin{sourcecode}
  \UseLTXTalkMetadata[lines=1,linebreak={ -- }]{short-title}
\end{sourcecode}

\subsection{\ldeen{Navigation}{Navigation}}
\label{sec:ref-navigation}

\begin{commands}
  \command{LTXTalkNavigation}[\marg{\ldeen{Name}{name}}]
  \command{DeclareLTXTalkNavigation}[\marg{\ldeen{Name}{name}}\marg{Code}]
  \ldeen{
    \cs*{LTXTalkNavigation} setzt einen benannten Navigations-Renderer --
    gedacht als Slot-Inhalt im Aufbau-Code eines Layouts oder Themes.
    \cs*{DeclareLTXTalkNavigation} registriert einen eigenen Renderer;
    \meta{Code} wird bei jedem Aufruf ausgeführt und kann beispielsweise \cs*{LTXTalkMetadata} verwenden.

    Mitgeliefert:
    \begin{itemize}
      \item \code{current-section}, \code{current-subsection} -- Titel des
        aktuellen Abschnitts bzw.\ Unterabschnitts; ein Durchlauf genügt.
      \item \code{section-list} -- alle Abschnitte in Dokumentreihenfolge,
        nebeneinander.
      \item \code{subsection-list} -- die Unterabschnitte des aktuellen
        Abschnitts, nebeneinander.
      \item \code{toc} -- Abschnitte untereinander, unter dem aktuellen
        seine Unterabschnitte eingerückt.
      \item \code{section-dots} -- ein Punkt je Abschnitt (aktueller gefüllt,
        zurückliegende gedämpft, folgende offen).
      \item \code{section-progress} -- \enquote{\meta{Position} /
        \meta{Anzahl}}.
    \end{itemize}
    Der jeweils aktuelle Eintrag steht in \code{ltxtalk-primary}, die
    übrigen gedämpft.

    Die Navigation verwendet die Abschnittsstruktur aus dem vorherigen
    LaTeX-Lauf. Alle Renderer außer \code{current-section}
    und \code{current-subsection} brauchen also zwei Läufe; ändert sich die
    Struktur, mahnt lttheme einen weiteren Lauf an. Abschnittstitel mit
    Auszeichnung erscheinen als Klartext, da sie ein bewegliches Argument
    sind.
  }{
    \cs*{LTXTalkNavigation} typesets a named navigation renderer -- intended
    as slot content in the setup code of a layout or theme.
    \cs*{DeclareLTXTalkNavigation} registers a custom renderer; \meta{Code}
    runs on every call and can use \cs*{LTXTalkMetadata}, for example.

    Bundled:
    \begin{itemize}
      \item \code{current-section}, \code{current-subsection} -- title of the
        current section or subsection; one pass suffices.
      \item \code{section-list} -- every section in document order, side by
        side.
      \item \code{subsection-list} -- the current section's subsections, side
        by side.
      \item \code{toc} -- sections one per line, the current section's
        subsections indented below it.
      \item \code{section-dots} -- one dot per section (current filled, past
        dimmed, upcoming open).
      \item \code{section-progress} -- \enquote{\meta{position} /
        \meta{count}}.
    \end{itemize}
    The current entry is set in \code{ltxtalk-primary}, the rest dimmed.

    Navigation uses the section structure from the preceding LaTeX run. Every renderer except \code{current-section} and
    \code{current-subsection} therefore needs two passes; if the structure
    changes, lttheme asks for another run. Section titles with markup appear
    as plain text, being a moving argument.
  }
\end{commands}

\subsection{\ldeen{Inhaltselemente}{Content elements}}
\label{sec:ref-elements}

\begin{commands}
  \command{InsertLTXTalkElement}[\marg{\ldeen{Name}{name}}]
  \ldeen{
    Setzt eine benannte Instanz des Template-Typs \code{ltxtalk-element} --
    gedacht für einzelne, formatierbare Inhaltswerte wie Seitenzahlen oder
    Abschnittsüberschriften, im Unterschied zu \cs*{LTXTalkNavigation}s
    Renderern für die \emph{gesamte} Abschnittsfolge. Die getaggte Rolle
    kommt, wie bei jedem anderen Slotinhalt, vom vierten Argument des
    umgebenden \cs*{defineltxtalkslot} (Abschnitt~\ref{sec:ref-accessibility}
    behandelt entsprechend die Tagging-Optionen der Slots).

    Mitgeliefert:
    \begin{itemize}
      \item \code{pagenumber}, \code{totalframes} -- aktuelle Foliennummer
        beziehungsweise Gesamtzahl.
      \item \code{pagenumber-of-total} -- \enquote{\meta{Foliennummer} /
        \meta{Gesamtzahl}}.
      \item \code{section-pagenumber} -- \enquote{\meta{Abschnittstitel} --
        \meta{Foliennummer}}.
      \item \code{sectionheading}, \code{subsectionheading} -- nummerierter
        Abschnitts- beziehungsweise Unterabschnittstitel.
    \end{itemize}
    Jede eingebaute Instanz verwendet eine von drei Schablonen und lässt
    sich mit \cs{EditInstance}\allowbreak\Marg{ltxtalk-element}\allowbreak\Marg{Name}\Marg{Schlüssel}
    anpassen:
    \begin{itemize}
      \item \code{counter}: Schlüssel \code{source} (der auszugebende Wert).
      \item \code{fraction}: Schlüssel \code{left}, \code{right},
        \code{separator}.
      \item \code{heading}: Schlüssel \code{numbered} (boolesch),
        \code{level}, \code{number}, \code{text}, \code{separator}. Mit
        \code{level} (\code{section}, \code{subsection} oder
        \code{subsubsection}) entfällt die Nummer, solange die aktuelle
        Überschrift dieser Ebene unnummeriert ist (\cs*{section*}).
    \end{itemize}
    Neue Instanzen -- auch mit einer dieser drei Schablonen, nur mit anderen
    Werten -- entstehen wie bei jedem anderen Template-Typ über
    \cs{DeclareInstance}\allowbreak\Marg{ltxtalk-element}\allowbreak\Marg{Name}\Marg{Schablone}\Marg{Schlüssel}.
  }{
    Typesets a named instance of the \code{ltxtalk-element} template type --
    intended for single, formattable content values such as page numbers or
    section headings, as opposed to \cs*{LTXTalkNavigation}'s renderers for
    the \emph{whole} section sequence. The tagged role comes, like for any
    other slot content, from the surrounding \cs*{defineltxtalkslot}'s
    fourth argument (Section~\ref{sec:ref-accessibility} covers the slots'
    tagging options accordingly).

    Bundled:
    \begin{itemize}
      \item \code{pagenumber}, \code{totalframes} -- current frame number
        and total count.
      \item \code{pagenumber-of-total} -- \enquote{\meta{frame number} /
        \meta{total count}}.
      \item \code{section-pagenumber} -- \enquote{\meta{section title} --
        \meta{frame number}}.
      \item \code{sectionheading}, \code{subsectionheading} -- numbered
        section or subsection title.
    \end{itemize}
    Every built-in instance uses one of three templates and can be adjusted
    with \cs{EditInstance}\allowbreak\Marg{ltxtalk-element}\allowbreak\Marg{name}\Marg{keys}:
    \begin{itemize}
      \item \code{counter}: key \code{source} (the value to output).
      \item \code{fraction}: keys \code{left}, \code{right},
        \code{separator}.
      \item \code{heading}: keys \code{numbered} (Boolean), \code{level},
        \code{number}, \code{text}, \code{separator}. With \code{level}
        (\code{section}, \code{subsection}, or \code{subsubsection}) the
        number is omitted while the current heading of that level is
        unnumbered (\cs*{section*}).
    \end{itemize}
    New instances -- even reusing one of these three templates with just
    different values -- are created like for any other template type, via
    \cs{DeclareInstance}\allowbreak\Marg{ltxtalk-element}\allowbreak\Marg{name}\Marg{template}\Marg{keys}.
  }
\end{commands}

\begin{sourcecode}
  \defineltxtalkslot{my-page}{footer}{custom}{role=navigation}
  \setltxtalkslotcontent{my-page}{\InsertLTXTalkElement{pagenumber-of-total}}
  \EditInstance{ltxtalk-element}{pagenumber-of-total}{separator = { of }}
\end{sourcecode}

\subsection{\ldeen{Farbkonfiguration}{Colour configuration}}

\begin{commands}
  \command{setltxtalkcolors}[\marg{\ldeen{Farben}{colours}}]
  \ldeen{
    Definiert die semantischen Farben \code{primary}, \code{secondary},
    \code{accent}, \code{text}, \code{background}, \code{structure},
    \code{alert} und \code{example}. Jeder Wert hat die Form
    \code{model=...,~value=...}, beispielsweise
    \code{primary=\{model=HTML,~value=005B50\}}. Die zugehörigen Farbnamen lauten
    \code{ltxtalk-primary}, \code{ltxtalk-secondary}, \code{ltxtalk-accent},
    \code{ltxtalk-text}, \code{ltxtalk-bg}, \code{ltxtalk-structure},
    \code{ltxtalk-alert} und \code{ltxtalk-example}. Die letzten drei werden
    zugleich auf die Klassennamen \code{structure}, \code{alert} und
    \code{example} abgebildet.
  }{
    Defines the semantic colours \code{primary}, \code{secondary},
    \code{accent}, \code{text}, \code{background}, \code{structure},
    \code{alert}, and \code{example}. Each value has the form
    \code{model=...,~value=...}. Their colour names use the
    \code{ltxtalk-} prefix, with \code{ltxtalk-bg} for the background. The
    final three are also mapped to the class colour names \code{structure},
    \code{alert}, and \code{example}.
  }
\end{commands}

\subsection{\ldeen{Schriftkonfiguration}{Font configuration}}

\begin{commands}
  \command{DeclareLTXTalkFontPalette}[\marg{\ldeen{Name}{name}}\marg{\ldeen{Schriften}{fonts}}]
  \command{UseLTXTalkFontPalette}[\marg{\ldeen{Name}{name}}]
  \ldeen{
    Deklariert beziehungsweise aktiviert eine Schriftpalette. Die portablen
    Slots heißen \code{main}, \code{companion}, \code{display},
    \code{accent}, \code{mono}, \code{math} und \code{symbol}. Eine Ressource
    hat die Form \code{font=\{...\}} mit optionalen \code{features}; alternativ
    verweist \code{alias=...} auf einen anderen Slot. \code{main} ist Pflicht.
    Die mitgelieferte Palette \code{ltxtalk-default} verwendet New Computer
    Modern Sans und Latin Modern Mono.
  }{
    Declares or activates a font palette. Its portable slots are \code{main},
    \code{companion}, \code{display}, \code{accent}, \code{mono}, \code{math},
    and \code{symbol}. A resource has the form \code{font=\{...\}}, optionally
    with \code{features}; alternatively, \code{alias=...} refers to another
    slot. \code{main} is required. The bundled \code{ltxtalk-default} palette
    uses New Computer Modern Sans with Latin Modern Mono.
  }
  \command{UseLTXTalkFont}[\marg{\ldeen{Rolle}{role}}]
  \ldeen{
    Wählt eine Textschrift über ihre semantische Rolle. Verfügbar sind
    \code{body}, \code{support}, \code{heading}, \code{emphasis},
    \code{code} und \code{symbol}. Die technischen Palettennamen
    \code{main}, \code{companion}, \code{display}, \code{accent} und
    \code{mono} werden ebenfalls akzeptiert. \code{math} bezeichnet nur
    eine Ressource und kann nicht als Textschrift gewählt werden.
  }{
    Selects a text face by semantic role. The roles are \code{body},
    \code{support}, \code{heading}, \code{emphasis}, \code{code}, and
    \code{symbol}. The technical palette names \code{main},
    \code{companion}, \code{display}, \code{accent}, and \code{mono} are
    accepted as well. \code{math} names a resource only and cannot be
    selected as a text face.
  }
\end{commands}

\ldeen{Die Rollen sind feste Namen für die Paletteneinträge:}
{Roles are fixed names for palette entries:}
\begin{center}
\begin{tabular}{ll}
\textbf{\ldeen{Rolle}{Role}} & \textbf{\ldeen{Paletteneintrag}{Palette entry}}\\\hline
\code{body} & \code{main}\\
\code{support} & \code{companion}\\
\code{heading} & \code{display}\\
\code{emphasis} & \code{accent}\\
\code{code} & \code{mono}\\
\code{symbol} & \code{symbol}\\
\end{tabular}
\end{center}
\begin{sourcecode}
  \DeclareLTXTalkFontPalette{my-fonts}{
    main = {font={Latin Modern Sans}},
    companion = {alias=main},
    display = {alias=companion},
    accent = {alias=display},
    mono = {font={Latin Modern Mono}},
    symbol = {alias=main}
  }
  \UseLTXTalkFontPalette{my-fonts}
\end{sourcecode}
\ldeen{Schriftnamen müssen in der TeX-Installation verfügbar sein.
\code{features} enthält Schriftoptionen für \pkg*{fontspec}.
Vollständige Angaben zu fehlenden Einträgen, Aliasauflösung und
Mathematikschriften stehen in der Schriftpalettenreferenz von
\pkg*{osgstyler}; die beiden Palettenbefehle verwenden diese Schnittstelle.
Mit der Ladeoption \code{outer-only=true} ist die Palettenauswahl deaktiviert.}
{Font names must be available in the TeX installation. \code{features}
contains \pkg*{fontspec} font options. See the \pkg*{osgstyler} font-palette
reference for omitted entries, alias resolution, and mathematical fonts;
the two palette commands use that interface. Palette selection is disabled
with the load option \code{outer-only=true}.}

\subsection{\ldeen{Inneres Theme}{Inner theme}}

\begin{commands}
  \command{styleltxtalkblock}[\marg{\ldeen{Typ}{type}}\marg{\ldeen{Optionen}{options}}]
  \ldeen{
    Bearbeitet die Instanz \code{block}, \code{alertblock} oder
    \code{exampleblock} des Template-Typs \code{osgstyler-block}
    (bereitgestellt von \pkg*{osgstyler}). Die
    Standard-Schnittstelle umfasst \code{background}, \code{rule-color},
    \code{rule-thickness}, \code{padding}, \code{corner-radius},
    \code{shadow}, \code{shadow-offset}, \code{before} und \code{after}.
    Fertige Optiken liegen als \pkg*{osgstyler}-Traits vor: \code{card}
    (leicht gerahmte, zart getönte Box mit fettem Titel), \code{titlebar}
    (Beamers Madrid: voller Farbbalken über getönter Body-Fläche mit
    Unterkante), \code{heading} (nur farbiger Titel, fließend),
    \code{soft} (Titel mit dünnen Linien, fließend), \code{plain}
    (rahmenlos) sowie \code{framed}/\code{filled} (Rahmen ohne bzw.\ mit
    Tönung). \code{heading}, \code{soft} und \code{plain} lassen das Tagging
    der Klasse unangetastet; die übrigen sind echte Kästen und fügen im
    getaggten PDF genau ein \code{Div} je Block hinzu. Ohne Aufruf
    verwendet lttheme den Trait \code{card}, sodass ein Block stets
    erkennbar ist; \code{magpie} und \code{bluebird} setzen \code{titlebar},
    \code{hawk}, \code{sparrow} und \code{goose} \code{heading} -- jeweils
    in der Themefarbe. Die Ladeoption \option{block-hairlines} (oder
    \cs*{ltxtalksetup}) schaltet bei allen Themes dünne Trennlinien dazu
    (Rahmen beim Kasten, Kopf-/Fußlinie beim reinen Titel). Ein Blockstil
    wird beim Theme-Wechsel auf den \code{card}-Standard zurückgesetzt.
  }{
    Edits the \code{block}, \code{alertblock}, or \code{exampleblock}
    instance of the \code{osgstyler-block} template type provided by
    \pkg*{osgstyler}. The standard interface includes \code{background},
    \code{rule-color}, \code{rule-thickness}, \code{padding},
    \code{corner-radius}, \code{shadow}, \code{shadow-offset},
    \code{before}, and \code{after}. Ready-made looks are available as
    \pkg*{osgstyler} traits: \code{card} (a lightly framed, faintly tinted
    box with a bold title), \code{titlebar} (beamer's Madrid: a full colour
    bar over a tinted body area with a bottom edge), \code{heading}
    (a coloured title only, flowing), \code{soft} (a title with thin rules,
    flowing), \code{plain} (frameless), and \code{framed}/\code{filled}
    (a frame without / with a tint). \code{heading}, \code{soft} and
    \code{plain} leave the class's tagging untouched; the rest are real
    boxes and add exactly one \code{Div} per block in tagged PDF. Without a
    call lttheme uses the \code{card} trait, so a block is always
    recognisable; \code{magpie} and \code{bluebird} use \code{titlebar},
    \code{hawk}, \code{sparrow} and \code{goose} use \code{heading} -- each
    in the theme colour. The load option \option{block-hairlines} (or
    \cs*{ltxtalksetup}) adds thin dividing rules for every theme (a border
    on the box, head/foot rules on the plain title). A block style is reset
    to the \code{card} default on a theme switch.
  }

  \command{setltxtalkitemize}[\marg{\ldeen{Optionen}{options}}]
  \ldeen{
    Setzt mit \code{level-1} bis \code{level-4} das Aufzählungszeichen der
    jeweiligen \code{itemize}-Ebene. Es wird nur die visuelle Marke geändert;
    Listen- und Listenelement-Tags der Klasse bleiben unverändert.
  }{
    Sets the item marker for each \code{itemize} level with \code{level-1}
    through \code{level-4}. Only the visual marker changes; the class's list
    and list-item tags remain unchanged.
  }
\end{commands}

\subsection{\ldeen{Slot-Definition}{Slot definition}}

\begin{commands}
  \command{defineltxtalkslot}
    [\marg{\ldeen{Name}{name}}\marg{\ldeen{Bereich}{area}}\marg{\ldeen{Typ}{type}}\marg{\ldeen{Optionen für Barrierefreiheit}{accessibility fields}}]
  \ldeen{
    Definiert einen Slot und fügt ihn am Ende des angegebenen Bereichs ein.
    Eine erneute Definition ersetzt seine Zuordnung und ordnet ihn dort
    erneut am Ende ein; sie erzeugt keinen zweiten Slot gleichen Namens.
    Gültige Standardbereiche sind \code{header}, \code{left}, \code{content},
    \code{right} und \code{footer}. Vordefinierte Typen sind \code{title}, \code{subtitle},
    \code{author}, \code{date}, \code{institute}, \code{section},
    \code{subsection}, \code{frametitle}, \code{framesubtitle},
    \code{pagenumber}, \code{logo} und \code{custom}.
  }{
    Defines a slot and appends it to the specified area. Redefinition replaces
    its assignment and moves it to the end of that area; it does not create
    a second slot with the same name. Standard areas are
    \code{header}, \code{left}, \code{content}, \code{right}, and
    \code{footer}. Predefined types are \code{title}, \code{subtitle}, \code{author},
    \code{date}, \code{institute}, \code{section}, \code{subsection},
    \code{frametitle}, \code{framesubtitle}, \code{pagenumber}, \code{logo},
    and \code{custom}.
  }

  \command{setltxtalkslotcontent}[\marg{\ldeen{Name}{name}}\marg{\ldeen{Inhalt}{content}}]
  \ldeen{
    Hinterlegt den auszuführenden Inhalt eines freien Slots. Er wird für
    \code{custom}, \code{logo} und nicht vordefinierte eigene Typen verwendet.
  }{
    Stores the executable content of a free slot. It is used for
    \code{custom}, \code{logo}, and non-predefined custom types.
  }
\end{commands}

\begin{table}[ht]
\centering
\begin{tabular}{lll}
\hline
\textbf{\ldeen{Typ}{Type}} & \textbf{\ldeen{Beschreibung}{Description}}
  & \textbf{\ldeen{Mögliche Rolle}{Possible role}} \\
\hline
\texttt{frametitle}    & \ldeen{Folientitel}{Frame title}        & heading (H2)     \\
\texttt{framesubtitle} & \ldeen{Folienuntertitel}{Frame subtitle} & heading (H3)     \\
\texttt{title}         & \ldeen{Präsentationstitel}{Presentation title} & heading (H1) \\
\texttt{section}       & \ldeen{Aktueller Abschnitt}{Current section} & heading (H2) \\
\texttt{subsection}    & \ldeen{Aktueller Unterabschnitt}{Current subsection} & heading (H3) \\
\texttt{author}        & \ldeen{Autor}{Author name}        & note             \\
\texttt{date}          & \ldeen{Datum}{Date}               & note             \\
\texttt{institute}     & \ldeen{Institut}{Institute name}  & note             \\
\texttt{pagenumber}    & \ldeen{Foliennummer}{Page number} & navigation       \\
\texttt{logo}          & Logo                                & artifact         \\
\texttt{custom}        & \ldeen{Frei definiert}{User-defined} & artifact       \\
\hline
\end{tabular}
\caption{\ldeen{Vordefinierte Slottypen}{Predefined slot types}}
\label{tab:template-variables}
\end{table}
\ldeen{Die Rollen in der Tabelle sind Beispiele, keine Vorgaben des Slottyps. Ohne explizite Rolle gilt \code{artifact}; eine Ausnahme ist \code{frametitle}, dessen Tagging die Klasse übernimmt.}{The roles in the table are examples, not defaults imposed by the slot type. Without an explicit role, \code{artifact} applies; \code{frametitle} is an exception, with tagging provided by the class.}

\Needspace{8\baselineskip}
\subsection{\ldeen{Slot-Positionierung}{Slot positioning}}

\begin{commands}
  \command{positionltxtalkslot}
    [\marg{\ldeen{Name}{name}}\marg{x}\marg{y}\marg{\ldeen{Breite}{width}}\marg{\ldeen{Höhe}{height}}]
  \ldeen{
    Positioniert den Slot relativ zu seinem Bereich. Für \meta{x} sind
    \code{left}, \code{center}, \code{right} oder eine Länge zulässig; für
    \meta{y} entsprechend \code{top}, \code{center}, \code{bottom} oder eine
    Länge. Positive Längen werden von der linken beziehungsweise oberen Kante
    gemessen.
  }{
    Positions a slot relative to its area. For \meta{x}, \code{left},
    \code{center}, \code{right}, or a dimension is accepted; for \meta{y},
    use \code{top}, \code{center}, \code{bottom}, or a dimension. Positive
    dimensions are measured from the left or top edge.
  }

  \command{DeclareLTXTalkAreaGrid}
    [\marg{\ldeen{Bereich}{area}}\marg{\ldeen{Spalten}{columns}}\marg{\ldeen{Zeilen}{rows}}]
  \command{PositionLTXTalkSlotInGrid}
    [\marg{\ldeen{Name}{name}}\marg{\ldeen{Spalte}{column}}\marg{\ldeen{Zeile}{row}}\marg{\ldeen{Spaltenanzahl}{column span}}\marg{\ldeen{Zeilenanzahl}{row span}}]
  \command{SetLTXTalkAreaGridRows}[\marg{\ldeen{Bereich}{area}}\marg{\ldeen{Zeilen}{rows}}]
  \ldeen{
    Definiert ein Raster für einen Bereich und positioniert Slots darin.
    Spalten sind kommagetrennte Längen; \code{*} verteilt den verbleibenden
    Platz gleichmäßig auf alle Sternspalten. Spalten und Zeilen werden ab eins
    gezählt. Die letzten beiden Argumente der Positionierung sind die Anzahl
    überspannter Spalten und Zeilen, keine Längen.
    Die Rasterdefinition und Änderungen der Zeilenzahl sind global;
    eine TeX-Gruppe oder das Frame-Ende nimmt sie nicht zurück.
    Stellen Sie für die nächste Folie die gewünschte Zeilenzahl explizit ein.
  }{
    Defines a grid for an area and positions slots in it. Columns are a
    comma-separated list of lengths; \code{*} distributes the remaining
    width equally among all star columns. Columns and rows are one-based. The final two positioning arguments are the numbers of columns and rows
    spanned, not dimensions. Grid declarations and row-count changes are
    global; a TeX group or the end of a frame does not undo them. Set the
    desired row count explicitly for the next slide.
  }
\end{commands}

\subsection{\ldeen{Titelseiten}{Title pages}}
\label{sec:ref-title-pages}

\begin{commands}
  \command{DeclareLTXTalkTitleLayout}
    [\marg{\ldeen{Name}{name}}\marg{\ldeen{Layoutoptionen}{layout options}}\marg{\ldeen{Inhalt}{content}}]
  \command{UseLTXTalkTitleLayout}[\marg{\ldeen{Name}{name}}]
  \command{MakeLTXTalkTitle}[\oarg{\ldeen{Name}{name}}]
  \ldeen{
    \cs*{DeclareLTXTalkTitleLayout} registriert eine Titelseitenvariante
    aus temporären Layoutoptionen und ihrem Inhalt. \cs*{UseLTXTalkTitleLayout} wählt die Vorgabe;
    \cs*{MakeLTXTalkTitle} erzeugt den Frame und kann optional eine Variante
    nur für diesen Aufruf wählen. Nach der Titelseite wird die vorherige
    Geometrie wiederhergestellt. Das Theme \code{bluebird} bringt mit
    \code{bluebird/band} eine solche Variante mit; \cls{ltx-talk}s
    \cs*{maketitle} bleibt davon unberührt.
  }{
    \cs*{DeclareLTXTalkTitleLayout} registers a title-page variant
    consisting of temporary layout options and its contents. \cs*{UseLTXTalkTitleLayout} selects the default;
    \cs*{MakeLTXTalkTitle} creates the frame and can optionally select a
    variant for that invocation. The previous geometry is restored after the
    title page. The \code{bluebird} theme ships one such variant as
    \code{bluebird/band}; \cls{ltx-talk}'s own \cs*{maketitle} is unaffected.
  }
  \command{LTXTalkHeaderRows}
  \command{IfLTXTalkTitlePageTF}[\marg{\ldeen{Titelseitencode}{title-page code}}\marg{\ldeen{Framecode}{frame code}}]
  \ldeen{
    Liefert Theme-Autoren die aktuell wirksame Zahl der Kopfzeilen bzw.
    unterscheidet eine von \cs*{MakeLTXTalkTitle} erzeugte Titelseite von
    einem gewöhnlichen Frame. Beide Schnittstellen bleiben auch dann gültig,
    wenn die Basisklasse den Seitenkopf erst beim Ausschiffen aufbaut.
  }{
    Gives theme authors the effective number of header rows and distinguishes
    a title page created by \cs*{MakeLTXTalkTitle} from an ordinary frame.
    Both interfaces remain valid when the base class defers construction of
    the running head until shipout.
  }
\end{commands}

\subsection{\ldeen{Slot-Gestaltung}{Slot styling}}

\begin{commands}
  \command{styleltxtalkslot}[\marg{\ldeen{Name}{name}}\marg{\ldeen{Optionen}{options}}]
\ldeen{Ändert die angegebenen Eigenschaften der Slot-Instanz. Nicht genannte Eigenschaften behalten ihren bisherigen Wert. Die Vorgaben unten gelten für eine neue Instanz; Themes setzen eigene Werte.}{Changes the specified properties of the slot instance. Omitted properties keep their previous values. Defaults below apply to new instances; themes set their own values.}
\end{commands}
\begin{options}
\keyval{font-slot}{\ldeen{Rolle}{role}}\Default{companion}
\ldeen{Schriftrolle: \code{body}, \code{support}, \code{heading}, \code{emphasis}, \code{code}, \code{symbol} oder ein entsprechender Palettenname. \code{math} ist keine Textschrift.}{Font role: \code{body}, \code{support}, \code{heading}, \code{emphasis}, \code{code}, \code{symbol}, or the corresponding palette name. \code{math} is not a text font.}
\keyval{font}{\ldeen{Befehle}{commands}}\Default{\ldeen{leer}{empty}}
\ldeen{Zusätzliche Schriftbefehle, etwa \cs*{Large}\cs*{bfseries}; werden nach der Schriftrolle angewandt.}{Additional font commands, such as \cs*{Large}\cs*{bfseries}, applied after the font role.}
\keyval{color}{\ldeen{Farbe}{colour}}\Default{ltxtalk-text}
\ldeen{Textfarbe.}{Text colour.}
\keyval{background}{\ldeen{Farbe}{colour}}\Default{none}
\ldeen{Hintergrundfarbe oder \code{none}. Bei \code{frame=box} ergibt \code{none} einen weißen Hintergrund.}{Background colour or \code{none}. With \code{frame=box}, \code{none} gives a white background.}
\keybool{background-fill}\Default{false}
\ldeen{Füllt bei gesetztem Hintergrund die deklarierte Slotfläche statt nur die Textfläche. Bei einem Boxrahmen gilt dessen Darstellung.}{With a background colour, fills the declared slot area instead of only the text area. Box frames use their own rendering.}
\keychoice{align}{left,center,right}\Default{center}
\ldeen{Horizontale Textausrichtung.}{Horizontal text alignment.}
\keychoice{frame}{none,box,top,bottom,left,right}\Default{none}
\ldeen{\code{box} zeichnet einen Rahmen. Die einzelnen Kantenwerte werden angenommen, zeichnen im aktuellen Slotrenderer aber keine Linie.}{\code{box} draws a frame. Individual edge values are accepted but do not draw a rule in the current slot renderer.}
\keyval{padding}{\ldeen{Länge}{length}}\Default{0pt}
\ldeen{Innenabstand bei Farbflächen und Boxrahmen.}{Inset for colour backgrounds and box frames.}
\keyval{rule-color}{\ldeen{Farbe}{colour}}\Default{ltxtalk-primary}
\ldeen{Rahmenfarbe.}{Frame colour.}
\keyval{rule-thick}{\ldeen{Länge}{length}}\Default{0.4pt}
\ldeen{Linienstärke des Boxrahmens. Anders als bei Bereichen heißt dieser Schlüssel nicht \code{rule-thickness}.}{Box-frame rule width. Unlike area decoration, this key is named \code{rule-thick}, not \code{rule-thickness}.}
\keyval{space-after}{\ldeen{Länge}{length}}\Default{0pt}
\ldeen{Abstand unter einem Titel-Slot im Inhaltsbereich. Positive Werte setzen den Abstand; sonst gilt \code{0.4\string\baselineskip} in der Slotschrift. Ohne Wirkung auf absolut positionierte Slots.}{Gap below a title slot in the content area. Positive values set the gap; otherwise it is \code{0.4\string\baselineskip} in the slot font. No effect on absolutely positioned slots.}
\end{options}
\ldeen{Zusätzlich angenommen, aber derzeit ohne sichtbare Wirkung: \code{rotate} (Vorgabe \code{0}), \code{opacity} (\code{1}), \code{shadow}, \code{uppercase} und \code{lowercase} (jeweils \code{false}). Verwenden Sie diese Schlüssel nicht als Voraussetzung für Ihr Layout.}{Also accepted, but currently without visible effect: \code{rotate} (default \code{0}), \code{opacity} (\code{1}), \code{shadow}, \code{uppercase}, and \code{lowercase} (each \code{false}). Do not rely on these keys for your layout.}

\subsection{\ldeen{Bereichsdekoration}{Area decoration}}

\begin{commands}
  \command{decorateltxtalkarea}[\marg{\ldeen{Bereich}{area}}\marg{\ldeen{Optionen}{options}}]
\ldeen{Ändert die angegebenen Eigenschaften der Bereichsinstanz. Die übrigen bleiben erhalten.}{Changes the specified properties of the area instance, retaining the others.}
\end{commands}
\begin{options}
\keyval{background}{\ldeen{Farbe}{colour}}\Default{none}
\ldeen{Einfarbiger Hintergrund oder keine Füllung.}{Solid background or no fill.}
\keyval{background-split}{\ldeen{Farbliste}{colour list}}\Default{\ldeen{leer}{empty}}
\ldeen{Nebeneinanderliegende Farbflächen; \code{Farbe*2} gibt doppeltes Gewicht. Verwenden Sie gültige Farbnamen wie \code{ltxtalk-primary}.}{Adjacent colour fields; \code{colour*2} gives double weight. Use valid colour names such as \code{ltxtalk-primary}.}
\keyval{background-gradient}{\ldeen{Farben}{colours}}\Default{\ldeen{leer}{empty}}
\ldeen{Zwei Farben \code{\{oben,unten\}} für einen vertikalen Verlauf.}{Two colours \code{\{top,bottom\}} for a vertical gradient.}
\keychoice{frame}{none,box,top,bottom,left,right,topbottom}\Default{none}
\ldeen{\code{top}, \code{bottom} und \code{topbottom} zeichnen horizontale Linien. \code{left} und \code{right} zeichnen die jeweilige Seitenkante. \code{box} zeichnet derzeit nur die obere und untere Linie.}{\code{top}, \code{bottom}, and \code{topbottom} draw horizontal rules. \code{left} and \code{right} draw the corresponding side. \code{box} currently draws only the top and bottom rules.}
\keyval{rule-color}{\ldeen{Farbe}{colour}}\Default{ltxtalk-primary}
\ldeen{Farbe der Bereichslinien.}{Area-rule colour.}
\keyval{rule-thickness}{\ldeen{Länge}{length}}\Default{0.4pt}
\ldeen{Stärke der Bereichslinien.}{Area-rule width.}
\keyval{padding}{\ldeen{Länge}{length}}\Default{0pt}
\ldeen{Abstand nach einer linken Bereichslinie; verschiebt keine Slotpositionen.}{Spacing after a left area rule; does not move slots.}
\keyval{artifact-type}{\ldeen{Name}{name}}\Default{layout}
\ldeen{Beschreibende Angabe; die Standardausgabe wertet den Wert derzeit nicht aus.}{Descriptive field; standard output does not currently use its value.}
\end{options}
\ldeen{Die Schlüssel \code{background-opacity} (Vorgabe \code{1}), \code{shadow} (\code{false}), \code{shadow-color} (\code{black!30}), \code{shadow-offset} (\code{3pt}), \code{margin-top} und \code{margin-bottom} (jeweils \code{0pt}) werden angenommen, sind aber derzeit ohne sichtbare Wirkung. Verwenden Sie für die Geometrie \cs*{ltxtalksetup}.}{The keys \code{background-opacity} (default \code{1}), \code{shadow} (\code{false}), \code{shadow-color} (\code{black!30}), \code{shadow-offset} (\code{3pt}), \code{margin-top}, and \code{margin-bottom} (each \code{0pt}) are accepted but currently have no visible effect. Use \cs*{ltxtalksetup} for geometry.}

\subsection{\ldeen{Titelplatzierung}{Title placement}}

\begin{commands}
  \command{setltxtalktitleplacement}[\marg{\ldeen{Optionen}{options}}]
  \ldeen{
    Legt mit \code{frametitle=content|header|both} und
    \code{section=header|none} die beabsichtigte Titelplatzierung fest. Das
    aktive Theme muss Slots für die gewählten Bereiche definieren.
  }{
    Declares the intended title placement with
    \code{frametitle=content|header|both} and
    \code{section=header|none}. The active theme must define slots in the
    selected areas.
  }
\end{commands}

\begin{commands}
  \command{setltxtalkheadingbehavior}[\marg{\ldeen{Optionen}{options}}]
  \ldeen{
    Konfiguriert mit dem booleschen Schlüssel \code{auto-section-title}
    (Vorgabe: \code{false}), ob die erste \cs{frametitle}-Folie nach
    \cs{section}/\cs{subsection} deren nummerierte Überschrift als Titel übernimmt. Ein an
    derselben Folie gegebener Text wird dabei zum Subtitel; ein zusätzlich
    gesetzter \cs{framesubtitle} entfällt.

    \textbf{Bekanntes Problem:} Mit \code{tagging=on} kann diese Option
    bei bestimmten Folieninhalten zum Fehler \enquote{TeX capacity exceeded}
    führen. Prüfen Sie das vollständige Dokument und deaktivieren Sie
    \code{auto-section-title}, falls dieser Fehler auftritt.
  }{
    Configures, with the Boolean key \code{auto-section-title} (default:
    \code{false}), whether the first \cs{frametitle} frame after
    \cs{section}/\cs{subsection} takes over its numbered heading as the title. Text
    given at that same frame becomes the subtitle; a separately set
    \cs{framesubtitle} is dropped.

    \textbf{Known issue:} With \code{tagging=on}, this option can cause
    a \enquote{TeX capacity exceeded} error with some frame content.
    Compile the complete document and disable \code{auto-section-title}
    if that error occurs.
  }

  \command{contframetitle}[\oarg{\ldeen{Untertitel}{subtitle}}]
  \ldeen{Wiederholt die zuletzt mit \cs*{section} oder \cs*{subsection} gesetzte, nummerierte Überschrift mit einem Fortsetzungshinweis. Verwenden Sie den Befehl innerhalb eines neuen \env{frame}, wenn ein Thema mehrere separate Frames umfasst. Er ist unabhängig von \code{auto-section-title} und übernimmt nicht den letzten manuell gesetzten Folientitel. Das optionale Argument setzt einen Untertitel; ein Pflichtargument gibt es nicht. Vor dem optionalen Argument ist wie bei \cs*{frametitle} eine Overlay-Spezifikation in spitzen Klammern möglich. Für Overlays innerhalb desselben Frames genügt \cs*{frametitle}.}{Repeats the numbered heading most recently set by \cs*{section} or \cs*{subsection}, adding a continuation marker. Use it inside a new \env{frame} when a topic spans several separate frames. It is independent of \code{auto-section-title} and does not repeat the last manually set frame title. The optional argument supplies a subtitle; there is no mandatory argument. As with \cs*{frametitle}, an overlay specification in angle brackets may precede the optional argument. For overlays within the same frame, \cs*{frametitle} suffices.}

\end{commands}

\subsection{
  \ldeen
    {Optionen für Barrierefreiheit}
    {Accessibility options}
}

\label{sec:ref-accessibility}
\ldeen{Das vierte Argument von \cs*{defineltxtalkslot} legt die semantische Rolle und gegebenenfalls einen Alternativtext fest. Diese Angaben wirken bei aktiviertem Tagging. Leere Slots erzeugen kein Strukturelement. Beim Typ \code{frametitle} übernimmt die Klasse das Tagging; die folgenden Optionen ändern dessen Struktur nicht.}{The fourth argument of \cs*{defineltxtalkslot} specifies the semantic role and, optionally, alternative text. These settings take effect when tagging is enabled. Empty slots create no structure element. The class handles tagging for the \code{frametitle} type; the following options do not change its structure.}
\begin{options}
\keyval{role}{\ldeen{Rolle}{role}}\Default{artifact}
\ldeen{\code{heading} kennzeichnet eine Überschrift auf der mit \code{heading-level} gewählten Ebene; \code{heading-1}, \code{heading-2} und \code{heading-3} wählen direkt die jeweilige Ebene. \code{note} kennzeichnet eine Anmerkung. \code{artifact} und \code{navigation} nehmen dekorative beziehungsweise wiederkehrende Navigationselemente aus der Lesereihenfolge aus. \code{content} verwendet das automatische Absatz-Tagging für normalen Inhalt.}{\code{heading} marks a heading at the level selected by \code{heading-level}; \code{heading-1}, \code{heading-2}, and \code{heading-3} select that level directly. \code{note} marks a note. \code{artifact} and \code{navigation} exclude decorative or recurring navigation elements from the reading order. \code{content} uses automatic paragraph tagging for ordinary content.}
\keyval{heading-level}{\ldeen{Ganzzahl}{integer}}\Default{1}
\ldeen{Überschriftenebene für \code{role=heading}, begrenzt auf 1 bis 6.}{Heading level for \code{role=heading}, limited to 1 through 6.}
\keyval{alt-text}{\ldeen{Text}{text}}\Default{\ldeen{leer}{empty}}
\ldeen{Alternativtext für den Slotinhalt. Ein nicht leerer Wert erhält bei Überschriften und Anmerkungen deren Rolle; für alle anderen Rollen wird der Slot als Abbildung (\code{Figure}) mit Alternativtext ausgegeben. Er wird dadurch auch bei \code{artifact} oder \code{navigation} Teil der Dokumentstruktur. Für rein dekorative Elemente lassen Sie den Wert leer.}{Alternative text for the slot content. A non-empty value preserves heading and note roles; for every other role, the slot becomes a figure (\code{Figure}) with alternative text. This includes it in the document structure even with \code{artifact} or \code{navigation}. Leave the value empty for purely decorative elements.}
\keyval{continuation-text}{\ldeen{Text}{text}}
\ldeen{Beabsichtigter Fortsetzungstext; derzeit ohne Ausgabewirkung.}{Intended continuation text; currently without output effect.}
\keychoice{continuation-mode}{explicit,implicit}
\ldeen{Beabsichtigte Fortsetzungsart; derzeit ohne Ausgabewirkung.}{Intended continuation mode; currently without output effect.}
\end{options}
\ldeen{Bereichshintergründe mit Farbaufteilung oder Verlauf werden
unabhängig davon immer ausdrücklich als Artefakte ausgegeben.}{Split and
gradient area backgrounds are always explicitly emitted as artifacts,
independently of the above.}

\subsection{\ldeen{Templates und Sockets}{Templates and sockets}}

\ldeen{
Für jeden Slot existiert eine Instanz des Template-Typs
\code{lttheme-slot}, für jeden Bereich eine Instanz von \code{lttheme-area}.
Zum Bearbeiten dieser Instanzen dienen die beiden zuvor dokumentierten
Befehle für Slotgestaltung und Bereichsdekoration.
}{
Every slot has an instance of the \code{lttheme-slot} template type and every
area an instance of \code{lttheme-area}. Use the previously documented slot
styling and area decoration commands to edit them.
}

\ldeen{
Der Seitenstil stellt Sockets für den Seitenhintergrund, die Bereiche
\code{header}, \code{left}, \code{right} und \code{footer} sowie den
Seitenvordergrund bereit. Ihre Namen folgen dem Schema
\code{lttheme/area/}\meta{\ldeen{Bereich}{area}} beziehungsweise
\code{lttheme/page/}\meta{Ebene}. Der Plug \code{standard} rendert den
zugehörigen Bereich. Eigene Plugs sind für grundlegende, austauschbare
Ausgabephasen gedacht; zusätzliche Seitenelemente sollten gewöhnlich als
Slots eines Teilthemes implementiert werden.
}{
The page style provides sockets for the page background, the \code{header},
\code{left}, \code{right}, and \code{footer} areas, and the page foreground.
Their names follow \code{lttheme/area/}\meta{Area} and
\code{lttheme/page/}\meta{Layer}. The \code{standard} plug renders the
corresponding area. Custom plugs are intended for fundamental replaceable
output phases; additional page elements should normally be slots in a partial
theme.
}



\end{document}
%</driver>
%<*pkg>
\NeedsTeXFormat{LaTeX2e}
% \ProvidesExplPackage's own version argument must stay a literal here,
% not a macro reference: driver-side tools like \UseVersionOf read this
% line's raw text from the generated file without expanding it, so a
% macro name would show up unresolved there. \ltxtalkversion mirrors the
% same bare number (no "v" -- \ProvidesExplPackage adds that itself when
% printing the banner) for use in error messages and documentation prose
% that need it before this line has run; keep the two literals in sync.
% A plain \def, not \tl_const:Nn: \ExplSyntaxOn is not active yet at
% this point (\ProvidesExplPackage itself activates it for the rest
% of the file), so a name with "_"/":" would not tokenize correctly.
\def\ltxtalkversion{0.5.3}
\ProvidesExplPackage{ltxtalk-theme}
{2026-10-05}
{v0.5.3}
{Theme engine for ltx-talk}

% The declared ltx-talk compatibility, as two independent facts that are
% recalibrated by hand, not something meant to track the class's own live
% version:
% - the oldest class release the theme engine still supports; anything
%   older is a fatal error;
% - the class release the theme engine was last tested with; anything
%   dated later is unexpectedly new and only produces a warning.
% Each pair feeds both the check below and the message describing it, so
% the two cannot silently drift apart from each other.
\tl_const:Nn \c__ltxtalk_min_class_date_tl { 2026/08/05 }
\tl_const:Nn \c__ltxtalk_min_class_version_tl { 0.5.3 }
\tl_const:Nn \c__ltxtalk_tested_class_date_tl { 2026/10/13 }
\tl_const:Nn \c__ltxtalk_tested_class_version_tl { 0.6.10 }

\RequirePackage{xcoffins}
\RequirePackage{xcolor}

% \ldeen*{@1 hält den "`äußeren"' Teil des Themes (Layout, Slots,
% Dekorationen) frei von @2s \LuaTeX{}/\XeTeX{}-Bindung: Farbverwaltung
% wird über osgstyler bezogen (siehe unten bei @3), aber osgstylers
% Font-Palette-Modul -- und damit @2 selbst -- wird nicht geladen.
% Ohne @1 steht die volle osgstyler-Fontverwaltung zur Verfügung.}
% {Option @1 keeps the "`outer"' part of the theme (layout, slots,
% decorations) free of @2's \LuaTeX{}/\XeTeX{} binding: color management
% is still sourced from osgstyler (see @3 below), but osgstyler's
% font-palette module -- and thus @2 itself -- is not loaded. Without
% @1, full osgstyler font management is available.}
% {\option{outer-only}}{\pkg*{fontspec}}{\cs{setltxtalkcolors}}
\bool_new:N \g__ltxtalk_outeronly_bool
% \ldeen{Setzt bei allen mitgelieferten Themes die dünnen Trennlinien am
%   Block wieder ein (Rahmen beim Kasten-Look, Kopf-/Fußlinie beim reinen
%   Titel). Als Ladeoption oder über \cs{ltxtalksetup}; wird bei
%   \cs*{useltxtalktheme} ausgewertet.}{Restores the thin dividing rules on
%   blocks for all bundled themes (a border on the boxed look, head/foot
%   rules on the plain-title look). As a load option or via
%   \cs{ltxtalksetup}; read at \cs*{useltxtalktheme} time.}
\bool_new:N \g__ltxtalk_block_hairlines_bool
\DeclareKeys
  {
    outer-only .bool_gset:N = \g__ltxtalk_outeronly_bool,
    outer-only .initial:n = false,
    outer-only .usage:n = load,
    block-hairlines .bool_gset:N = \g__ltxtalk_block_hairlines_bool,
    block-hairlines .initial:n = false,
  }
\ProcessKeyOptions\relax
% \ldeen*{@1 signalisiert osgstyler, dass lttheme seine Themefarben
% selbst über @2/@3 einspeist (siehe unten bei @4), sodass osgstylers
% eigene reaktive lttheme-Integration entfällt.}{@1 signals to osgstyler
% that lttheme feeds its theme colors into osgstyler itself via @2/@3
% (see @4 below), so osgstyler's own reactive lttheme integration does
% not apply.}{\cs{LtxtalkUsesOsgstylerNatively}}
% {\cs{DeclareOsgColorPalette}}{\cs{UseOsgColorPalette}}
% {\cs{__ltxtalk\_colors\_apply:n}}
\cs_gset_protected:Npn \LtxtalkUsesOsgstylerNatively { }
\bool_if:NTF \g__ltxtalk_outeronly_bool
  { \RequirePackage[colors-only]{osgstyler} }
  { \RequirePackage{osgstyler} }
\RequirePackage{pgfcore}

\msg_new:nnnn { ltxtalk } { missing-class }
  { Missing~document~class }
  { The~ltxtalk-theme~package~requires~ltx-talk. }
\msg_new:nnnn { ltxtalk } { class-too-old }
  { Unsupported~ltx-talk~version }
  {
    ltxtalk-theme~v\ltxtalkversion\space requires~at~least~ltx-talk~
    v\c__ltxtalk_min_class_version_tl\space from~\c__ltxtalk_min_class_date_tl.~
    Update~the~ltx-talk~document~class~before~loading~this~theme~engine.
  }
% \ldeen*{@1 gibt nur die Kurzform aus, ohne interaktive Hilfeabfrage;
%   deshalb steht die relevante Information hier, nicht im Langtext unten.}{
%   @1 only prints the short form, with no interactive help query; the
%   relevant information therefore lives here, not in the long text below.
% }{\cs*{msg_warning:nn}}
\msg_new:nnnn { ltxtalk } { class-too-new }
  {
    Untested~ltx-talk~version:~loaded~class~is~newer~than~the~tested~
    v\c__ltxtalk_tested_class_version_tl.
  }
  {
    ltxtalk-theme~v\ltxtalkversion\space was~last~tested~with~ltx-talk~
    v\c__ltxtalk_tested_class_version_tl\space from~
    \c__ltxtalk_tested_class_date_tl.~This~is~only~a~warning:~no~
    incompatibility~with~the~loaded~class~is~known.~If~something~
    looks~wrong,~a~newer~theme-engine~release~may~be~available.
  }

% \@ifclasslater also accepts an equal date, which fits the lower bound
% but not "later than the tested release"; hence the numeric comparison.
\str_new:N \l__ltxtalk_date_str
\int_new:N \l__ltxtalk_class_date_int
\int_new:N \l__ltxtalk_tested_date_int
\cs_new_protected:Npn \__ltxtalk_date_to_int:nN #1#2
  {
    \str_set:Ne \l__ltxtalk_date_str { \str_range:nnn {#1} { 1 } { 10 } }
    \str_replace_all:Nnn \l__ltxtalk_date_str { - } { }
    \str_replace_all:Nnn \l__ltxtalk_date_str { / } { }
    \int_set:Nn #2 { \l__ltxtalk_date_str }
  }
\cs_generate_variant:Nn \__ltxtalk_date_to_int:nN { e , V }

% ltx-talk v0.6.10 (2026-10-13) renamed the titlepage template key
% framestyle to frame-style without keeping the old name; the key name is
% chosen once the class is known, so the themes need not care.
\tl_new:N \g__ltxtalk_titlepage_style_key_tl
\cs_new_protected:Npn \__ltxtalk_titlepage_defaults:n #1
  {
    \use:e
      {
        \exp_not:n { \EditTemplateDefaults { titlepage } { talk } }
          { \g__ltxtalk_titlepage_style_key_tl = lttheme , \exp_not:n {#1} }
      }
  }

% \ldeen*{Das Paket ist nur sinnvoll, wenn @1 geladen ist.}{
%  The package is only useful, if @1 is loaded.
% }{\cls*{ltx-talk}}
\@ifclassloaded{ltx-talk}
  {
    \@ifclasslater{ltx-talk}{\c__ltxtalk_min_class_date_tl}
      {}
      {\msg_fatal:nn { ltxtalk } { class-too-old }}
    \@ifclasslater{ltx-talk}{2026/10/13}
      { \tl_gset:Nn \g__ltxtalk_titlepage_style_key_tl { frame-style } }
      { \tl_gset:Nn \g__ltxtalk_titlepage_style_key_tl { framestyle } }
    \__ltxtalk_date_to_int:eN { \use:c { ver@ltx-talk.cls } }
      \l__ltxtalk_class_date_int
    \__ltxtalk_date_to_int:VN \c__ltxtalk_tested_class_date_tl
      \l__ltxtalk_tested_date_int
    \int_compare:nNnT
      { \l__ltxtalk_class_date_int } > { \l__ltxtalk_tested_date_int }
      { \msg_warning:nn { ltxtalk } { class-too-new } }
  }
  { 
    \msg_error:nnnn { ltxtalk } { missing-class }
      { This~package~requires~the~ltx-talk~document~class }
      { Please~use~\token_to_str:N \documentclass{ltx-talk} } 
  }

% ==========================================
% NACHRICHTEN
% ==========================================
\msg_new:nnnn { ltxtalk } { unknown-theme }
  { Unknown~theme~'#1'. }
  { The~theme~'#1'~is~not~registered.~Use~\token_to_str:N \RegisterLTXTalkTheme~to~register~it. }

\msg_new:nnn { ltxtalk } { missing-heading }
  { Warning:~No~heading~defined~in~frame.~This~may~affect~accessibility. }

\msg_new:nnn { ltxtalk } { theme-not-activated }
  { Theme~'#1'~loaded~but~not~activated.~Use~\token_to_str:N \useltxtalktheme{#1}~to~activate. }
\msg_new:nnnn { ltxtalk } { unknown-layout }
  { Unknown~layout~'#1'. }
  { Declare~it~with~\token_to_str:N\DeclareLTXTalkLayout. }
\msg_new:nnnn { ltxtalk } { unknown-title-layout }
  { Unknown~title~layout~'#1'. }
  { Declare~it~with~\token_to_str:N\DeclareLTXTalkTitleLayout. }
\msg_new:nnnn { ltxtalk } { unknown-navigation }
  { Unknown~navigation~'#1'. }
  { Declare~it~with~\token_to_str:N\DeclareLTXTalkNavigation~or~use~one~of~
    current-section,~current-subsection,~section-list. }
\msg_new:nnn { ltxtalk } { rerun-navigation }
  { The~document~structure~changed;~rerun~to~get~the~navigation~right. }
\msg_new:nnn { ltxtalk } { font-theme-outer-only }
  { Font~palettes~are~unavailable~with~the~outer-only~option;~keeping~the~NFSS~fallback. }

% ==========================================
% INTERNE COFFINS (VERSTECKT VOR NUTZER)
% ==========================================
\coffin_new:N \g__ltxtalk_page_coffin
\coffin_new:N \g__ltxtalk_header_coffin
\coffin_new:N \g__ltxtalk_left_coffin
\coffin_new:N \g__ltxtalk_content_coffin
\coffin_new:N \g__ltxtalk_right_coffin
\coffin_new:N \g__ltxtalk_footer_coffin

% Temporäre Coffins für Spalten-Layout
\coffin_new:N \l__ltxtalk_header_left_col
\coffin_new:N \l__ltxtalk_header_center_col
\coffin_new:N \l__ltxtalk_header_right_col

% ==========================================
% THEME-REGISTRIERUNG
% ==========================================

\tl_new:N \g__ltxtalk_active_theme_tl
\tl_gset:Nn \g__ltxtalk_active_theme_tl { default }

\prop_new:N \g__ltxtalk_themes_prop
\tl_new:N \l__ltxtalk_theme_setup_tl

\NewDocumentCommand \RegisterLTXTalkTheme { m m }
  {
    \prop_gput:Nnn \g__ltxtalk_themes_prop { #1 } { #2 }
  }

% ==========================================
% LAYOUT-KONFIGURATION
% ==========================================

\dim_new:N \l__ltxtalk_margin_dim
\dim_new:N \l__ltxtalk_left_area_width_dim
\dim_new:N \l__ltxtalk_right_area_width_dim
\dim_new:N \l__ltxtalk_content_inset_left_dim
\dim_new:N \l__ltxtalk_content_inset_right_dim
\dim_new:N \l__ltxtalk_header_height_dim
\dim_new:N \l__ltxtalk_footer_height_dim
\dim_new:N \l__ltxtalk_area_width_dim
\dim_new:N \l__ltxtalk_area_height_dim

\int_new:N \l__ltxtalk_header_rows_int

\bool_new:N \l__ltxtalk_show_header_bool
\bool_new:N \l__ltxtalk_show_left_margin_bool
\bool_new:N \l__ltxtalk_show_right_margin_bool
\bool_new:N \l__ltxtalk_show_footer_bool
% \ldeen{Von \code{ltxtalk / a11y} gesetzt (\code{continuation-mode}); die
%   übrige Auswertung ist Aufgabe des inneren Themes.}{Set by
%   \code{ltxtalk / a11y} (\code{continuation-mode}); acting on it is the
%   inner theme's job.}
\bool_new:N \l__ltxtalk_explicit_cont_bool

\clist_new:N \l__ltxtalk_header_columns_clist
\clist_new:N \l__ltxtalk_footer_columns_clist
\prop_new:N \g__ltxtalk_layouts_prop
\prop_new:N \g__ltxtalk_layout_code_prop

\keys_define:nn { ltxtalk / layout }
  {
    header         .bool_set:N = \l__ltxtalk_show_header_bool,
    header         .initial:n = false,
    header-height  .dim_set:N = \l__ltxtalk_header_height_dim,
    header-height  .initial:n = 1.5cm,
    header-rows    .int_set:N = \l__ltxtalk_header_rows_int,
    header-rows    .initial:n = 1,
    left-margin    .bool_set:N = \l__ltxtalk_show_left_margin_bool,
    left-margin    .initial:n = false,
    right-margin   .bool_set:N = \l__ltxtalk_show_right_margin_bool,
    right-margin   .initial:n = false,
    footer         .bool_set:N = \l__ltxtalk_show_footer_bool,
    footer         .initial:n = false,
    footer-height  .dim_set:N = \l__ltxtalk_footer_height_dim,
    footer-height  .initial:n = 1cm,
    margin-width   .code:n =
      {
        \dim_set:Nn \l__ltxtalk_margin_dim {#1}
        \dim_set:Nn \l__ltxtalk_left_area_width_dim {#1}
        \dim_set:Nn \l__ltxtalk_right_area_width_dim {#1}
        \dim_set:Nn \l__ltxtalk_content_inset_left_dim {#1}
        \dim_set:Nn \l__ltxtalk_content_inset_right_dim {#1}
      },
    margin-width   .initial:n = 2.5cm,
    left-area-width .dim_set:N = \l__ltxtalk_left_area_width_dim,
    left-area-width .initial:n = 2.5cm,
    right-area-width .dim_set:N = \l__ltxtalk_right_area_width_dim,
    right-area-width .initial:n = 2.5cm,
    content-inset-left .dim_set:N = \l__ltxtalk_content_inset_left_dim,
    content-inset-left .initial:n = 2.5cm,
    content-inset-right .dim_set:N = \l__ltxtalk_content_inset_right_dim,
    content-inset-right .initial:n = 2.5cm,
    
    header-columns .clist_set:N = \l__ltxtalk_header_columns_clist,
    header-columns .initial:n = { 0.2, 0.6, 0.2 },
    footer-columns .clist_set:N = \l__ltxtalk_footer_columns_clist,
    footer-columns .initial:n = { 0.33, 0.34, 0.33 },

    % Preference, not a layout dimension: read by the theme setup on the
    % next \useltxtalktheme, so a document can set it once up front.
    block-hairlines .bool_gset:N = \g__ltxtalk_block_hairlines_bool,
  }

\NewDocumentCommand \ltxtalksetup { m }
  {
    \keys_set:nn { ltxtalk / layout } { #1 }
    \__ltxtalk_update_text_area:
  }

% \ldeen{
%   Ein Layout bündelt eine benannte Grundeinstellung: die Keys von
%   \code{ltxtalk / layout} und optional Aufbau-Code (Slots definieren,
%   Flächen dekorieren, eine Navigation binden). \cs{UseLTXTalkLayout}
%   wendet zuerst die gespeicherten Keys an, dann die Aufruf-Overrides,
%   dann den Code -- der Code sieht also die endgültigen Werte (etwa
%   \cs{LTXTalkHeaderRows}). Layouts sind additiv: nicht genannte Keys
%   behalten ihren Wert, sodass ein Theme ein Layout als Ausgangspunkt
%   nutzen und einzelne Slots danach überschreiben kann. Ein Theme kann
%   mehrere Layouts deklarieren und pro Frame zwischen ihnen umschalten.
% }{
%   A layout bundles a named baseline: the \code{ltxtalk / layout} keys and
%   optionally setup code (define slots, decorate areas, bind a
%   navigation). \cs{UseLTXTalkLayout} applies the stored keys first, then
%   the per-call overrides, then the code -- so the code sees the final
%   values (such as \cs{LTXTalkHeaderRows}). Layouts are additive: keys not
%   named keep their value, so a theme can use a layout as a starting point
%   and override individual slots afterwards. A theme may declare several
%   layouts and switch between them per frame.
% }
\NewDocumentCommand \DeclareLTXTalkLayout { m m O{} }
  {
    \prop_gput:Nnn \g__ltxtalk_layouts_prop {#1} {#2}
    \prop_gput:Nnn \g__ltxtalk_layout_code_prop {#1} {#3}
  }

\NewDocumentCommand \UseLTXTalkLayout { m O{} }
  {
    \prop_get:NnNTF \g__ltxtalk_layouts_prop {#1} \l_tmpa_tl
      {
        \keys_set:nV { ltxtalk / layout } \l_tmpa_tl
        \tl_if_blank:nF {#2} { \keys_set:nn { ltxtalk / layout } {#2} }
        \prop_get:NnNT \g__ltxtalk_layout_code_prop {#1} \l_tmpb_tl
          { \tl_use:N \l_tmpb_tl }
        \__ltxtalk_update_text_area:
      }
      { \msg_error:nnn { ltxtalk } { unknown-layout } {#1} }
  }

% \ldeen{
%   Die Titelseite ist der Spezialfall eines Layouts: ihre Optionen liegen
%   im selben Speicher und Schlüsselraum (\code{ltxtalk / layout}) wie
%   gewöhnliche Layouts. Der dritte Parameter von
%   \cs{DeclareLTXTalkTitleLayout} ist jedoch kein Aufbau-Code, sondern der
%   \emph{Inhalt} des Titel-Frames -- er wird von \cs{MakeLTXTalkTitle}
%   einmalig in einer \env{frame}-Umgebung ausgeführt, nicht als
%   persistenter Aufbau. Deshalb ein eigener Code-Speicher.
% }{
%   The title page is the special case of a layout: its options live in the
%   same store and key space (\code{ltxtalk / layout}) as ordinary layouts.
%   The third parameter of \cs{DeclareLTXTalkTitleLayout} is not setup code
%   but the \emph{content} of the title frame -- \cs{MakeLTXTalkTitle} runs
%   it once inside a \env{frame}, not as persistent setup. Hence a separate
%   code store.
% }
\prop_new:N \g__ltxtalk_title_layout_code_prop
\tl_new:N \g__ltxtalk_title_layout_tl
\bool_new:N \l__ltxtalk_title_page_bool
\int_new:N \g__ltxtalk_title_header_rows_int
\int_new:N \g__ltxtalk_saved_header_grid_rows_int
% \ldeen{Wahr, während eine Titelseite den Zeilenzähler des Kopfrasters
%   überschreibt -- nur dann muss er nach dem Ausgeben wiederhergestellt
%   werden. Themes ohne Kopfraster tragen keinen Eintrag ein.}{True while a
%   title page has overridden the header grid's row count -- only then does it
%   need restoring after shipout. Themes without a header grid leave no
%   entry.}
\bool_new:N \g__ltxtalk_title_grid_saved_bool

\NewExpandableDocumentCommand \LTXTalkHeaderRows {}
  {\bool_if:NTF \l__ltxtalk_title_page_bool
     {\int_use:N \g__ltxtalk_title_header_rows_int}
     {\int_use:N \l__ltxtalk_header_rows_int}}

\NewDocumentCommand \IfLTXTalkTitlePageTF {m m}
  {\bool_if:NTF \l__ltxtalk_title_page_bool {#1}{#2}}

\NewDocumentCommand \DeclareLTXTalkTitleLayout { m m m }
  {
    \prop_gput:Nnn \g__ltxtalk_layouts_prop {#1} {#2}
    \prop_gput:Nnn \g__ltxtalk_title_layout_code_prop {#1} {#3}
  }

\NewDocumentCommand \UseLTXTalkTitleLayout { m }
  { \tl_gset:Nn \g__ltxtalk_title_layout_tl {#1} }

\NewDocumentCommand \MakeLTXTalkTitle {O{}}
  {
    \tl_if_blank:nTF {#1}
      {\tl_set_eq:NN \l_tmpa_tl \g__ltxtalk_title_layout_tl}
      {\tl_set:Nn \l_tmpa_tl {#1}}
    \prop_get:NVNTF \g__ltxtalk_title_layout_code_prop \l_tmpa_tl \l_tmpb_tl
      {
        \prop_get:NVN \g__ltxtalk_layouts_prop \l_tmpa_tl \l_tmpc_tl
        \group_begin:
          \keys_set:nV {ltxtalk/layout} \l_tmpc_tl
          % ltx-talk 0.5.3 can defer construction of the running head until
          % after the frame group.  Keep the small amount of state needed by
          % header sockets alive until this page has actually shipped.
          \bool_gset_true:N \l__ltxtalk_title_page_bool
          \int_gset_eq:NN \g__ltxtalk_title_header_rows_int
            \l__ltxtalk_header_rows_int
          % \ldeen{Nur wenn das Theme ein Kopfraster nutzt, gibt es eine
          %   Zeilenzahl zu sichern und zu ersetzen; ohne Eintrag lieferte
          %   \cs{prop_get:NnN} \cs{q_no_value} und \cs{int_gset:Nn} liefe
          %   sich fest.}{Only a theme with a header grid has a row count to
          %   save and replace; without an entry \cs{prop_get:NnN} would
          %   yield \cs{q_no_value} and \cs{int_gset:Nn} would spin.}
          \bool_gset_false:N \g__ltxtalk_title_grid_saved_bool
          \prop_get:NnNT \g__ltxtalk_area_grid_rows_prop {header} \l_tmpa_tl
            {
              \bool_gset_true:N \g__ltxtalk_title_grid_saved_bool
              \int_gset:Nn \g__ltxtalk_saved_header_grid_rows_int {\l_tmpa_tl}
              \prop_gput:NnV \g__ltxtalk_area_grid_rows_prop {header}
                \l__ltxtalk_header_rows_int
            }
          \AddToHookNext{shipout/after}
            {
              \bool_gset_false:N \l__ltxtalk_title_page_bool
              \bool_if:NT \g__ltxtalk_title_grid_saved_bool
                {\prop_gput:Nnx \g__ltxtalk_area_grid_rows_prop {header}
                  {\int_use:N \g__ltxtalk_saved_header_grid_rows_int}}
            }
          \__ltxtalk_update_text_area:
          \begin{frame}[vertical-alignment=top]
            \thispagestyle{lttheme}
            \tl_use:N \l_tmpb_tl
          \end{frame}
        \group_end:
        \__ltxtalk_update_text_area:
      }
      {\msg_error:nnV {ltxtalk}{unknown-title-layout}\l_tmpa_tl}
  }

% ==========================================
% FARBSCHEMA
% ==========================================

% \ldeen*{@1 löst selbst keine Farben auf, sondern reicht sein Argument
% unverändert an @2 weiter -- beide Schnittstellen teilen absichtlich
% dasselbe Vokabular (dieselben acht Slotnamen, dieselbe
% \code{model=...,~value=...}"=~bzw.\ \code{alias=...}"=Syntax), sodass
% keine Übersetzung nötig ist. Nicht genannte Slots werden über @2s
% eigene Fallback-Kette aufgelöst (\code{secondary} etc.\ fallen auf
% \code{primary} zurück): @1 ist eine vollständige Neudeklaration, kein
% inkrementelles Patch. Die resultierenden osgstyler-Farben werden
% anschließend unter den etablierten \code{ltxtalk-*}"=Namen (und den
% unpräfigierten \code{structure}/\code{alert}/\code{example}"=Namen)
% gespiegelt, damit Themecode diese Namen unverändert nutzen
% kann.}{@1 does not resolve colors itself; it forwards its argument
% unchanged to @2 -- both interfaces deliberately share the same
% vocabulary (the same eight slot names, the same
% \code{model=...,~value=...} resp.\ \code{alias=...} syntax), so no
% translation is needed. Slots not given resolve via @2's own fallback
% chain (\code{secondary} etc.\ fall back to \code{primary}): @1 is a
% full redeclaration, not an incremental patch. The resulting osgstyler
% colors are then mirrored under the established \code{ltxtalk-*} names
% (and the unprefixed \code{structure}/\code{alert}/\code{example}
% names), so theme code can use those names unchanged.}
% {\cs{setltxtalkcolors}}{\cs{DeclareOsgColorPalette}}
% \ldeen*{@1 liest den aufgelösten Wert per @2 aus der bereits von
% osgstyler gesetzten Farbe @3 und registriert ihn anschließend sowohl
% nativ über @4 als auch klassisch über @5: \cls*{ltx-talk} ersetzt
% \cs{color} durch eine auf dem \pkg*{l3color}"=Modul aufbauende
% Fassung, die ausschließlich nativ registrierte Farben kennt -- eine
% nur klassisch definierte Farbe wäre für \cs{color} "`unbekannt"',
% obwohl \cs{extractcolorspec} sie korrekt läse.}{@1 reads the resolved
% value via @2 from the color @3 that osgstyler has already set, then
% registers it both natively via @4 and classically via @5:
% \cls*{ltx-talk} replaces \cs{color} with a version built on the
% \pkg*{l3color} module that only recognizes natively registered colors
% -- a color defined only classically would be "`unknown"' to \cs{color},
% even though \cs{extractcolorspec} would read it correctly.}
% {\cs{\_\_ltxtalk\_colors\_mirror:nn}}{\cs{color\_export:nnN}}
% {\code{osgstyler-*}}{\cs{color\_set:nnn}}{\cs{definecolor}}
\cs_generate_variant:Nn \color_set:nnn { nnV }
\cs_new_protected:Npn \__ltxtalk_colors_mirror:nn #1#2
  {
    \color_export:nnN {#2} { HTML } \l_tmpb_tl
    \color_set:nnV {#1} { HTML } \l_tmpb_tl
    \use:e
      {
        \exp_not:N \definecolor {#1} { HTML } { \l_tmpb_tl }
      }
  }
\cs_new_protected:Npn \__ltxtalk_colors_apply:n #1
  {
    \DeclareOsgColorPalette { ltxtalk } {#1}
    \UseOsgColorPalette { ltxtalk }
    \__ltxtalk_colors_mirror:nn { ltxtalk-primary }   { osgstyler-primary }
    \__ltxtalk_colors_mirror:nn { ltxtalk-secondary } { osgstyler-secondary }
    \__ltxtalk_colors_mirror:nn { ltxtalk-accent }    { osgstyler-accent }
    \__ltxtalk_colors_mirror:nn { ltxtalk-text }      { osgstyler-text }
    \__ltxtalk_colors_mirror:nn { ltxtalk-bg }        { osgstyler-background }
    \__ltxtalk_colors_mirror:nn { ltxtalk-structure } { osgstyler-structure }
    \__ltxtalk_colors_mirror:nn { ltxtalk-alert }     { osgstyler-alert }
    \__ltxtalk_colors_mirror:nn { ltxtalk-example }   { osgstyler-example }
    \__ltxtalk_colors_mirror:nn { structure } { osgstyler-structure }
    \__ltxtalk_colors_mirror:nn { alert }     { osgstyler-alert }
    \__ltxtalk_colors_mirror:nn { example }   { osgstyler-example }
  }

\NewDocumentCommand \setltxtalkcolors { m }
  { \__ltxtalk_colors_apply:n {#1} }

% Standardfarben
\__ltxtalk_colors_apply:n
  {
    primary    = { model=HTML, value=2B3A67 },
    secondary  = { model=HTML, value=496A81 },
    accent     = { model=HTML, value=66999B },
    text       = { model=HTML, value=333333 },
    background = { model=HTML, value=FFFFFF },
    structure  = { alias=primary },
    alert      = { model=HTML, value=B00020 },
    example    = { model=HTML, value=166534 },
  }

% ==========================================
% SCHRIFTSCHEMA
% ==========================================

\NewDocumentCommand \DeclareLTXTalkFontPalette { m m }
  { \DeclareOsgFontPalette {#1} {#2} }

\NewDocumentCommand \UseLTXTalkFontPalette { m }
  {
    \bool_if:NTF \g__ltxtalk_outeronly_bool
      { \msg_warning:nn { ltxtalk } { font-theme-outer-only } }
      { \UseOsgFontPalette {#1} }
  }

\cs_new:Npn \__ltxtalk_font_role_to_slot:n #1
  {
    \str_case:nnF {#1}
      {
        { body }     { main }
        { support }  { companion }
        { heading }  { display }
        { emphasis } { accent }
        { code }     { mono }
      }
      {#1}
  }

\cs_new_protected:Npn \__ltxtalk_font_select:n #1
  {
    \tl_set:Nx \l_tmpa_tl { \__ltxtalk_font_role_to_slot:n {#1} }
    \bool_if:NTF \g__ltxtalk_outeronly_bool
      {
        \str_case:VnF \l_tmpa_tl
          {
            { main }      { \rmfamily }
            { mono }      { \ttfamily }
            { companion } { \sffamily }
            { display }   { \sffamily }
            { accent }    { \sffamily }
            { symbol }    { \rmfamily }
          }
          { \normalfont }
      }
      { \exp_args:NV \UseOsgFont \l_tmpa_tl }
  }

\NewDocumentCommand \UseLTXTalkFont { m }
  { \__ltxtalk_font_select:n {#1} }

\DeclareLTXTalkFontPalette { ltxtalk-default }
  {
    % Match ltx-talk's file-based font selection.  Looking the family up by
    % name is platform-dependent (and bypasses NewCM's .fontspec file on
    % some systems), which makes otherwise identical PDFs differ in CI.
    main      = { font = { NewCMSans10-Regular.otf } },
    companion = { alias = main },
    display   = { alias = companion },
    accent    = { alias = companion },
    mono      = { font = { Latin Modern Mono } },
    symbol    = { alias = main }
  }
\bool_if:NF \g__ltxtalk_outeronly_bool
  { \UseOsgFontPalette { ltxtalk-default } }

% ==========================================
% INNER THEME: BLOCKS AND LIST MARKERS
% ==========================================

% The box-styling engine itself (template type, interface, and typeset
% code) now lives in osgstyler as osgstyler-block, since long-form
% documents need the same boxed-content rendering without pulling in
% this presentation-specific theme. This file only declares its own
% instances against that shared type and wraps the beamer/ltx-talk
% environments -- the "style a known environment" case, where the
% original environment keeps its own semantics and this wrapper only
% adds the visual frame.
\clist_map_inline:nn { block, alertblock, exampleblock }
  { \DeclareInstance { osgstyler-block } {#1} { standard } { } }

\NewDocumentCommand \styleltxtalkblock { m m }
  { \StyleOsgBlockInstance {#1} {#2} }

% \ldeen{Wendet den Theme-Trait plus Farbschlüssel auf eine Blockinstanz
%   an und ergänzt bei aktivem \option{block-hairlines} die passende dünne
%   Linie: einen Rahmen beim Kasten-Trait (\code{titlebar}), Kopf-/Fußlinie
%   beim reinen Titel (\code{heading}). \code{#1} Trait, \code{#2}
%   Farbschlüssel, \code{#3} Instanz.}{Applies the theme trait plus colour
%   keys to a block instance and, when \option{block-hairlines} is on, adds
%   the matching thin rule: a border for the boxed trait (\code{titlebar}),
%   head/foot rules for the plain-title trait (\code{heading}). \code{#1}
%   trait, \code{#2} colour keys, \code{#3} instance.}
\cs_new_protected:Npn \__ltxtalk_theme_block:nnn #1#2#3
  {
    \StyleOsgBlockInstance {#3} { traits = {#1} , #2 }
    \bool_if:NT \g__ltxtalk_block_hairlines_bool
      {
        \str_case:nn {#1}
          {
            { titlebar }
              { \StyleOsgBlockInstance {#3} { rule-thickness = 0.4pt } }
            { heading }
              { \StyleOsgBlockInstance {#3}
                  { head-rule-thickness = 0.8pt , foot-rule-thickness = 0.6pt } }
          }
      }
  }

\skip_new:N \l__ltxtalk_original_block_medskip_skip
\cs_new_protected:Npn \__ltxtalk_use_original_block:nnn #1#2#3
  {
    % ltx-talk currently puts \medskip both before its title and between the
    % title and body.  Suppress those class-owned skips only while the begin
    % code runs, then restore the amount before user body material is read.
    % The following \unskip remains a harmless fallback for other trailing
    % glue that a future class version might leave at the hand-off point.
    \skip_set_eq:NN \l__ltxtalk_original_block_medskip_skip \medskipamount
    \skip_zero:N \medskipamount
    \IfNoValueTF {#1}
      { \begin{ltxtalk-original-block}{#2} }
      { \begin{ltxtalk-original-block}<#1>{#2} }
    \skip_set_eq:NN \medskipamount \l__ltxtalk_original_block_medskip_skip
    \unskip #3
    \end{ltxtalk-original-block}
  }

% \ldeen{
%   Zwei Wege je nach Block-Layout: \code{plain} reicht die Original-Umgebung
%   \code{ltxtalk-original-block} (mit deren eigenem Titel) unverteilt an
%   \code{osgstyler-block} weiter -- die \code{<Overlay>}-Behandlung der
%   Klasse bleibt erhalten. \code{titled} braucht Titel und Body getrennt:
%   der Titel geht in den farbigen Kopf, der Body ohne Klassen-Umgebung
%   direkt; die Overlay-Auswahl übernimmt hier \cs{__talk_if_overlay:nT}.
% }{
%   Two paths depending on the block layout: \code{plain} hands the original
%   \code{ltxtalk-original-block} environment (with its own title)
%   undivided to \code{osgstyler-block} -- the class's \code{<overlay>}
%   handling is preserved. \code{titled} needs title and body separately:
%   the title goes into the coloured head, the body directly without the
%   class environment; \cs{__talk_if_overlay:nT} does the overlay selection
%   here.
% }
\cs_new_protected:Npn \__ltxtalk_render_block:nnnn #1#2#3#4
  {
    \OsgIfBlockTitledTF {#1}
      {
        \IfNoValueTF {#2}
          { \__talk_if_overlay:nT { all }
              { \__osgstyler_block_use:nnn {#1} {#3} {#4} } }
          { \__talk_if_overlay:nT {#2}
              { \__osgstyler_block_use:nnn {#1} {#3} {#4} } }
      }
      {
        \__osgstyler_block_use:nnn {#1} { }
          { \__ltxtalk_use_original_block:nnn {#2} {#3} {#4} }
      }
  }

\NewEnvironmentCopy { ltxtalk-original-block } { block }
\RenewDocumentEnvironment { block } { d <> m +b }
  { \__ltxtalk_render_block:nnnn { block } {#1} {#2} {#3} }
  { }

% alertblock/exampleblock keep the "structure" rule-color default and
% locally alias it to alert/example instead of overriding rule-color
% per instance, so a later \styleltxtalkblock customization of
% rule-color is not silently undone here. The alias targets the
% resolved osgstyler-structure/-alert/-example names (via \OsgColorName)
% rather than the bare, lttheme-only mirrored ones, since
% osgstyler-block resolves colors through \OsgColorName itself.
% Only provide the two variants while the class does not provide its own.
\cs_if_exist:cF { alertblock }
  {
    \NewDocumentEnvironment { alertblock } { d <> m +b }
      {
        \group_begin:
          \exp_args:Nee \colorlet
            { \OsgColorName{structure} } { \OsgColorName{alert} }
          \__ltxtalk_render_block:nnnn { alertblock } {#1} {#2} {#3}
        \group_end:
      }
      { }
  }
\cs_if_exist:cF { exampleblock }
  {
    \NewDocumentEnvironment { exampleblock } { d <> m +b }
      {
        \group_begin:
          \exp_args:Nee \colorlet
            { \OsgColorName{structure} } { \OsgColorName{example} }
          \__ltxtalk_render_block:nnnn { exampleblock } {#1} {#2} {#3}
        \group_end:
      }
      { }
  }

% Delegates to osgstyler's list palette (enumitem-backed) instead of
% redefining \labelitemi directly, so itemize customization here gains
% mode-awareness for free and goes through the same engine as every
% other theme's list styling.
\tl_new:N \l__ltxtalk_itemize_options_tl
\keys_define:nn { ltxtalk / itemize }
  {
    level-1 .code:n =
      \tl_put_right:Nn \l__ltxtalk_itemize_options_tl { 1 = {label=#1}, },
    level-2 .code:n =
      \tl_put_right:Nn \l__ltxtalk_itemize_options_tl { 2 = {label=#1}, },
    level-3 .code:n =
      \tl_put_right:Nn \l__ltxtalk_itemize_options_tl { 3 = {label=#1}, },
    level-4 .code:n =
      \tl_put_right:Nn \l__ltxtalk_itemize_options_tl { 4 = {label=#1}, }
  }
\NewDocumentCommand \setltxtalkitemize { m }
  {
    \tl_clear:N \l__ltxtalk_itemize_options_tl
    \keys_set:nn { ltxtalk / itemize } {#1}
    \exp_args:Nnx \DeclareOsgListPalette { ltxtalk-itemize }
      { itemize = { \l__ltxtalk_itemize_options_tl } }
    \UseOsgListPalette { ltxtalk-itemize }
  }

% ==========================================
% NAMED-SLOT-SYSTEM
% ==========================================

\prop_new:N \g__ltxtalk_slot_types_prop
\prop_new:N \g__ltxtalk_slot_positions_prop
\prop_new:N \g__ltxtalk_slot_styles_prop
\prop_new:N \g__ltxtalk_slot_areas_prop
\prop_new:N \g__ltxtalk_slot_accessibility_prop
\prop_new:N \g__ltxtalk_area_grid_columns_prop
\prop_new:N \g__ltxtalk_area_grid_rows_prop
\prop_new:N \g__ltxtalk_slot_grid_positions_prop

\tl_new:N \l__ltxtalk_current_slot_name_tl
\tl_new:N \l__ltxtalk_slot_type_tl
\tl_new:N \l__ltxtalk_slot_content_tl
\tl_new:N \l__ltxtalk_slot_style_tl
\tl_new:N \l__ltxtalk_slot_area_tl
\tl_new:N \l__ltxtalk_slot_accessibility_tl

% \ldeen{
%   \#1 Slot-Name (eindeutig), \#2 Bereich (header/left/content/right/footer),
%   \#3 Slot-Typ (frametitle, section, logo, \dots), \#4 Barrierefreiheits-Optionen
%   (Key-Value). Idempotent: ein Layout darf pro Frame erneut ausgeführt werden,
%   ohne dass ein Slot doppelt in die Bereichs-Reihenfolge gerät. Wird ein Slot
%   in einen anderen Bereich verschoben, wird er zuerst aus der alten Reihenfolge
%   entfernt.
% }{
%   \#1 slot name (unique), \#2 area (header/left/content/right/footer),
%   \#3 slot type (frametitle, section, logo, \dots), \#4 accessibility options
%   (key-value). Idempotent: a layout may run again per frame without a slot
%   ending up twice in an area's order. If a slot moves to another area, it is
%   first removed from the old order.
% }
\NewDocumentCommand \defineltxtalkslot { m m m m }
  {
    \prop_get:NnNT \g__ltxtalk_slot_areas_prop {#1} \l__ltxtalk_slot_area_tl
      {
        \seq_if_exist:cT { g__ltxtalk_ \l__ltxtalk_slot_area_tl _slots_seq }
          { \seq_gremove_all:cn { g__ltxtalk_ \l__ltxtalk_slot_area_tl _slots_seq } {#1} }
      }
    \prop_gput:Nnn \g__ltxtalk_slot_areas_prop {#1} {#2}
    \prop_gput:Nnn \g__ltxtalk_slot_types_prop {#1} {#3}
    \prop_gput:Nnn \g__ltxtalk_slot_accessibility_prop {#1} {#4}
    \seq_if_exist:cF { g__ltxtalk_#2_slots_seq }
      { \seq_new:c { g__ltxtalk_#2_slots_seq } }
    \seq_if_in:cnF { g__ltxtalk_#2_slots_seq } {#1}
      { \seq_gput_right:cn { g__ltxtalk_#2_slots_seq } {#1} }
    \IfInstanceExistsTF { lttheme-slot } {#1}
      { \EditInstance { lttheme-slot } {#1} { } }
      { \DeclareInstance { lttheme-slot } {#1} { standard } { } }
  }

\NewDocumentCommand \positionltxtalkslot { m m m m m }
  {
    % 
    % \begin{itemize}
    %  \item \#1: Slot-Name
    %  \item \#2: x-Position (Dimension oder 'left'/'center'/'right')
    %  \item \#3: y-Position (Dimension oder 'top'/'center'/'bottom')
    %  \item \#4: Breite (Dimension)
    %  \item \#5: Höhe (Dimension)
    %\end{itemize}
    \prop_gput:Nnn \g__ltxtalk_slot_positions_prop { #1 } 
      { { #2 } { #3 } { #4 } { #5 } }
  }

\NewDocumentCommand \DeclareLTXTalkAreaGrid { m m m }
  {
    \prop_gput:Nnn \g__ltxtalk_area_grid_columns_prop {#1} {#2}
    \prop_gput:Nnn \g__ltxtalk_area_grid_rows_prop {#1} {#3}
  }

\NewDocumentCommand \PositionLTXTalkSlotInGrid { m m m m m }
  {\prop_gput:Nnn \g__ltxtalk_slot_grid_positions_prop {#1}
    {{#2}{#3}{#4}{#5}}}

\NewDocumentCommand \SetLTXTalkAreaGridRows { m m }
  {\prop_gput:Nnn \g__ltxtalk_area_grid_rows_prop {#1}{#2}}

% ==========================================
% SLOT-FORMATIERUNG
% ==========================================

\tl_new:N \l__ltxtalk_slot_font_tl
\tl_new:N \l__ltxtalk_slot_font_slot_tl
\tl_new:N \l__ltxtalk_slot_color_tl
\tl_new:N \l__ltxtalk_slot_bg_tl
\tl_new:N \l__ltxtalk_slot_align_tl
\tl_new:N \l__ltxtalk_slot_frame_tl
\tl_new:N \l__ltxtalk_slot_rule_tl
\tl_new:N \l__ltxtalk_slot_rotate_tl
\tl_new:N \l__ltxtalk_slot_opacity_tl

\dim_new:N \l__ltxtalk_slot_padding_dim
\dim_new:N \l__ltxtalk_slot_rule_thick_dim
\dim_new:N \l__ltxtalk_slot_space_after_dim

\bool_new:N \l__ltxtalk_slot_shadow_bool
\bool_new:N \l__ltxtalk_slot_bg_fill_bool
\bool_new:N \l__ltxtalk_slot_uppercase_bool
\bool_new:N \l__ltxtalk_slot_lowercase_bool
% \ldeen{Wahr, während ein Slot im Textfluss des Frames gesetzt wird
%   (Folientitel/-untertitel im Inhaltsbereich), im Gegensatz zu absolut
%   positionierten Slots in Kopf, Fuß oder Randspalten. Nur im Textfluss
%   trägt \code{space-after} bzw.\ die schriftgrößenabhängige Vorgabe.}{
%   True while a slot is set in the frame's text stream (frame
%   title/subtitle in the content area), as opposed to absolutely
%   positioned slots in the header, footer, or margin columns. Only in the
%   text stream does \code{space-after}, or the font-size-dependent
%   default, take effect.}
\bool_new:N \l__ltxtalk_slot_flow_bool

% \ldeen{\#1 Slot-Name, \#2 Formatierungsoptionen aus der Schnittstelle des
%   Template-Typs \code{lttheme-slot}. Der gespeicherte Wert dient dem
%   Theme-Wechsel-Reset; \cs{EditInstance} prüft die Schlüssel und wendet
%   sie sofort an.}{\#1 slot name, \#2 styling options from the
%   \code{lttheme-slot} template type's interface. The stored value is used
%   by the theme-switch reset; \cs{EditInstance} validates the keys and
%   applies them immediately.}
\NewDocumentCommand \styleltxtalkslot { m m }
  {
    \prop_gput:Nnn \g__ltxtalk_slot_styles_prop {#1} {#2}
    \EditInstance { lttheme-slot } {#1} {#2}
  }

% ==========================================
% BEREICHSDEKORATIONEN
% ==========================================

\prop_new:N \g__ltxtalk_area_decorations_prop

\tl_new:N \l__ltxtalk_area_frame_tl
\tl_new:N \l__ltxtalk_area_rule_color_tl
\tl_new:N \l__ltxtalk_area_background_tl
\tl_new:N \l__ltxtalk_area_bg_split_tl
\tl_new:N \l__ltxtalk_area_bg_gradient_tl
\tl_new:N \l__ltxtalk_area_bg_opacity_tl
\tl_new:N \l__ltxtalk_area_shadow_color_tl
\clist_new:N \l__ltxtalk_area_bg_split_clist
\fp_new:N   \l__ltxtalk_area_bg_split_wt_fp
\dim_new:N  \l__ltxtalk_area_bg_split_x_dim
\dim_new:N  \l__ltxtalk_area_bg_split_seg_dim

\dim_new:N \l__ltxtalk_area_rule_thickness_dim
\dim_new:N \l__ltxtalk_area_shadow_offset_dim
\dim_new:N \l__ltxtalk_area_padding_dim
\dim_new:N \l__ltxtalk_area_margin_top_dim
\dim_new:N \l__ltxtalk_area_margin_bottom_dim

\bool_new:N \l__ltxtalk_area_shadow_bool

% \ldeen{\#1 Bereich (header/left/right/footer/content), \#2
%   Dekorationsoptionen aus der Schnittstelle des Template-Typs
%   \code{lttheme-area}. Der gespeicherte Wert dient dem Theme-Wechsel-Reset;
%   \cs{EditInstance} prüft die Schlüssel und wendet sie sofort an.}{\#1 area
%   (header/left/right/footer/content), \#2 decoration options from the
%   \code{lttheme-area} template type's interface. The stored value is used
%   by the theme-switch reset; \cs{EditInstance} validates the keys and
%   applies them immediately.}
\NewDocumentCommand \decorateltxtalkarea { m m }
  {
    \prop_gput:Nnn \g__ltxtalk_area_decorations_prop {#1} {#2}
    \EditInstance { lttheme-area } {#1} {#2}
  }

% ==========================================
% TITEL-PLATZIERUNG
% ==========================================

\tl_new:N \g__ltxtalk_frametitle_target_tl
\tl_gset:Nn \g__ltxtalk_frametitle_target_tl { content }
\tl_new:N \g__ltxtalk_section_target_tl
\tl_gset:Nn \g__ltxtalk_section_target_tl { none }

\NewDocumentCommand \setltxtalktitleplacement { m }
  {
    \keys_set:nn { ltxtalk / title-placement } { #1 }
  }

\keys_define:nn { ltxtalk / title-placement }
  {
    frametitle .choice:,
    frametitle / content .code:n = 
      { \tl_gset:Nn \g__ltxtalk_frametitle_target_tl { content } },
    frametitle / header .code:n = 
      { \tl_gset:Nn \g__ltxtalk_frametitle_target_tl { header } },
    frametitle / both .code:n = 
      { \tl_gset:Nn \g__ltxtalk_frametitle_target_tl { both } },
    frametitle .initial:n = content,
    
    section .choice:,
    section / header .code:n = 
      { \tl_gset:Nn \g__ltxtalk_section_target_tl { header } },
    section / none .code:n = 
      { \tl_gset:Nn \g__ltxtalk_section_target_tl { none } },
    section .initial:n = none,
  }

% ==========================================
% ACCESSIBILITY
% ==========================================

\tl_new:N \l__ltxtalk_slot_role_tl
\tl_new:N \l__ltxtalk_alt_text_tl
\tl_new:N \l__ltxtalk_continuation_text_tl

\int_new:N \l__ltxtalk_heading_level_int

\keys_define:nn { ltxtalk / a11y }
  {
    role .choice:,
    role / heading       .code:n = \tl_set:Nn \l__ltxtalk_slot_role_tl { heading },
    role / heading-1     .code:n = \tl_set:Nn \l__ltxtalk_slot_role_tl { H1 },
    role / heading-2     .code:n = \tl_set:Nn \l__ltxtalk_slot_role_tl { H2 },
    role / heading-3     .code:n = \tl_set:Nn \l__ltxtalk_slot_role_tl { H3 },
    role / artifact      .code:n = \tl_set:Nn \l__ltxtalk_slot_role_tl { artifact },
    role / content       .code:n = \tl_set:Nn \l__ltxtalk_slot_role_tl { content },
    role / navigation    .code:n = \tl_set:Nn \l__ltxtalk_slot_role_tl { navigation },
    role / note          .code:n = \tl_set:Nn \l__ltxtalk_slot_role_tl { note },
    role .initial:n = artifact,
    
    heading-level .int_set:N = \l__ltxtalk_heading_level_int,
    heading-level .initial:n = 1,
    
    alt-text .tl_set:N = \l__ltxtalk_alt_text_tl,
    alt-text .initial:n = {},
    
    continuation-text .tl_set:N = \l__ltxtalk_continuation_text_tl,
    continuation-text .initial:n = { (Fortsetzung) },
    continuation-mode .choice:,
    continuation-mode / explicit .code:n = 
      { \bool_set_true:N \l__ltxtalk_explicit_cont_bool },
    continuation-mode / implicit .code:n = 
      { \bool_set_false:N \l__ltxtalk_explicit_cont_bool },
    continuation-mode .initial:n = implicit,
  }

% \ldeen{Wendet das vierte Argument von \cs*{defineltxtalkslot} tatsächlich
%   an, statt es nur zu dokumentieren. Wiederverwendet dafür bewusst
%   \cls*{ltx-talk}s eigenen, bereits für \cs{frametitle} bewährten
%   Tagging-Baustein (\cs{__talk_header_tag_begin:e}/\cs{__talk_header_tag_end:}
%   mit \code{parent}\code{=}\cs{g__talk_frame_struct_int}), statt einen
%   zweiten zu erfinden: dieselbe Positionierung im Tag-Baum funktioniert
%   nachweislich unabhängig davon, ob der Slot im Inhaltsbereich (sofortiges
%   Rendern im Textfluss) oder in einem Kopf-/Rand-/Fußbereich (verzögertes
%   Rendern über die Seitenstil-Ausgaberoutine, also physisch \emph{nach} dem
%   umgebenden Folieninhalt) liegt. \code{role=heading}/\code{H1..H3} und
%   \code{role=note} öffnen daher ein echtes Strukturelement (\code{Hn}
%   beziehungsweise \code{Note}, Standard-PDF2.0-Typen ohne RoleMap-Umweg);
%   \code{role=artifact} und \code{role=navigation} (letzteres mangels
%   eigenen PDF-Strukturtyps für wiederkehrende Navigationselemente wie
%   Seitenzahlen) erzeugen nur einen reinen Artefakt-MC-Span außerhalb des
%   Strukturbaums; \code{role=content} lässt den automatischen
%   Absatz-Tagging-Hook unangetastet. Ist \code{alt-text} gesetzt, gewinnt es:
%   der Slot bekommt in jedem Fall ein echtes Strukturelement mit
%   \code{Alt}-Attribut (\code{Figure}, sofern die Rolle selbst kein
%   Strukturelement wäre). Bei abgeschaltetem Tagging für die aktuelle Folie
%   (\cs{g__talk_frame_tag_bool} falsch) unterbleibt jeder Tagging-Aufruf --
%   genau wie bei \cls*{ltx-talk}s eigener Frametitel-Funktion, aus demselben
%   Grund: kein unausgeglichener Tag-Stack.}{Actually applies the fourth
%   argument of \cs*{defineltxtalkslot} instead of merely documenting it.
%   Deliberately reuses \cls*{ltx-talk}'s own tagging primitive, already
%   proven for \cs{frametitle} (\cs{__talk_header_tag_begin:e}/
%   \cs{__talk_header_tag_end:} with \code{parent}\code{=}
%   \cs{g__talk_frame_struct_int}), rather than inventing a second one: the
%   same tag-tree positioning demonstrably works whether the slot sits in the
%   content area (rendered immediately, in text flow) or in a header/margin/
%   footer area (rendered later, through the page style's output routine --
%   physically \emph{after} the surrounding frame content). \code{role=heading}
%   /\code{H1..H3} and \code{role=note} therefore open a genuine structure
%   element (\code{Hn} or \code{Note}, standard PDF2.0 types, no RoleMap
%   indirection needed); \code{role=artifact} and \code{role=navigation}
%   (the latter for lack of a dedicated PDF structure type for recurring
%   navigation chrome such as page numbers) produce a plain artifact MC span
%   outside the structure tree; \code{role=content} leaves the automatic
%   per-paragraph tagging hook untouched. A given \code{alt-text} wins: the
%   slot then always gets a genuine structure element with an \code{Alt}
%   attribute (\code{Figure} if the role itself would not be a structure
%   element). With tagging switched off for the current frame
%   (\cs{g__talk_frame_tag_bool} false), no tagging call happens at all --
%   exactly as in \cls*{ltx-talk}'s own frame-title function, for the same
%   reason: no unbalanced tag stack.}
\cs_new_protected:Npn \__ltxtalk_accessibility_artifact:n #1
  {
    \bool_if:NTF \g__talk_frame_tag_bool
      { \tag_mc_begin:n { artifact } #1 \tag_mc_end: }
      { #1 }
  }
% \ldeen{Strukturelemente im Textstrom des Frames (Inhalts-Slots) dürfen
%   \emph{nicht} über \cs{__talk_header_tag_begin:e}/\cs{__talk_header_tag_end:}
%   getaggt werden: Dieses Paar ist für Kopf-/Fußbereiche gebaut, die beim
%   Ausschiffen innerhalb eines offenen Artefakt-MC mit suspendiertem Tagging
%   entstehen, und endet deshalb mit \cs{tag_mc_begin:n}\code{\{artifact\}}
%   und \cs{tag_suspend:n}. Im Folienrumpf bliebe dieser MC offen; folgt dann
%   Material ohne Absatz-Tagging (etwa ein Block), landet es als loser Inhalt
%   direkt im \code{frame} bzw. \code{Sect} (\enquote{Parent-Child ... MC
%   (realcontent) ... Relation is not allowed!}). \cs{__ltxtalk_flow_struct:nn}
%   öffnet und schließt Struktur und MC deshalb selbst und hinterlässt den
%   Tagging-Zustand so, wie es ihn vorgefunden hat. Kein \code{firstkid}:
%   das Element steht dort im Baum, wo es im Textstrom steht.}{Structure
%   elements in the frame's text stream (content slots) must \emph{not} be
%   tagged via \cs{__talk_header_tag_begin:e}/\cs{__talk_header_tag_end:}:
%   that pair is built for header/footer areas, which are created at shipout
%   inside an open artifact MC with tagging suspended, and therefore ends
%   with \cs{tag_mc_begin:n}\code{\{artifact\}} and \cs{tag_suspend:n}. In the
%   frame body that MC would stay open; if material without paragraph tagging
%   follows (a block, say), it ends up as loose content directly in the
%   \code{frame} or \code{Sect} (\enquote{Parent-Child ... MC (realcontent)
%   ... Relation is not allowed!}). \cs{__ltxtalk_flow_struct:nn} therefore
%   opens and closes structure and MC itself and leaves the tagging state as
%   it found it. No \code{firstkid}: the element sits in the tree where it
%   sits in the text stream.}
% \ldeen{Strukturelemente aus Kopf-/Rand-/Fußbereichen entstehen erst beim
%   Ausschiffen. Sie werden ebenfalls \emph{ohne} \code{firstkid} an den
%   \code{frame} gehängt, also hinter dessen Inhalt: Mit \code{firstkid}
%   stellten sie sich vor den im Textstrom getaggten Folientitel, und der
%   Titel wäre nicht mehr das erste Element der Folie. Die Lesereihenfolge
%   ist damit in allen Themes Titel, Untertitel, Inhalt, dann die
%   Randnotizen in der Reihenfolge ihrer Slots.}{Structure elements from
%   header/margin/footer areas are only created at shipout. They too are
%   attached to the \code{frame} \emph{without} \code{firstkid}, i.e. after
%   its content: with \code{firstkid} they would jump ahead of the frame
%   title tagged in the text stream, and the title would no longer be the
%   first element of the frame. Reading order is thus, in every theme,
%   title, subtitle, content, then the marginal notes in the order of
%   their slots.}
\cs_new_protected:Npn \__ltxtalk_flow_struct:nn #1 #2
  {
    \tagpdfparaOff
    \tag_struct_begin:e
      {
        parent = \int_use:N \g__talk_frame_struct_int ,
        #1
      }
    \tag_mc_begin:n { }
    \group_begin:
      #2
    \group_end:
    \tag_mc_end:
    \tag_struct_end:
  }
\cs_new_protected:Npn \__ltxtalk_accessibility_struct:nn #1 #2
  {
    \bool_if:NTF \g__talk_frame_tag_bool
      {
        \bool_if:NTF \l__ltxtalk_slot_flow_bool
          { \__ltxtalk_flow_struct:nn {#1} {#2} }
          {
            \__talk_header_tag_begin:e
              {
                parent = \int_use:N \g__talk_frame_struct_int,
                #1
              }
            \group_begin:
              \tagpdfparaOff
              #2
            \group_end:
            \__talk_header_tag_end:
          }
      }
      { #2 }
  }
\cs_new:Npn \__ltxtalk_accessibility_heading_tag:
  {
    H
    \int_compare:nNnTF { \l__ltxtalk_heading_level_int } < {1} {1}
      { \int_compare:nNnTF { \l__ltxtalk_heading_level_int } > {6} {6}
          { \int_use:N \l__ltxtalk_heading_level_int } }
  }
\cs_new_protected:Npn \__ltxtalk_slot_accessibility_dispatch:n #1
  {
    \tl_if_empty:NTF \l__ltxtalk_alt_text_tl
      {
        \str_case:VnF \l__ltxtalk_slot_role_tl
          {
            { artifact }   { \__ltxtalk_accessibility_artifact:n {#1} }
            { navigation } { \__ltxtalk_accessibility_artifact:n {#1} }
            { content }    { #1 }
            { note }       { \__ltxtalk_accessibility_struct:nn { tag = Note } {#1} }
            { heading }    { \__ltxtalk_accessibility_struct:nn
                               { tag = \__ltxtalk_accessibility_heading_tag: } {#1} }
            { H1 }         { \__ltxtalk_accessibility_struct:nn { tag = H1 } {#1} }
            { H2 }         { \__ltxtalk_accessibility_struct:nn { tag = H2 } {#1} }
            { H3 }         { \__ltxtalk_accessibility_struct:nn { tag = H3 } {#1} }
          }
          { #1 }
      }
      {
        \str_case:VnF \l__ltxtalk_slot_role_tl
          {
            { note }    { \__ltxtalk_accessibility_struct:nn
                            { tag = Note, alt = \l__ltxtalk_alt_text_tl } {#1} }
            { heading } { \__ltxtalk_accessibility_struct:nn
                            { tag = \__ltxtalk_accessibility_heading_tag: ,
                              alt = \l__ltxtalk_alt_text_tl } {#1} }
            { H1 }      { \__ltxtalk_accessibility_struct:nn
                            { tag = H1, alt = \l__ltxtalk_alt_text_tl } {#1} }
            { H2 }      { \__ltxtalk_accessibility_struct:nn
                            { tag = H2, alt = \l__ltxtalk_alt_text_tl } {#1} }
            { H3 }      { \__ltxtalk_accessibility_struct:nn
                            { tag = H3, alt = \l__ltxtalk_alt_text_tl } {#1} }
          }
          { \__ltxtalk_accessibility_struct:nn
              { tag = Figure, alt = \l__ltxtalk_alt_text_tl } {#1} }
      }
  }
% \ldeen{Leerer Inhalt bekommt keine Tagging-Hülle: eine Folie ohne
%   \cs{framesubtitle} etwa liefert für den zugehörigen Slot leeren Inhalt,
%   der bei jedem Bereichs-Rendern (Kopf/Rand/Fuß laufen pro Folie, unabhängig
%   davon ob der zugehörige Befehl überhaupt aufgerufen wurde) trotzdem
%   erzeugt würde -- ohne diese Prüfung entstünde eine leere, bedeutungslose
%   Übrschrift/Struktur im Tag-Baum. Die Leerheitsprüfung (\code{:e}) expandiert
%   den Inhalt nur für den Test, damit z.\,B. \cs{LTXTalkMetadata} als auf
%   leer aufgelöst erkannt wird; getippt wird weiterhin die unexpandierte
%   Fassung.}{Empty content gets no tagging wrapper: a frame without
%   \cs{framesubtitle}, for instance, yields empty content for that slot,
%   which would still be produced on every area render (header/margin/footer
%   run once per frame, regardless of whether the corresponding command was
%   ever called) -- without this check, an empty, meaningless
%   heading/structure would appear in the tag tree. The blankness check
%   (\code{:e}) expands the content only for the test, so that, e.g.,
%   \cs{LTXTalkMetadata} resolving to nothing is detected; typesetting still
%   uses the unexpanded form.}
\cs_new_protected:Npn \__ltxtalk_slot_accessibility_apply:nn #1 #2
  {
    \tl_if_blank:eTF {#2}
      { #2 }
      {
        \group_begin:
          \tl_set:Nn \l__ltxtalk_slot_role_tl { artifact }
          \int_set:Nn \l__ltxtalk_heading_level_int { 1 }
          \tl_clear:N \l__ltxtalk_alt_text_tl
          \prop_get:NnNT \g__ltxtalk_slot_accessibility_prop {#1} \l_tmpa_tl
            { \keys_set:nV { ltxtalk / a11y } \l_tmpa_tl }
          \__ltxtalk_slot_accessibility_dispatch:n {#2}
        \group_end:
      }
  }

% ==========================================
% ABSCHNITTSTITEL ALS FRAMETITLE
% ==========================================
% \ldeen{
%   Auf Wunsch übernimmt der nächste \cs{frametitle}-Aufruf nach
%   \cs{section}/\cs{subsection} deren Text als Frametitel, unabhängig davon,
%   ob ein Theme Abschnitte zusätzlich im Kopf zeigt (Schlüssel \code{section}
%   von \cs*{setltxtalktitleplacement}). Ein am selben Aufruf gegebener Text
%   wird dabei zum Subtitel; eine zugehörige explizite \cs{framesubtitle}
%   entfällt dann, weil der demotierte Titel deren Platz einnimmt. Der Haken
%   \code{section/begin} beziehungsweise \code{subsection/begin} merkt nur
%   \emph{vor}; verbraucht wird der Merker erst vom nächsten
%   \cs{frametitle}-Aufruf -- so erscheint der Abschnittstitel höchstens
%   einmal, auch wenn ihm mehrere titellose Folien vorausgehen.
% }{
%   On request, the next \cs{frametitle} call after \cs{section}/\cs{subsection}
%   takes over its text as the frame title, independently of whether a theme
%   also shows sections in the header (the \code{section} key of
%   \cs*{setltxtalktitleplacement}). Text given at that same call then becomes
%   the subtitle; an accompanying explicit \cs{framesubtitle} is then dropped,
%   because the demoted title takes its place. The \code{section/begin} and
%   \code{subsection/begin} hooks only \emph{flag} the pending title; it is
%   consumed by the next \cs{frametitle} call -- so the section title appears
%   at most once, even if several titleless frames precede it.
% }
\bool_new:N \g__ltxtalk_auto_section_title_bool
\bool_new:N \g__ltxtalk_pending_heading_title_bool
\tl_new:N   \g__ltxtalk_pending_heading_title_tl
\int_new:N  \g__ltxtalk_auto_subtitle_frame_int
% \ldeen{Merkt sich, für welche Folie (Foliennummer) die Demotion zuletzt
%   angewendet wurde -- initial \code{0}, was nie mit einer echten
%   Foliennummer (beginnt bei~1) zusammenfällt. Nötig, weil \cs{frametitle}
%   bei mehrseitigen Folien (Overlays/\cs{pause}) pro Folienschritt erneut
%   ausgeführt wird, der \enquote{vorgemerkt}-Schalter aber nur beim
%   \emph{ersten} Schritt aktiv ist; siehe \cs{frametitle} weiter
%   unten.}{Records which frame (frame number) the demotion was last
%   applied to -- initially \code{0}, which never coincides with a real
%   frame number (starts at~1). Needed because \cs{frametitle} re-runs
%   once per overlay step on multi-page frames
%   (overlays/\cs{pause}), but the "'pending"' flag is only true on the
%   \emph{first} step; see \cs{frametitle} further below.}
\int_new:N  \g__ltxtalk_auto_title_frame_int

\NewDocumentCommand \setltxtalkheadingbehavior { m }
  { \keys_set:nn { ltxtalk / heading } {#1} }

% \ldeen{Merkt sich \emph{zusätzlich} zum eigentlichen Bool, ob
%   \code{auto-section-title} jemals explizit gesetzt wurde (in welche
%   Richtung auch immer) -- unabhängig davon, ob das vor oder nach einer
%   Kopfzeileninstanz geschieht, die es standardmäßig aktivieren möchte
%   (siehe \cs*{settucthemeheader}'s \code{teaching}-Zweig). Ein solcher
%   Default darf eine bereits getroffene Nutzerentscheidung nie
%   überschreiben.}{Additionally records whether
%   \code{auto-section-title} was ever set explicitly (in either
%   direction) -- independent of whether that happens before or after a
%   header instance that wants to default it on (see
%   \cs*{settucthemeheader}'s \code{teaching} branch). Such a default must
%   never overwrite a choice the user already made.}
\bool_new:N \g__ltxtalk_auto_section_title_explicit_bool

\keys_define:nn { ltxtalk / heading }
  {
    auto-section-title .code:n =
      {
        \bool_gset_true:N \g__ltxtalk_auto_section_title_explicit_bool
        \str_if_eq:eeTF {#1} {false}
          { \bool_gset_false:N \g__ltxtalk_auto_section_title_bool }
          { \bool_gset_true:N \g__ltxtalk_auto_section_title_bool }
      },
    auto-section-title .default:n = true,
    % \ldeen{Bewusst \emph{kein} \code{.initial:n}: Bei einem
    %   \code{.code:n}-Schlüssel löst das den Code einmal beim Definieren
    %   aus (mit dem Anfangswert als Argument) -- das würde
    %   \cs{g__ltxtalk_auto_section_title_explicit_bool} sofort auf
    %   \code{true} setzen, noch bevor je ein echter Nutzeraufruf
    %   stattfand. \cs{bool_new:N} initialisiert
    %   \cs{g__ltxtalk_auto_section_title_bool} ohnehin bereits mit
    %   \code{false}.}{Deliberately \emph{no} \code{.initial:n}: for a
    %   \code{.code:n} key, that fires the code once at definition time
    %   (with the initial value as its argument) -- which would set
    %   \cs{g__ltxtalk_auto_section_title_explicit_bool} to \code{true}
    %   immediately, before any real user call ever happened.
    %   \cs{bool_new:N} already initializes
    %   \cs{g__ltxtalk_auto_section_title_bool} to \code{false} anyway.}
  }

% \ldeen{Nur \emph{merken}: \cs{l__talk_section_tl}/\cs{l__talk_subsection_tl}
%   stehen laut \cls{ltx-talk} bereits, wenn der Haken feuert. Die
%   demotierte Frametitle bekommt eine \emph{einfache} Nummer als Präfix
%   (\cs{c@section} bzw.\ \code{section.subsection}) -- bewusst
%   \emph{nicht} \cs{thesection}/\cs{thesubsection}, die \pkg{osglecture}
%   auf \enquote{Kapitel.Abschnitt} umdefiniert: die zusammengesetzte
%   Nummer gehört in die Kopfzeile (siehe
%   \file{lttheme-tuc-2019.dtx}s \code{teaching}-Instanz), der
%   Content-Teil (hier: die Folie selbst) bekommt nur die schlichte,
%   lokale Nummer. \cs{c_space_tl} statt \code{~}: eine aktive Tilde
%   direkt nach der Nummer landete unter \cs{tl_gset:Nx} als leeres
%   Nichts in der getaggten PDF-Bookmark-/Struktur-Titel-Zeichenkette
%   (vermutlich eine Eigenheit von deren Text-Purifizierung) -- die
%   sichtbare Folie selbst zeigte dabei ebenfalls keine Lücke; die feste
%   Leerzeichen-Tokenliste behebt beides.}{Only \emph{record}:
%   \cs{l__talk_section_tl}/\cs{l__talk_subsection_tl} are already set by
%   \cls{ltx-talk} when the hook fires. The demoted frame title gets a
%   \emph{simple} number as its prefix (\cs{c@section} resp.\
%   \code{section.subsection}) -- deliberately \emph{not}
%   \cs{thesection}/\cs{thesubsection}, which \pkg{osglecture} redefines
%   to \enquote{chapter.section}: the compound number belongs in the
%   header (see \file{lttheme-tuc-2019.dtx}'s \code{teaching} instance),
%   the content part (here: the slide itself) only gets the plain, local
%   number. \cs{c_space_tl} rather than \code{~}: an active-character tie
%   directly after the number vanished under \cs{tl_gset:Nx} in the
%   tagged PDF bookmark/structure title string (likely a quirk of its
%   text purification) -- the visible slide itself also showed no gap;
%   the constant space token list fixes both.}
% \ldeen{Die numerierte Überschrift wird \emph{immer} nachgeführt, auch
%   bei ausgeschaltetem \code{auto-section-title} -- \cs{contframetitle}
%   (weiter unten) liest denselben Wert und ist ein bewusst
%   \emph{eigenständiger}, explizit vom Autor aufgerufener Mechanismus,
%   der nicht an die automatische Demotion gekoppelt sein soll. Nur das
%   \emph{automatische} Verbrauchen durch \cs{frametitle} bleibt hinter
%   dem Schalter.}{The numbered heading is \emph{always} kept current,
%   even with \code{auto-section-title} off -- \cs{contframetitle}
%   (further below) reads the same value and is a deliberately
%   \emph{independent}, explicitly author-invoked mechanism that should
%   not be tied to the automatic demotion. Only the \emph{automatic}
%   consumption by \cs{frametitle} stays behind the switch.}
% \ldeen{\cls{ltx-talk} erhöht den Zähler auch bei der Sternform
%   (\cs{section*}) und beim Schlüssel \code{unnumbered}; beides schaltet
%   dort nur \cs{l__talk_sec_numbered_bool} aus -- und zwar bleibend, denn
%   die Klasse setzt den Schalter nie zurück (und initialisiert ihn auch
%   nicht mit \code{true}). \cs{__ltxtalk_heading_begin:n} läuft deshalb als
%   \emph{erster} Hakencode jeder Ebene: es übernimmt den Schalter in ein
%   eigenes, globales Bool je Ebene, setzt ihn für die nächste Überschrift
%   wieder auf \code{true} und nimmt bei unnummerierten Überschriften den
%   Zählerschritt zurück -- einschließlich der dabei zurückgesetzten
%   untergeordneten Zähler, deren letzter Stand dafür mitgeführt wird. So
%   verhält sich \cs{section*} wie in den Standardklassen: keine Nummer,
%   und die folgende nummerierte Überschrift zählt lückenlos weiter.}{
%   \cls{ltx-talk} steps the counter for the starred form (\cs{section*})
%   and the \code{unnumbered} key, too; both merely switch off
%   \cs{l__talk_sec_numbered_bool} there -- permanently, as the class never
%   resets the switch (nor initialises it to \code{true}).
%   \cs{__ltxtalk_heading_begin:n} therefore runs as the \emph{first} hook
%   code of each level: it copies the switch into a global Boolean of its
%   own per level, resets it to \code{true} for the next heading, and for
%   unnumbered headings undoes the counter step -- including the
%   subordinate counters reset by it, whose last values are tracked for
%   that purpose. \cs{section*} thus behaves as in the standard classes: no
%   number, and the next numbered heading continues without a gap.}
\bool_new:N \g__ltxtalk_section_numbered_bool
\bool_new:N \g__ltxtalk_subsection_numbered_bool
\bool_new:N \g__ltxtalk_subsubsection_numbered_bool
\bool_gset_true:N \g__ltxtalk_section_numbered_bool
\bool_gset_true:N \g__ltxtalk_subsection_numbered_bool
\bool_gset_true:N \g__ltxtalk_subsubsection_numbered_bool
\int_new:N \g__ltxtalk_last_subsection_int
\int_new:N \g__ltxtalk_last_subsubsection_int
\bool_if_exist:NT \l__talk_sec_numbered_bool
  { \bool_set_true:N \l__talk_sec_numbered_bool }
% \ldeen{Der Zählerschritt der Klasse hat sein Sprungziel bereits angelegt,
%   wenn der Haken läuft; nach dem Zurücknehmen trüge die nächste
%   nummerierte Überschrift dasselbe Ziel noch einmal, und ihr Lesezeichen
%   zeigte auf die unnummerierte. Die Zielnamen (\cs{theHsection} usw.)
%   erhalten deshalb nach jeder unnummerierten Überschrift einen neuen
%   Zusatz; ohne unnummerierte Überschriften bleiben sie unverändert.}{The
%   class's counter step has already created its link destination when the
%   hook runs; after undoing the step, the next numbered heading would carry
%   the same destination again, and its bookmark would point at the
%   unnumbered one. The destination names (\cs{theHsection} etc.) therefore
%   receive a fresh suffix after every unnumbered heading; without
%   unnumbered headings they stay unchanged.}
\int_new:N \g__ltxtalk_unnumbered_heading_int
\AddToHook { begindocument / before }
  {
    \clist_map_inline:nn { section, subsection, subsubsection }
      {
        \cs_if_exist:cT { theH #1 }
          {
            \cs_gset_eq:cc { __ltxtalk_theH_ #1 : } { theH #1 }
            \cs_gset:cpn { theH #1 }
              {
                \use:c { __ltxtalk_theH_ #1 : }
                \int_compare:nNnT \g__ltxtalk_unnumbered_heading_int > { 0 }
                  { .u \int_use:N \g__ltxtalk_unnumbered_heading_int }
              }
          }
      }
  }
\cs_new_protected:Npn \__ltxtalk_heading_begin:n #1
  {
    \bool_lazy_and:nnTF
      { \bool_if_exist_p:N \l__talk_sec_numbered_bool }
      { ! \l__talk_sec_numbered_bool }
      {
        \bool_gset_false:c { g__ltxtalk_ #1 _numbered_bool }
        \int_gincr:N \g__ltxtalk_unnumbered_heading_int
        \int_gdecr:c { c@ #1 }
        \str_case:nn {#1}
          {
            { section }
              {
                \int_gset_eq:NN \c@subsection
                  \g__ltxtalk_last_subsection_int
                \int_gset_eq:NN \c@subsubsection
                  \g__ltxtalk_last_subsubsection_int
              }
            { subsection }
              {
                \int_gset_eq:NN \c@subsubsection
                  \g__ltxtalk_last_subsubsection_int
              }
          }
        \bool_set_true:N \l__talk_sec_numbered_bool
      }
      { \bool_gset_true:c { g__ltxtalk_ #1 _numbered_bool } }
    \int_gset_eq:NN \g__ltxtalk_last_subsection_int \c@subsection
    \int_gset_eq:NN \g__ltxtalk_last_subsubsection_int \c@subsubsection
  }
\AddToHook { section / begin }
  {
    \__ltxtalk_heading_begin:n { section }
    \tl_gset:Nx \g__ltxtalk_pending_heading_title_tl
      {
        \bool_if:NT \g__ltxtalk_section_numbered_bool
          { \int_use:N \c@section \c_space_tl }
      }
    \tl_gput_right:NV \g__ltxtalk_pending_heading_title_tl
      \l__talk_section_tl
    \bool_if:NT \g__ltxtalk_auto_section_title_bool
      { \bool_gset_true:N \g__ltxtalk_pending_heading_title_bool }
  }
\AddToHook { subsection / begin }
  {
    \__ltxtalk_heading_begin:n { subsection }
    \tl_gset:Nx \g__ltxtalk_pending_heading_title_tl
      {
        \bool_if:NT \g__ltxtalk_subsection_numbered_bool
          { \int_use:N \c@section . \int_use:N \c@subsection \c_space_tl }
      }
    \tl_gput_right:NV \g__ltxtalk_pending_heading_title_tl
      \l__talk_subsection_tl
    \bool_if:NT \g__ltxtalk_auto_section_title_bool
      { \bool_gset_true:N \g__ltxtalk_pending_heading_title_bool }
  }
\AddToHook { subsubsection / begin }
  { \__ltxtalk_heading_begin:n { subsubsection } }

% ==========================================
% SLOT-CONTENT-RESOLVER
% ==========================================

\tl_new:N \l__ltxtalk_metadata_lines_tl
\tl_new:N \l__ltxtalk_metadata_linebreak_tl
\keys_define:nn {ltxtalk/metadata-use}
  {
    lines .choice:,
    lines / all .code:n = \tl_set:Nn \l__ltxtalk_metadata_lines_tl {all},
    lines / 1 .code:n = \tl_set:Nn \l__ltxtalk_metadata_lines_tl {1},
    lines .initial:n = all,
    linebreak .tl_set:N = \l__ltxtalk_metadata_linebreak_tl,
    linebreak .initial:n = {~}
  }

\cs_new:Npn \__ltxtalk_metadata:n #1
  {
    \str_case:nnF {#1}
      {
        {title}{\@title}
        {short-title}{\@shorttitle}
        {subtitle}{\@subtitle}
        {short-subtitle}{\@shortsubtitle}
        {author}{\@author}
        {short-author}{\@shortauthor}
        {institute}{\@institute}
        {short-institute}{\@shortinstitute}
        {date}{\@date}
        {short-date}{\@shortdate}
        {section}{\insertsection}
        {subsection}{\insertsubsection}
        {frametitle}{\tl_use:N \g__talk_frame_title_tl}
        {framesubtitle}{\tl_use:N \g__talk_frame_subtitle_tl}
        {framenumber}{\@framenumber}
        {totalframes}{\@totalframes}
      }
      { }
  }

\NewExpandableDocumentCommand \LTXTalkMetadata {m}
  {\__ltxtalk_metadata:n {#1}}

\NewDocumentCommand \UseLTXTalkMetadata {O{} m}
  {
    \group_begin:
      \keys_set:nn {ltxtalk/metadata-use}{#1}
      \tl_set:Ne \l_tmpa_tl {\__ltxtalk_metadata:n {#2}}
      \str_if_eq:VnT \l__ltxtalk_metadata_lines_tl {1}
        {\tl_replace_all:NnV \l_tmpa_tl {\\} \l__ltxtalk_metadata_linebreak_tl}
      \tl_use:N \l_tmpa_tl
    \group_end:
  }

% ==========================================
% NAVIGATION
% ==========================================
% \ldeen{
%   Eine \emph{Navigation} ist eine benannte, wiederverwendbare Darstellung
%   der Dokumentstruktur. Ein Layout bindet sie im Aufbau-Code an einen Slot
%   (\cs{setltxtalkslotcontent}\Marg{slot}\Marg{\cs{LTXTalkNavigation}
%   \Marg{name}}); \cs{DeclareLTXTalkNavigation} registriert eigene.
%
%   Renderer, die die \emph{gesamte} Abschnittsfolge zeigen (nicht nur den
%   aktuellen Eintrag), brauchen zwei Läufe: \cls{ltx-talk} setzt Abschnitte
%   nicht selbst, deshalb sammelt lttheme über die Haken
%   \code{section/begin} und \code{subsection/begin} die Struktur in die
%   \file{.aux} und liest sie beim nächsten Lauf. Ändert sich die Struktur,
%   meldet lttheme \enquote{rerun to get the navigation right}. Renderer,
%   die nur den aktuellen Abschnitt zeigen, kommen mit einem Lauf aus.
% }{
%   A \emph{navigation} is a named, reusable rendering of the document
%   structure. A layout binds it to a slot in its setup code
%   (\cs{setltxtalkslotcontent}\Marg{slot}\Marg{\cs{LTXTalkNavigation}
%   \Marg{name}}); \cs{DeclareLTXTalkNavigation} registers new ones.
%
%   Renderers that show the \emph{whole} section sequence (not just the
%   current entry) need two passes: \cls{ltx-talk} does not typeset
%   sections, so lttheme collects the structure into the \file{.aux}
%   through the \code{section/begin} and \code{subsection/begin} hooks and
%   reads it back on the next run. If the structure changes, lttheme asks
%   for a rerun. Renderers that show only the current section need one pass.
% }

\prop_new:N \g__ltxtalk_navigations_prop
% Each entry is a brace group { {level} {number} {title} {frame} }.
\seq_new:N \g__ltxtalk_nav_toc_seq         % read from the .aux (previous run)
\seq_new:N \g__ltxtalk_nav_thisrun_seq     % collected during this run
\seq_new:N \l__ltxtalk_nav_tmp_seq
\bool_new:N \g__ltxtalk_nav_structure_used_bool
\int_new:N \g__ltxtalk_nav_map_int         % running entry count (separator logic)
\int_new:N \g__ltxtalk_nav_total_int       % number of sections
\int_new:N \g__ltxtalk_nav_index_int       % 1-based position of the current section
\tl_new:N \l__ltxtalk_nav_sep_tl
\tl_set:Nn \l__ltxtalk_nav_sep_tl { \nobreakspace \textbullet \nobreakspace }

\NewDocumentCommand \DeclareLTXTalkNavigation { m +m }
  { \prop_gput:Nnn \g__ltxtalk_navigations_prop {#1} {#2} }

\NewDocumentCommand \LTXTalkNavigation { m }
  {
    \prop_if_in:NnTF \g__ltxtalk_navigations_prop {#1}
      { \prop_item:Nn \g__ltxtalk_navigations_prop {#1} }
      { \msg_error:nnn { ltxtalk } { unknown-navigation } {#1} }
  }

% \ldeen{Renderer rufen dies auf, wenn sie die gesammelte Struktur nutzen;
%   nur dann wird am Dokumentende ein Rerun angemahnt.}{Renderers call this
%   when they use the collected structure; only then is a rerun requested at
%   the end of the document.}
\cs_new_protected:Npn \__ltxtalk_nav_use_structure:
  { \bool_gset_true:N \g__ltxtalk_nav_structure_used_bool }

% \ldeen{Der Titel wird detokenisiert in die \file{.aux} geschrieben --
%   einfache Titel erscheinen unverändert, Titel mit Auszeichnung als
%   Klartext (dokumentierte Einschränkung, da bewegliches Argument). Die
%   Signatur (Ebene/Nummer/Titel/Frame je Eintrag) dient der
%   Rerun-Erkennung.}{The title is written detokenised to the \file{.aux} --
%   plain titles appear unchanged, marked-up titles as plain text
%   (documented limitation, being a moving argument). The signature
%   (level/number/title/frame per entry) drives rerun detection.}
\cs_new_protected:Npn \__ltxtalk_nav_record:nnn #1#2#3
  {
    \seq_gput_right:Ne \g__ltxtalk_nav_thisrun_seq
      { { #1 } { #2 } { #3 } { \@framenumber } }
    \legacy_if:nT { @filesw }
      {
        \iow_now:Ne \@auxout
          {
            \token_to_str:N \ltxtalk@nav@entry
              { #1 } { #2 } { #3 } { \@framenumber }
          }
      }
  }

\cs_new_protected:Npn \ltxtalk@nav@entry #1#2#3#4
  { \seq_gput_right:Nn \g__ltxtalk_nav_toc_seq { {#1} {#2} {#3} {#4} } }

% \ldeen{\cs{insertsection} ist \cs{protected} und expandiert unter \code{:e}
%   nicht; die internen Titel-Variablen der Klasse werden hier direkt
%   detokenisiert (in der Variablenliste von \cls{ltx-talk} dokumentiert,
%   mit Existenzprüfung als Absicherung).}{\cs{insertsection} is
%   \cs{protected} and will not expand under \code{:e}; the class's internal
%   title variables are detokenised here directly (documented in
%   \cls{ltx-talk}'s variable list, guarded by an existence test).}
\cs_new:Npn \__ltxtalk_nav_sec_title:
  { \tl_if_exist:cT { l__talk_section_tl }
      { \tl_to_str:c { l__talk_section_tl } } }
\cs_new:Npn \__ltxtalk_nav_subsec_title:
  { \tl_if_exist:cT { l__talk_subsection_tl }
      { \tl_to_str:c { l__talk_subsection_tl } } }

% \ldeen{Jeder Eintrag trägt eine Kennung, über die die Renderer den
%   \emph{aktuellen} (Unter-)Abschnitt wiederfinden: bei nummerierten
%   Überschriften die Nummer, bei unnummerierten (\cs{section*}) ein
%   fortlaufendes \code{*}\meta{n} -- deren Zähler steht ja still, die Nummer
%   würde also auf den vorangehenden Abschnitt zeigen. Unnummerierte
%   Abschnitte erscheinen damit wie bei \beamer{} weiterhin in der
%   Navigation.}{Every entry carries an identifier by which the renderers
%   find the \emph{current} (sub)section again: the number for numbered
%   headings, a running \code{*}\meta{n} for unnumbered ones
%   (\cs{section*}) -- their counter stands still, so the number would point
%   at the preceding section. Unnumbered sections thus still appear in the
%   navigation, as with \beamer{}.}
\tl_new:N \g__ltxtalk_nav_sec_id_tl
\tl_new:N \g__ltxtalk_nav_subsec_id_tl
\int_new:N \g__ltxtalk_nav_unnumbered_int
\bool_new:N \g__ltxtalk_nav_in_current_bool
\cs_new_protected:Npn \__ltxtalk_nav_set_id:NNn #1#2#3
  {
    \bool_if:NTF #1
      { \tl_gset:Ne #2 {#3} }
      {
        \int_gincr:N \g__ltxtalk_nav_unnumbered_int
        \tl_gset:Ne #2 { * \int_use:N \g__ltxtalk_nav_unnumbered_int }
      }
  }
\AddToHook { section / begin }
  {
    \__ltxtalk_nav_set_id:NNn \g__ltxtalk_section_numbered_bool
      \g__ltxtalk_nav_sec_id_tl { \thesection }
    \tl_gclear:N \g__ltxtalk_nav_subsec_id_tl
    \__ltxtalk_nav_record:nnn { 1 } { \g__ltxtalk_nav_sec_id_tl }
      { \__ltxtalk_nav_sec_title: }
  }
\AddToHook { subsection / begin }
  {
    \__ltxtalk_nav_set_id:NNn \g__ltxtalk_subsection_numbered_bool
      \g__ltxtalk_nav_subsec_id_tl { \thesubsection }
    \__ltxtalk_nav_record:nnn { 2 } { \g__ltxtalk_nav_subsec_id_tl }
      { \__ltxtalk_nav_subsec_title: }
  }

\AddToHook { enddocument / afterlastpage }
  {
    \bool_if:NT \g__ltxtalk_nav_structure_used_bool
      {
        \str_if_eq:eeF
          { \seq_use:Nn \g__ltxtalk_nav_toc_seq     { | } }
          { \seq_use:Nn \g__ltxtalk_nav_thisrun_seq { | } }
          { \msg_warning:nn { ltxtalk } { rerun-navigation } }
      }
  }

% \ldeen{Setzt einen Eintrag der Abschnittsliste; der aktuelle Abschnitt
%   wird über die Klassenfarbe \code{ltxtalk-primary} hervorgehoben, die
%   übrigen gedämpft.}{Typesets one section-list entry; the current section
%   is emphasised in the class colour \code{ltxtalk-primary}, the others
%   dimmed.}
\cs_new_protected:Npn \__ltxtalk_nav_list_entry:nnnn #1#2#3#4
  {
    \str_if_eq:nnT {#1} { 1 }
      {
        \int_compare:nNnT \g__ltxtalk_nav_map_int > { 0 }
          { \l__ltxtalk_nav_sep_tl }
        \int_incr:N \g__ltxtalk_nav_map_int
        \str_if_eq:eeTF {#2} { \g__ltxtalk_nav_sec_id_tl }
          { {\color{ltxtalk-primary} #3} }
          { {\color{ltxtalk-secondary!55} #3} }
      }
  }

% \ldeen{Die Renderer leben in eigenen Funktionen, nicht direkt im
%   gespeicherten Navigations-Code: \cs{seq_map_inline:Nn} braucht dort ein
%   echtes Makro als Rahmen, damit \code{##1} eindeutig ist.}{The renderers
%   live in their own functions rather than inline in the stored navigation
%   code: \cs{seq_map_inline:Nn} needs a real macro frame there for
%   \code{##1} to be unambiguous.}
\cs_new_protected:Npn \__ltxtalk_nav_render_section_list:
  {
    \int_gzero:N \g__ltxtalk_nav_map_int
    \seq_map_inline:Nn \g__ltxtalk_nav_toc_seq
      { \__ltxtalk_nav_list_entry:nnnn ##1 }
  }

% \ldeen{Die Unterabschnitte des aktuellen Abschnitts sind die Einträge
%   der Ebene~2, die in der Liste auf dessen Eintrag folgen. Die Renderer
%   führen dazu beim Durchlaufen \cs{g__ltxtalk_nav_in_current_bool} mit:
%   vor dem ersten Abschnitt wahr, solange noch kein Abschnitt läuft,
%   danach bei jedem Eintrag der Ebene~1 neu bestimmt. (Ein Vergleich der
%   Nummernpräfixe scheiterte an unnummerierten Abschnitten und an einem
%   umdefinierten \cs{thesection}.)}{The current section's subsections are
%   the level-2 entries following its entry in the list. While mapping, the
%   renderers therefore maintain \cs{g__ltxtalk_nav_in_current_bool}: true
%   ahead of the first section as long as no section is running, then
%   determined anew at every level-1 entry. (Comparing number prefixes
%   failed for unnumbered sections and for a redefined \cs{thesection}.)}
\cs_new_protected:Npn \__ltxtalk_nav_track_init:
  {
    \tl_if_empty:NTF \g__ltxtalk_nav_sec_id_tl
      { \bool_gset_true:N \g__ltxtalk_nav_in_current_bool }
      { \bool_gset_false:N \g__ltxtalk_nav_in_current_bool }
  }
\cs_new_protected:Npn \__ltxtalk_nav_track:nn #1#2
  {
    \str_if_eq:nnT {#1} { 1 }
      {
        \str_if_eq:eeTF {#2} { \g__ltxtalk_nav_sec_id_tl }
          { \bool_gset_true:N \g__ltxtalk_nav_in_current_bool }
          { \bool_gset_false:N \g__ltxtalk_nav_in_current_bool }
      }
  }

% \ldeen{Zählt die Abschnitte und merkt sich die Position des aktuellen; von
%   den Renderern \code{section-dots} und \code{section-progress} vor dem
%   Setzen aufgerufen.}{Counts the sections and records the current one's
%   position; called by the \code{section-dots} and \code{section-progress}
%   renderers before they typeset.}
\cs_new_protected:Npn \__ltxtalk_nav_measure:
  {
    \int_gzero:N \g__ltxtalk_nav_total_int
    \int_gzero:N \g__ltxtalk_nav_index_int
    \seq_map_inline:Nn \g__ltxtalk_nav_toc_seq
      { \__ltxtalk_nav_measure_entry:nnnn ##1 }
  }
\cs_new_protected:Npn \__ltxtalk_nav_measure_entry:nnnn #1#2#3#4
  {
    \str_if_eq:nnT {#1} { 1 }
      {
        \int_gincr:N \g__ltxtalk_nav_total_int
        \str_if_eq:eeT {#2} { \g__ltxtalk_nav_sec_id_tl }
          { \int_gset_eq:NN \g__ltxtalk_nav_index_int \g__ltxtalk_nav_total_int }
      }
  }

% \ldeen{Unterabschnittsliste des aktuellen Abschnitts, aktueller
%   Unterabschnitt hervorgehoben.}{Subsection list of the current section,
%   current subsection emphasised.}
\cs_new_protected:Npn \__ltxtalk_nav_render_subsection_list:
  {
    \int_gzero:N \g__ltxtalk_nav_map_int
    \__ltxtalk_nav_track_init:
    \seq_map_inline:Nn \g__ltxtalk_nav_toc_seq
      { \__ltxtalk_nav_subsec_entry:nnnn ##1 }
  }
\cs_new_protected:Npn \__ltxtalk_nav_subsec_entry:nnnn #1#2#3#4
  {
    \__ltxtalk_nav_track:nn {#1} {#2}
    \str_if_eq:nnT {#1} { 2 }
      {
        \bool_if:NT \g__ltxtalk_nav_in_current_bool
          {
            \int_compare:nNnT \g__ltxtalk_nav_map_int > { 0 }
              { \l__ltxtalk_nav_sep_tl }
            \int_incr:N \g__ltxtalk_nav_map_int
            \str_if_eq:eeTF {#2} { \g__ltxtalk_nav_subsec_id_tl }
              { {\color{ltxtalk-primary} #3} }
              { {\color{ltxtalk-secondary!55} #3} }
          }
      }
  }

% \ldeen{Abschnitte untereinander; unter dem aktuellen Abschnitt seine
%   Unterabschnitte eingerückt. Zeilen werden mit \cs{newline} getrennt, es
%   entsteht also kein zusätzlicher Absatz.}{Sections one per line; the
%   current section's subsections indented below it. Lines are separated with
%   \cs{newline}, so no extra paragraph is created.}
\cs_new_protected:Npn \__ltxtalk_nav_render_toc:
  {
    \int_gzero:N \g__ltxtalk_nav_map_int
    \__ltxtalk_nav_track_init:
    \seq_map_inline:Nn \g__ltxtalk_nav_toc_seq
      { \__ltxtalk_nav_toc_entry:nnnn ##1 }
  }
\cs_new_protected:Npn \__ltxtalk_nav_toc_entry:nnnn #1#2#3#4
  {
    \__ltxtalk_nav_track:nn {#1} {#2}
    \str_if_eq:nnTF {#1} { 1 }
      {
        \int_compare:nNnT \g__ltxtalk_nav_map_int > { 0 } { \newline }
        \int_incr:N \g__ltxtalk_nav_map_int
        \str_if_eq:eeTF {#2} { \g__ltxtalk_nav_sec_id_tl }
          { {\color{ltxtalk-primary} #3} }
          { {\color{ltxtalk-secondary!55} #3} }
      }
      {
        \str_if_eq:nnT {#1} { 2 }
          {
            \bool_if:NT \g__ltxtalk_nav_in_current_bool
              {
                \int_compare:nNnT \g__ltxtalk_nav_map_int > { 0 } { \newline }
                \int_incr:N \g__ltxtalk_nav_map_int
                \hspace { 1em }
                \str_if_eq:eeTF {#2} { \g__ltxtalk_nav_subsec_id_tl }
                  { {\color{ltxtalk-primary} #3} }
                  { {\color{ltxtalk-secondary!55} #3} }
              }
          }
      }
  }

% \ldeen{Ein Punkt je Abschnitt: aktueller gefüllt in \code{ltxtalk-primary},
%   zurückliegende gefüllt gedämpft, folgende offen. Gefüllte und offene
%   Punkte werden als gleich große Kreise gezeichnet und hängen daher nicht
%   von den Formen der aktiven Mathematikschrift ab.}{One dot per section:
%   current filled in \code{ltxtalk-primary}, past filled and dimmed, upcoming
%   open. Filled and open dots are drawn as equal-sized circles and therefore
%   do not depend on the shapes of the active mathematics font.}
\cs_new_protected:Npn \__ltxtalk_nav_circle:n #1
  {
    \raisebox { -.08ex }
      {
        \hbox
          {
            \begin{pgfpicture}{0pt}{0pt}{.8ex}{.8ex}
              \pgfpathcircle { \pgfpoint{.4ex}{.4ex} } { .34ex }
              \pgfusepath {#1}
            \end{pgfpicture}
          }
      }
  }
\cs_new_protected:Npn \__ltxtalk_nav_render_section_dots:
  {
    \__ltxtalk_nav_measure:
    \int_gzero:N \g__ltxtalk_nav_map_int
    \seq_map_inline:Nn \g__ltxtalk_nav_toc_seq
      { \__ltxtalk_nav_dot_entry:nnnn ##1 }
  }
\cs_new_protected:Npn \__ltxtalk_nav_dot_entry:nnnn #1#2#3#4
  {
    \str_if_eq:nnT {#1} { 1 }
      {
        \int_compare:nNnT \g__ltxtalk_nav_map_int > { 0 } { \nobreakspace }
        \int_incr:N \g__ltxtalk_nav_map_int
        \int_compare:nNnTF \g__ltxtalk_nav_map_int = \g__ltxtalk_nav_index_int
          { {\color{ltxtalk-primary} \__ltxtalk_nav_circle:n { fill }} }
          {
            \int_compare:nNnTF \g__ltxtalk_nav_map_int < \g__ltxtalk_nav_index_int
              { {\color{ltxtalk-primary!45} \__ltxtalk_nav_circle:n { fill }} }
              { {\color{ltxtalk-secondary!45} \__ltxtalk_nav_circle:n { stroke }} }
          }
      }
  }

% \ldeen{Textueller Fortschritt \enquote{\meta{Position} / \meta{Anzahl}};
%   sprachneutral. Vor dem ersten Abschnitt (Titelseite, Inhaltsverzeichnis)
%   bleibt der Renderer leer.}{Textual progress \enquote{\meta{position} /
%   \meta{count}}; language-neutral. Before the first section (title page,
%   table of contents) the renderer stays empty.}
\cs_new_protected:Npn \__ltxtalk_nav_render_section_progress:
  {
    \__ltxtalk_nav_measure:
    \int_compare:nNnT \g__ltxtalk_nav_index_int > { 0 }
      {
        \int_use:N \g__ltxtalk_nav_index_int
        \nobreakspace / \nobreakspace
        \int_use:N \g__ltxtalk_nav_total_int
      }
  }

\DeclareLTXTalkNavigation { current-section }
  { \LTXTalkMetadata { section } }
\DeclareLTXTalkNavigation { current-subsection }
  { \LTXTalkMetadata { subsection } }
\DeclareLTXTalkNavigation { section-list }
  { \__ltxtalk_nav_use_structure: \__ltxtalk_nav_render_section_list: }
\DeclareLTXTalkNavigation { subsection-list }
  { \__ltxtalk_nav_use_structure: \__ltxtalk_nav_render_subsection_list: }
\DeclareLTXTalkNavigation { toc }
  { \__ltxtalk_nav_use_structure: \__ltxtalk_nav_render_toc: }
\DeclareLTXTalkNavigation { section-dots }
  { \__ltxtalk_nav_use_structure: \__ltxtalk_nav_render_section_dots: }
\DeclareLTXTalkNavigation { section-progress }
  { \__ltxtalk_nav_use_structure: \__ltxtalk_nav_render_section_progress: }

% ==========================================
% INHALTSELEMENTE
% ==========================================
% \ldeen{Eine \emph{Inhaltselement}-Instanz erzeugt formatierten, aber
%   ungetaggten Text (z.\,B. \enquote{3~/~12}); die semantische Tagging-Rolle
%   kommt -- wie bei jedem anderen Slot-Inhalt -- vom vierten Argument des
%   umgebenden \cs*{defineltxtalkslot}, nicht vom Element selbst. Drei
%   Schablonen decken die eingebauten Instanzen ab: \code{counter} (ein
%   einzelner Wert), \code{fraction} (zwei Werte mit Trennzeichen, z.\,B.
%   Seite~/~Gesamtzahl) und \code{heading} (optional nummerierter Text, z.\,B.
%   eine Abschnittsüberschrift). Neue Instanzen -- auch mit einer der drei
%   Schablonen und nur anderen Werten -- entstehen wie bei jedem anderen
%   Template-Typ über \cs{DeclareInstance}; vorhandene lassen sich mit
%   \cs{EditInstance} anpassen, etwa um das Trennzeichen zu ändern.}{A
%   \emph{content element} instance produces formatted but untagged text
%   (e.g.\ \enquote{3~/~12}); the semantic tagging role -- like for any other
%   slot content -- comes from the surrounding \cs*{defineltxtalkslot}'s
%   fourth argument, not from the element itself. Three templates cover the
%   built-in instances: \code{counter} (a single value), \code{fraction}
%   (two values with a separator, e.g.\ page~/~total) and \code{heading}
%   (optionally numbered text, e.g.\ a section heading). New instances --
%   even reusing one of the three templates with just different values --
%   are created like for any other template type, via \cs{DeclareInstance};
%   existing ones can be adjusted with \cs{EditInstance}, e.g.\ to change the
%   separator.}
\tl_new:N \l__ltxtalk_element_source_tl
\tl_new:N \l__ltxtalk_element_left_tl
\tl_new:N \l__ltxtalk_element_right_tl
\tl_new:N \l__ltxtalk_element_sep_tl
\tl_new:N \l__ltxtalk_element_number_tl
\tl_new:N \l__ltxtalk_element_level_tl
\tl_new:N \l__ltxtalk_element_text_tl
\bool_new:N \l__ltxtalk_element_numbered_bool

\NewTemplateType { ltxtalk-element } { 0 }

\DeclareTemplateInterface { ltxtalk-element } { counter } { 0 }
  { source : tokenlist = { } }
\DeclareTemplateCode { ltxtalk-element } { counter } { 0 }
  { source = \l__ltxtalk_element_source_tl }
  { \l__ltxtalk_element_source_tl }

\DeclareTemplateInterface { ltxtalk-element } { fraction } { 0 }
  {
    left      : tokenlist = { },
    right     : tokenlist = { },
    separator : tokenlist = { / },
  }
\DeclareTemplateCode { ltxtalk-element } { fraction } { 0 }
  {
    left      = \l__ltxtalk_element_left_tl,
    right     = \l__ltxtalk_element_right_tl,
    separator = \l__ltxtalk_element_sep_tl,
  }
  {
    \l__ltxtalk_element_left_tl
    \l__ltxtalk_element_sep_tl
    \l__ltxtalk_element_right_tl
  }

\DeclareTemplateInterface { ltxtalk-element } { heading } { 0 }
  {
    numbered  : boolean   = true,
    level     : tokenlist = { },
    number    : tokenlist = { },
    text      : tokenlist = { },
    separator : tokenlist = { ~ },
  }
\DeclareTemplateCode { ltxtalk-element } { heading } { 0 }
  {
    numbered  = \l__ltxtalk_element_numbered_bool,
    level     = \l__ltxtalk_element_level_tl,
    number    = \l__ltxtalk_element_number_tl,
    text      = \l__ltxtalk_element_text_tl,
    separator = \l__ltxtalk_element_sep_tl,
  }
  {
    \bool_lazy_and:nnT
      { \l__ltxtalk_element_numbered_bool }
      {
        \bool_lazy_or_p:nn
          { \tl_if_empty_p:N \l__ltxtalk_element_level_tl }
          {
            \bool_if_p:c
              { g__ltxtalk_ \l__ltxtalk_element_level_tl _numbered_bool }
          }
      }
      { \l__ltxtalk_element_number_tl \l__ltxtalk_element_sep_tl }
    \l__ltxtalk_element_text_tl
  }

\DeclareInstance { ltxtalk-element } { pagenumber } { counter }
  { source = \@framenumber }
\DeclareInstance { ltxtalk-element } { totalframes } { counter }
  { source = \@totalframes }
\DeclareInstance { ltxtalk-element } { pagenumber-of-total } { fraction }
  { left = \@framenumber, right = \@totalframes, separator = { / } }
\DeclareInstance { ltxtalk-element } { section-pagenumber } { fraction }
  { left = \insertsection, right = \@framenumber, separator = { ~--~ } }
\DeclareInstance { ltxtalk-element } { sectionheading } { heading }
  { level = section, number = \thesection, text = \insertsection }
\DeclareInstance { ltxtalk-element } { subsectionheading } { heading }
  { level = subsection, number = \thesubsection, text = \insertsubsection }

% \ldeen{\cs*{InsertLTXTalkElement}\Marg{Name} ist der einzige Aufrufpunkt für
%   Anwender: er reicht an \cs{UseInstance} durch, unabhängig davon, welche
%   der drei Schablonen die benannte Instanz tatsächlich verwendet.}{
%   \cs*{InsertLTXTalkElement}\Marg{name} is the only call site users need:
%   it forwards to \cs{UseInstance}, regardless of which of the three
%   templates the named instance actually uses.}
\NewDocumentCommand \InsertLTXTalkElement { m }
  { \UseInstance { ltxtalk-element } {#1} }

% ==========================================
% INITIALISIERUNG
% ==========================================

\AtBeginDocument{
  % Prüfen ob Themes geladen aber nicht aktiviert wurden
  \str_if_eq:VnT \g__ltxtalk_active_theme_tl { default }
    {
      \clist_map_inline:nn { minimal, magpie, hawk, sparrow, bluebird, goose, anchovy, carp }
        {
          \@ifpackageloaded{ltxtalk-theme-#1}
            {
              \msg_warning:nnn { ltxtalk } { theme-not-activated } { #1 }
            }{}
        }
    }
}

% ==========================================
% GENERIC PAGE-STYLE ADAPTER
% ==========================================
% \ldeen{Als Schnittstelle zu \pkg*{ltx-talk} dient der Seitenstil.
% }{
% The page style constitutes the interface to \pkg*{ltx-talk}.}
\seq_new:N \g__ltxtalk_header_slots_seq
\seq_new:N \g__ltxtalk_left_slots_seq
\seq_new:N \g__ltxtalk_content_slots_seq
\seq_new:N \g__ltxtalk_right_slots_seq
\seq_new:N \g__ltxtalk_footer_slots_seq
\prop_new:N \g__ltxtalk_slot_contents_prop

\coffin_new:N \l__ltxtalk_area_coffin
\coffin_new:N \l__ltxtalk_slot_coffin
\dim_new:N \l__ltxtalk_current_area_width_dim
\dim_new:N \l__ltxtalk_current_area_height_dim
\dim_new:N \l__ltxtalk_current_slot_width_dim
\dim_new:N \l__ltxtalk_current_slot_height_dim
\dim_new:N \l__ltxtalk_current_slot_x_dim
\dim_new:N \l__ltxtalk_current_slot_y_dim
\dim_new:N \l__ltxtalk_grid_star_width_dim
\dim_new:N \l__ltxtalk_grid_column_width_dim
\tl_new:N \l__ltxtalk_current_area_tl
\int_new:N \l__ltxtalk_grid_star_count_int
\dim_new:N \g__ltxtalk_base_left_margin_dim
\dim_new:N \g__ltxtalk_base_right_margin_dim
\dim_new:N \g__ltxtalk_base_top_margin_dim
\dim_new:N \g__ltxtalk_base_bottom_margin_dim
\dim_new:N \g__ltxtalk_current_left_margin_dim
\dim_new:N \g__ltxtalk_current_right_margin_dim
\dim_new:N \g__ltxtalk_current_top_margin_dim
\dim_new:N \g__ltxtalk_current_bottom_margin_dim
\dim_gset:Nn \g__ltxtalk_base_left_margin_dim {\Gm@lmargin}
\dim_gset:Nn \g__ltxtalk_base_right_margin_dim {\Gm@rmargin}
\dim_gset:Nn \g__ltxtalk_base_top_margin_dim {\Gm@tmargin}
\dim_gset:Nn \g__ltxtalk_base_bottom_margin_dim {\Gm@bmargin}

\NewExpandableDocumentCommand \LTXTalkBaseLeftMargin {}
  {\dim_use:N \g__ltxtalk_base_left_margin_dim}
\NewExpandableDocumentCommand \LTXTalkBaseRightMargin {}
  {\dim_use:N \g__ltxtalk_base_right_margin_dim}
\NewExpandableDocumentCommand \LTXTalkBaseTopMargin {}
  {\dim_use:N \g__ltxtalk_base_top_margin_dim}
\NewExpandableDocumentCommand \LTXTalkBaseBottomMargin {}
  {\dim_use:N \g__ltxtalk_base_bottom_margin_dim}
\NewExpandableDocumentCommand \LTXTalkCurrentLeftMargin {}
  {\dim_use:N \g__ltxtalk_current_left_margin_dim}
\NewExpandableDocumentCommand \LTXTalkCurrentRightMargin {}
  {\dim_use:N \g__ltxtalk_current_right_margin_dim}
\NewExpandableDocumentCommand \LTXTalkCurrentTopMargin {}
  {\dim_use:N \g__ltxtalk_current_top_margin_dim}
\NewExpandableDocumentCommand \LTXTalkCurrentBottomMargin {}
  {\dim_use:N \g__ltxtalk_current_bottom_margin_dim}

\NewTemplateType { lttheme-slot } { 1 }
\DeclareTemplateInterface { lttheme-slot } { standard } { 1 }
  {
    font        : tokenlist = {},
    font-slot   : tokenlist = companion,
    color       : tokenlist = ltxtalk-text,
    background  : tokenlist = none,
    background-fill : boolean = false,
    align       : choice { left, center, right } = center,
    frame       : choice { none, box, top, bottom, left, right } = none,
    padding     : length = 0pt,
    rule-color  : tokenlist = ltxtalk-primary,
    rule-thick  : length = 0.4pt,
    rotate      : tokenlist = 0,
    opacity     : tokenlist = 1,
    shadow      : boolean = false,
    uppercase   : boolean = false,
    lowercase   : boolean = false,
    space-after : length = 0pt
  }
\DeclareTemplateCode { lttheme-slot } { standard } { 1 }
  {
    font       = \l__ltxtalk_slot_font_tl,
    font-slot  = \l__ltxtalk_slot_font_slot_tl,
    color      = \l__ltxtalk_slot_color_tl,
    background = \l__ltxtalk_slot_bg_tl,
    background-fill = \l__ltxtalk_slot_bg_fill_bool,
    align      =
      {
        left   = \tl_set:Nn \l__ltxtalk_slot_align_tl { left },
        center = \tl_set:Nn \l__ltxtalk_slot_align_tl { center },
        right  = \tl_set:Nn \l__ltxtalk_slot_align_tl { right }
      },
    frame      =
      {
        none   = \tl_set:Nn \l__ltxtalk_slot_frame_tl { none },
        box    = \tl_set:Nn \l__ltxtalk_slot_frame_tl { box },
        top    = \tl_set:Nn \l__ltxtalk_slot_frame_tl { top },
        bottom = \tl_set:Nn \l__ltxtalk_slot_frame_tl { bottom },
        left   = \tl_set:Nn \l__ltxtalk_slot_frame_tl { left },
        right  = \tl_set:Nn \l__ltxtalk_slot_frame_tl { right }
      },
    padding    = \l__ltxtalk_slot_padding_dim,
    rule-color = \l__ltxtalk_slot_rule_tl,
    rule-thick = \l__ltxtalk_slot_rule_thick_dim,
    rotate = \l__ltxtalk_slot_rotate_tl,
    opacity = \l__ltxtalk_slot_opacity_tl,
    shadow = \l__ltxtalk_slot_shadow_bool,
    uppercase = \l__ltxtalk_slot_uppercase_bool,
    lowercase = \l__ltxtalk_slot_lowercase_bool,
    space-after = \l__ltxtalk_slot_space_after_dim
  }
  { \__ltxtalk_typeset_slot:n {#1} }

% \ldeen{\code{background-fill}: die Slotfläche wird in ihrer vollen erklärten
%   Breite und Höhe eingefärbt (verschachtelte \cs{parbox} in gleicher Grösse),
%   nicht nur hinter dem Text -- für Farbfelder in Kopf, Fuss oder Seitenleiste.
%   \code{padding} rückt den Text ein.}{\code{background-fill}: the slot area is
%   coloured at its full declared width and height (a nested \cs{parbox} of the
%   same size), not just behind the text -- for colour fields in a header,
%   footer, or sidebar. \code{padding} insets the text.}
\cs_new_protected:Npn \__ltxtalk_slot_bg_fill:n #1
  {
    \group_begin:
      \setlength\fboxsep{0pt}
      \colorbox { \l__ltxtalk_slot_bg_tl }
        {
          \parbox [c] [\l__ltxtalk_current_slot_height_dim] [c]
            { \l__ltxtalk_current_slot_width_dim }
            {
              \color { \l__ltxtalk_slot_color_tl }
              \str_case:Vn \l__ltxtalk_slot_align_tl
                {
                  { left }   { \raggedright }
                  { center } { \centering }
                  { right }  { \raggedleft }
                }
              % \ldeen{nach der Ausrichtung, da \cs{raggedright} \cs{leftskip}
              %   zurücksetzt}{after the alignment, since \cs{raggedright}
              %   resets \cs{leftskip}}
              \dim_add:Nn \leftskip  { \l__ltxtalk_slot_padding_dim }
              \dim_add:Nn \rightskip { \l__ltxtalk_slot_padding_dim }
              % \ldeen{\cs{strut}: eine \cs{parbox} mit leerem Inhalt fällt in
              %   der Breite zusammen, auch bei erzwungener Höhe.}{\cs{strut}: a
              %   \cs{parbox} with empty content collapses in width even when
              %   the height is forced.}
              \leavevmode \strut #1 \strut
              \par
            }
        }
    \group_end:
  }

\cs_new_protected:Npn \__ltxtalk_typeset_slot:n #1
  {
    \group_begin:
      \setlength\fboxsep{\l__ltxtalk_slot_padding_dim}
      \setlength\fboxrule{\l__ltxtalk_slot_rule_thick_dim}
      \color{\l__ltxtalk_slot_color_tl}
      \exp_args:NV \__ltxtalk_font_select:n \l__ltxtalk_slot_font_slot_tl
      \l__ltxtalk_slot_font_tl
      \str_case:Vn \l__ltxtalk_slot_align_tl
        {
          { left }   { \raggedright }
          { center } { \centering }
          { right }  { \raggedleft }
        }
      \str_if_eq:VnF \l__ltxtalk_slot_frame_tl { none }
        { \color{\l__ltxtalk_slot_rule_tl} }
      \str_if_eq:VnTF \l__ltxtalk_slot_frame_tl { box }
        {
          \fcolorbox{\l__ltxtalk_slot_rule_tl}
            {\str_if_eq:VnTF \l__ltxtalk_slot_bg_tl {none}{white}{\l__ltxtalk_slot_bg_tl}}
            {\color{\l__ltxtalk_slot_color_tl}#1}
        }
        {
          \str_if_eq:VnTF \l__ltxtalk_slot_bg_tl { none }
            {#1}
            {
              \bool_if:NTF \l__ltxtalk_slot_bg_fill_bool
                { \__ltxtalk_slot_bg_fill:n {#1} }
                { \colorbox{\l__ltxtalk_slot_bg_tl}
                    {\color{\l__ltxtalk_slot_color_tl}#1} }
            }
        }
      \par
      % \ldeen{Im Textfluss (Folientitel/-untertitel) trägt die umgebende
      %   vertikale Liste den \cs{baselineskip} des Fließtexts. Der ist zu
      %   klein, um unter einer in größerer Schrift gesetzten Slotzeile einen
      %   Abstand zu öffnen, sodass \cs{lineskip} greift und die Zeilen fast
      %   aneinanderstoßen. Hier -- noch mit der Slotschrift aktiv -- wird
      %   deshalb ein expliziter Abstand ergänzt: \code{space-after}, falls
      %   gesetzt, sonst schriftgrößenabhängig.}{
      %   In the text stream (frame title/subtitle) the surrounding vertical
      %   list carries the body text's \cs{baselineskip}. That is too small to
      %   open a gap below a slot line set in a larger font, so \cs{lineskip}
      %   takes over and the lines almost touch. Here -- still with the slot
      %   font active -- an explicit gap is therefore added: \code{space-after}
      %   if set, otherwise proportional to the font size.}
      \bool_if:NT \l__ltxtalk_slot_flow_bool
        {
          \dim_compare:nNnTF \l__ltxtalk_slot_space_after_dim > \c_zero_dim
            { \skip_vertical:N \l__ltxtalk_slot_space_after_dim }
            { \skip_vertical:n { 0.4 \baselineskip } }
        }
    \group_end:
  }

\NewTemplateType { lttheme-area } { 1 }
\DeclareTemplateInterface { lttheme-area } { standard } { 1 }
  {
    background     : tokenlist = none,
    background-split : tokenlist = ,
    background-gradient : tokenlist = ,
    frame          : choice { none, box, top, bottom, left, right, topbottom } = none,
    rule-color     : tokenlist = ltxtalk-primary,
    rule-thickness : length = 0.4pt,
    padding        : length = 0pt,
    artifact-type  : tokenlist = layout,
    background-opacity : tokenlist = 1,
    shadow         : boolean = false,
    shadow-color   : tokenlist = black!30,
    shadow-offset  : length = 3pt,
    margin-top     : length = 0pt,
    margin-bottom  : length = 0pt
  }
\DeclareTemplateCode { lttheme-area } { standard } { 1 }
  {
    background = \l__ltxtalk_area_background_tl,
    background-split = \l__ltxtalk_area_bg_split_tl,
    background-gradient = \l__ltxtalk_area_bg_gradient_tl,
    frame =
      {
        none      = \tl_set:Nn \l__ltxtalk_area_frame_tl { none },
        box       = \tl_set:Nn \l__ltxtalk_area_frame_tl { box },
        top       = \tl_set:Nn \l__ltxtalk_area_frame_tl { top },
        bottom    = \tl_set:Nn \l__ltxtalk_area_frame_tl { bottom },
        left      = \tl_set:Nn \l__ltxtalk_area_frame_tl { left },
        right     = \tl_set:Nn \l__ltxtalk_area_frame_tl { right },
        topbottom = \tl_set:Nn \l__ltxtalk_area_frame_tl { topbottom }
      },
    rule-color = \l__ltxtalk_area_rule_color_tl,
    rule-thickness = \l__ltxtalk_area_rule_thickness_dim,
    padding = \l__ltxtalk_area_padding_dim,
    artifact-type = \l__ltxtalk_area_artifact_tl,
    background-opacity = \l__ltxtalk_area_bg_opacity_tl,
    shadow = \l__ltxtalk_area_shadow_bool,
    shadow-color = \l__ltxtalk_area_shadow_color_tl,
    shadow-offset = \l__ltxtalk_area_shadow_offset_dim,
    margin-top = \l__ltxtalk_area_margin_top_dim,
    margin-bottom = \l__ltxtalk_area_margin_bottom_dim
  }
  { \__ltxtalk_typeset_area_background:n {#1} }

\clist_map_inline:nn { header, left, content, right, footer }
  { \DeclareInstance { lttheme-area } {#1} { standard } { } }

\cs_new_protected:Npn \__ltxtalk_typeset_area_background:n #1
  {
    \group_begin:
      \setlength\fboxsep{0pt}
      \clist_if_in:nVT {top,topbottom,box} \l__ltxtalk_area_frame_tl
        {
          \color{\l__ltxtalk_area_rule_color_tl}
          \rule{\l__ltxtalk_current_area_width_dim}
            {\l__ltxtalk_area_rule_thickness_dim}\par\nointerlineskip
        }
      \bool_lazy_any:nTF
        {
          { \str_if_eq_p:Vn \l__ltxtalk_area_background_tl { none } }
          { ! \tl_if_blank_p:V \l__ltxtalk_area_bg_split_tl }
          { ! \tl_if_blank_p:V \l__ltxtalk_area_bg_gradient_tl }
        }
        {\parbox[c][\l__ltxtalk_current_area_height_dim][c]
           {\l__ltxtalk_current_area_width_dim}
           {\__ltxtalk_typeset_area_sides:n {#1}}}
        {\colorbox{\l__ltxtalk_area_background_tl}
           {\parbox[c][\l__ltxtalk_current_area_height_dim][c]
             {\l__ltxtalk_current_area_width_dim}
             {\__ltxtalk_typeset_area_sides:n {#1}}}}
      \clist_if_in:nVT {bottom,topbottom,box} \l__ltxtalk_area_frame_tl
        {
          \par\nointerlineskip\color{\l__ltxtalk_area_rule_color_tl}
          \rule{\l__ltxtalk_current_area_width_dim}
            {\l__ltxtalk_area_rule_thickness_dim}
        }
    \group_end:
  }
\cs_new_protected:Npn \__ltxtalk_typeset_area_sides:n #1
  {
    \tl_if_blank:VF \l__ltxtalk_area_bg_split_tl
      { \__ltxtalk_area_bg_split_draw: }
    \tl_if_blank:VF \l__ltxtalk_area_bg_gradient_tl
      { \__ltxtalk_area_bg_gradient_draw: }
    \str_if_eq:VnT \l__ltxtalk_area_frame_tl {left}
      {
        \color{\l__ltxtalk_area_rule_color_tl}
        \rule{\l__ltxtalk_area_rule_thickness_dim}
          {\l__ltxtalk_current_area_height_dim}\hspace{\l__ltxtalk_area_padding_dim}
      }
    #1
    \str_if_eq:VnT \l__ltxtalk_area_frame_tl {right}
      {
        \hfill\color{\l__ltxtalk_area_rule_color_tl}
        \rule{\l__ltxtalk_area_rule_thickness_dim}
          {\l__ltxtalk_current_area_height_dim}
      }
  }
% \ldeen{Ein farblich geteilter Bereichshintergrund: \code{background-split}
%   nennt Farben, wahlweise mit Gewicht (\code{farbe*2}). Die Segmente werden
%   als \cs{rule}"=Kette ohne horizontale Ausdehnung (\cs{rlap}) hinter die
%   Slots gelegt und als Artefakt getaggt; das letzte Segment füllt exakt bis
%   zur Bereichskante, damit Rundung keine Lücke lässt.}{A colour-divided
%   area background: \code{background-split} lists colours, optionally
%   weighted (\code{colour*2}). The segments are a \cs{rule} chain that fills
%   the area's width and height like the \code{frame} rules, tagged as an
%   artifact; the last segment fills exactly to the area edge so rounding
%   leaves no gap. The strut \code{#1} that follows keeps the line box at the
%   full area height.}
\cs_new_protected:Npn \__ltxtalk_area_bg_split_draw:
  {
    \clist_set:NV \l__ltxtalk_area_bg_split_clist \l__ltxtalk_area_bg_split_tl
    \fp_zero:N \l__ltxtalk_area_bg_split_wt_fp
    \clist_map_inline:Nn \l__ltxtalk_area_bg_split_clist
      { \__ltxtalk_area_bg_split_weight:n {##1} }
    \dim_zero:N \l__ltxtalk_area_bg_split_x_dim
    \int_zero:N \l_tmpa_int
    \tag_mc_begin:n { artifact }
    \clist_map_inline:Nn \l__ltxtalk_area_bg_split_clist
      { \__ltxtalk_area_bg_split_seg:n {##1} }
    \tag_mc_end:
    \skip_horizontal:n { -\l__ltxtalk_current_area_width_dim }
  }
\cs_new_protected:Npn \__ltxtalk_area_bg_split_weight:n #1
  {
    \seq_set_split:Nnn \l_tmpa_seq { * } {#1}
    \fp_add:Nn \l__ltxtalk_area_bg_split_wt_fp
      {
        \int_compare:nNnTF { \seq_count:N \l_tmpa_seq } > { 1 }
          { \seq_item:Nn \l_tmpa_seq { 2 } } { 1 }
      }
  }
\cs_new_protected:Npn \__ltxtalk_area_bg_split_seg:n #1
  {
    \int_incr:N \l_tmpa_int
    \seq_set_split:Nnn \l_tmpa_seq { * } {#1}
    \int_compare:nNnTF \l_tmpa_int = { \clist_count:N \l__ltxtalk_area_bg_split_clist }
      {
        \dim_set:Nn \l__ltxtalk_area_bg_split_seg_dim
          { \l__ltxtalk_current_area_width_dim - \l__ltxtalk_area_bg_split_x_dim }
      }
      {
        \dim_set:Nn \l__ltxtalk_area_bg_split_seg_dim
          {
            \fp_to_dim:n
              {
                \l__ltxtalk_current_area_width_dim *
                ( \int_compare:nNnTF { \seq_count:N \l_tmpa_seq } > { 1 }
                    { \seq_item:Nn \l_tmpa_seq { 2 } } { 1 } )
                / \l__ltxtalk_area_bg_split_wt_fp
              }
          }
      }
    \dim_add:Nn \l__ltxtalk_area_bg_split_x_dim \l__ltxtalk_area_bg_split_seg_dim
    \exp_args:Ne \__ltxtalk_area_bg_split_rule:n
      { \tl_trim_spaces:n { \seq_item:Nn \l_tmpa_seq { 1 } } }
  }
\cs_new_protected:Npn \__ltxtalk_area_bg_split_rule:n #1
  {
    { \color{#1}
      \rule
        { \l__ltxtalk_area_bg_split_seg_dim }
        { \l__ltxtalk_current_area_height_dim } }
  }
% \ldeen{Ein senkrechter Farbverlauf als Bereichshintergrund:
%   \code{background-gradient=\{oben, unten\}}. Als Stapel von
%   \cs{rule}"=Bändern gezeichnet (mischt \code{oben!\meta{p}!unten}), wie
%   \code{background-split} als Artefakt hinter die Slots gelegt; danach
%   wird die vertikale Position zurückgesetzt. Keine
%   \pkg{pgf}"=Abhängigkeit; auf Projektionsdistanz stufenlos.}{A vertical
%   colour gradient as the area background:
%   \code{background-gradient=\{top, bottom\}}. Drawn as a stack of
%   \cs{rule} bands (mixing \code{top!\meta{p}!bottom}), placed behind the
%   slots as an artifact like \code{background-split}, with the vertical
%   position reset afterwards. No \pkg{pgf} dependency; smooth at
%   projection distance.}
\int_const:Nn \c__ltxtalk_area_gradient_steps_int { 24 }
\cs_new_protected:Npn \__ltxtalk_area_bg_gradient_draw:
  {
    \clist_set:NV \l__ltxtalk_area_bg_split_clist \l__ltxtalk_area_bg_gradient_tl
    % Pre-mix the endpoints into flat names so the band colour
    % "from!p!to" is a simple two-way mix, not a left-folded chain.
    \exp_args:Nne \colorlet { ltxtalk@grad@from }
      { \clist_item:Nn \l__ltxtalk_area_bg_split_clist { 1 } }
    \exp_args:Nne \colorlet { ltxtalk@grad@to }
      { \clist_item:Nn \l__ltxtalk_area_bg_split_clist { 2 } }
    \dim_set:Nn \l__ltxtalk_area_bg_split_seg_dim
      { \l__ltxtalk_current_area_height_dim
        / \c__ltxtalk_area_gradient_steps_int }
    \tag_mc_begin:n { artifact }
    \int_step_inline:nn { \c__ltxtalk_area_gradient_steps_int }
      {
        \noindent
        \exp_args:Ne \__ltxtalk_area_grad_band:n
          {
            \fp_eval:n
              {
                round ( 100 *
                  ( \c__ltxtalk_area_gradient_steps_int - ##1 + 0.5 )
                  / \c__ltxtalk_area_gradient_steps_int )
              }
          }
        \par \nointerlineskip
      }
    \tag_mc_end:
    \skip_vertical:n { -\l__ltxtalk_current_area_height_dim }
  }
\cs_new_protected:Npn \__ltxtalk_area_grad_band:n #1
  {
    \color { ltxtalk@grad@from ! #1 ! ltxtalk@grad@to }
    \rule { \l__ltxtalk_current_area_width_dim }
          { \l__ltxtalk_area_bg_split_seg_dim }
  }
% \ldeen{Über Sockets können die einzelnen Bereichebehandlungen gezielt ersetzt werden.
% }{
% The different area handler can be specificaly replcaced by means of sockets.}
\NewSocket { lttheme/page/background } { 0 }
\NewSocket { lttheme/area/header } { 0 }
\NewSocket { lttheme/area/left } { 0 }
\NewSocket { lttheme/area/right } { 0 }
\NewSocket { lttheme/area/footer } { 0 }
\NewSocket { lttheme/page/foreground } { 0 }
\NewSocketPlug { lttheme/page/background } { standard } { }
\NewSocketPlug { lttheme/page/background } { magpie-title }
  {
    \int_compare:nNnT {\@framenumber} = {1}
      {
        \tag_mc_begin:n {artifact}
        \raisebox{-2.05cm}[0pt][0pt]
          {\color{ltxtalk-primary}\rule{\paperwidth}{1.55cm}}
        \tag_mc_end:
      }
  }
\NewSocketPlug { lttheme/area/header } { standard }
  { \__ltxtalk_render_area:nnn {header}{\paperwidth}{\l__ltxtalk_header_height_dim} }
\cs_new_protected:Npn \__ltxtalk_render_standard_side_area:nn #1#2
  {
    \dim_set:Nn \l_tmpa_dim { \paperheight }
    \bool_if:NT \l__ltxtalk_show_header_bool
      { \dim_sub:Nn \l_tmpa_dim { \l__ltxtalk_header_height_dim } }
    \bool_if:NT \l__ltxtalk_show_footer_bool
      { \dim_sub:Nn \l_tmpa_dim { \l__ltxtalk_footer_height_dim } }
    \__ltxtalk_render_area:nnn {#1}{#2}{\l_tmpa_dim}
  }
\NewSocketPlug { lttheme/area/left } { standard }
  { \__ltxtalk_render_standard_side_area:nn
      {left}{\l__ltxtalk_left_area_width_dim} }
\NewSocketPlug { lttheme/area/left } { hawk }
  { \__ltxtalk_render_area:nnn {left}{\l__ltxtalk_left_area_width_dim}{\paperheight} }
\NewSocketPlug { lttheme/area/right } { standard }
  { \__ltxtalk_render_standard_side_area:nn
      {right}{\l__ltxtalk_right_area_width_dim} }
\NewSocketPlug { lttheme/area/right } { goose }
  { \__ltxtalk_render_area:nnn {right}{\l__ltxtalk_right_area_width_dim}{\paperheight} }
\NewSocketPlug { lttheme/area/footer } { standard }
  { \__ltxtalk_render_area:nnn {footer}{\paperwidth}{\l__ltxtalk_footer_height_dim} }
\NewSocketPlug { lttheme/page/foreground } { standard } { }
\NewSocketPlug { lttheme/page/foreground } { magpie-title }
  {
    \int_compare:nNnT {\@framenumber} = {1}
      {
        \tag_mc_begin:n {artifact}
        \raisebox{-1.42cm}[0pt][0pt]
          {\parbox[c][1.25cm][c]{\paperwidth}
            {\centering\color{white}\sffamily
             \Large\bfseries\@title\par
             \small\mdseries\@subtitle}}
        \tag_mc_end:
      }
  }
\NewSocketPlug { lttheme/page/foreground } { sparrow-bars }
  {
    \tag_mc_begin:n {artifact}
    \raisebox{\dim_eval:n{\Gm@tmargin-\headsep}}[0pt][0pt]
      {\vbox to 0pt
        {
          \color{ltxtalk-primary!35}\rlap{\rule{\paperwidth}{0.35pt}}
          \vskip 0.42cm
          \color{ltxtalk-primary!20}\rlap{\rule{\paperwidth}{0.35pt}}
          \vskip 0.30cm
          \color{ltxtalk-primary!45}\rlap{\rule{\paperwidth}{0.7pt}}
          \vss
        }}
    \tag_mc_end:
  }
\clist_map_inline:nn
  { page/background, area/header, area/left, area/right, area/footer, page/foreground }
  { \AssignSocketPlug { lttheme/#1 } { standard } }

% \ldeen{
%   Ein Theme kann jederzeit im Dokument gewechselt werden; die Doku-Galerie
%   nutzt genau das. \cs{__ltxtalk_clear_theme_state:} muss deshalb jede
%   Spur des vorigen Themes tilgen, nicht nur dessen Slots. Die Layout-Keys
%   und die Titelplatzierung werden auf die Paket-Vorgaben zurückgesetzt, und
%   die fünf Flächen-Instanzen -- \code{header}, \code{left}, \code{content},
%   \code{right}, \code{footer} tragen feste Namen und werden über das
%   gesamte Dokument wiederverwendet -- werden neu deklariert, damit
%   \cs{decorateltxtalkarea} des Vorgängers (Hintergrund, Rahmen, Ränder)
%   nicht in das nächste Theme durchschlägt.
% }{
%   A theme may be switched at any point in the document; the gallery in the
%   documentation does exactly that. \cs{__ltxtalk_clear_theme_state:} must
%   therefore erase every trace of the previous theme, not just its slots.
%   The layout keys and the title placement are restored to the package
%   defaults, and the five area instances -- \code{header}, \code{left},
%   \code{content}, \code{right}, \code{footer} carry fixed names and are
%   reused for the whole document -- are redeclared so that the predecessor's
%   \cs{decorateltxtalkarea} (background, frame, margins) does not bleed into
%   the next theme.
% }
\cs_new_protected:Npn \__ltxtalk_reset_layout_state:
  {
    \keys_set:nn { ltxtalk / layout }
      {
        header = false, header-height = 1.5cm, header-rows = 1,
        left-margin = false, right-margin = false,
        footer = false, footer-height = 1cm,
        margin-width = 2.5cm,
        left-area-width = 2.5cm, right-area-width = 2.5cm,
        content-inset-left = 2.5cm, content-inset-right = 2.5cm,
        header-columns = { 0.2, 0.6, 0.2 },
        footer-columns = { 0.33, 0.34, 0.33 },
      }
    \tl_gset:Nn \g__ltxtalk_frametitle_target_tl { content }
    \tl_gset:Nn \g__ltxtalk_section_target_tl { none }
    \clist_map_inline:nn { header, left, content, right, footer }
      { \DeclareInstance { lttheme-area } {##1} { standard } { } }
  }

\cs_new_protected:Npn \__ltxtalk_clear_theme_state:
  {
    \__ltxtalk_reset_layout_state:
    \bool_if:NF \g__ltxtalk_outeronly_bool
      { \UseOsgFontPalette { ltxtalk-default } }
    \AssignSocketPlug { lttheme/page/background } { standard }
    \AssignSocketPlug { lttheme/area/header } { standard }
    \AssignSocketPlug { lttheme/area/left } { standard }
    \AssignSocketPlug { lttheme/area/right } { standard }
    \AssignSocketPlug { lttheme/area/footer } { standard }
    \AssignSocketPlug { lttheme/page/foreground } { standard }
    \prop_gclear:N \g__ltxtalk_slot_types_prop
    \prop_gclear:N \g__ltxtalk_slot_positions_prop
    \prop_gclear:N \g__ltxtalk_slot_styles_prop
    \prop_gclear:N \g__ltxtalk_slot_areas_prop
    \prop_gclear:N \g__ltxtalk_slot_accessibility_prop
    \prop_gclear:N \g__ltxtalk_area_grid_columns_prop
    \prop_gclear:N \g__ltxtalk_area_grid_rows_prop
    \prop_gclear:N \g__ltxtalk_slot_grid_positions_prop
    \prop_gclear:N \g__ltxtalk_slot_contents_prop
    \prop_gclear:N \g__ltxtalk_area_decorations_prop
    \prop_gclear:N \g__ltxtalk_layouts_prop
    \prop_gclear:N \g__ltxtalk_layout_code_prop
    \prop_gclear:N \g__ltxtalk_title_layout_code_prop
    \seq_gclear:N \g__ltxtalk_header_slots_seq
    \seq_gclear:N \g__ltxtalk_left_slots_seq
    \seq_gclear:N \g__ltxtalk_content_slots_seq
    \seq_gclear:N \g__ltxtalk_right_slots_seq
    \seq_gclear:N \g__ltxtalk_footer_slots_seq
    % Block appearance is an osgstyler-block instance edit, not reset by the
    % clears above; a theme that styles its blocks would otherwise leak that
    % style into the next theme.  Restore the lttheme default -- through
    % \DeclareOsgBlockInstance (not raw \DeclareInstance) so the titled-layout
    % record is cleared with it.  The default is the \enquote{card} look (a
    % lightly framed, faintly tinted box), so a block is always clearly
    % marked even under a theme that does not style its blocks.
    % Not looped: the \code{traits} key nests a \cs{clist_map_inline:nn} of
    % its own, which must not run inside another one.
    \DeclareOsgBlockInstance { block }        { traits = card }
    \DeclareOsgBlockInstance { alertblock }   { traits = card }
    \DeclareOsgBlockInstance { exampleblock } { traits = card }
    \StyleOsgBlockInstance { alertblock }
      { head-color = alert, rule-color = alert!55, background = alert!6 }
    \StyleOsgBlockInstance { exampleblock }
      { head-color = example, rule-color = example!55, background = example!6 }
  }

\cs_new_protected:Npn \__ltxtalk_update_text_area:
  {
    \dim_gset_eq:NN \g__ltxtalk_current_left_margin_dim
      \g__ltxtalk_base_left_margin_dim
    \dim_gset_eq:NN \g__ltxtalk_current_right_margin_dim
      \g__ltxtalk_base_right_margin_dim
    \dim_gset_eq:NN \g__ltxtalk_current_top_margin_dim
      \g__ltxtalk_base_top_margin_dim
    \dim_gset_eq:NN \g__ltxtalk_current_bottom_margin_dim
      \g__ltxtalk_base_bottom_margin_dim
    \bool_if:NT \l__ltxtalk_show_left_margin_bool
      {
        \dim_gadd:Nn \g__ltxtalk_current_left_margin_dim
          {\l__ltxtalk_content_inset_left_dim}
      }
    \bool_if:NT \l__ltxtalk_show_right_margin_bool
      {
        \dim_gadd:Nn \g__ltxtalk_current_right_margin_dim
          {\l__ltxtalk_content_inset_right_dim}
      }
    % The header and footer are page overlays, whereas ordinary frame
    % contents occupy LaTeX's text area. Keep that text outside every visible
    % theme area and retain \headsep as the gap below the header. Title pages
    % are deliberately exempt: their layouts already compose their contents
    % against the decorative page areas and carry their own vertical spacing.
    \bool_if:NF \l__ltxtalk_title_page_bool
      {
        \bool_if:NT \l__ltxtalk_show_header_bool
          {
            \dim_gset:Nn \g__ltxtalk_current_top_margin_dim
              {
                \dim_max:nn
                  {\g__ltxtalk_base_top_margin_dim}
                  {\l__ltxtalk_header_height_dim+\headsep}
              }
          }
        \bool_if:NT \l__ltxtalk_show_footer_bool
          {
            \dim_gset:Nn \g__ltxtalk_current_bottom_margin_dim
              {
                \dim_max:nn
                  {\g__ltxtalk_base_bottom_margin_dim}
                  {\l__ltxtalk_footer_height_dim}
              }
          }
      }
    \cs_gset:Npx \Gm@lmargin
      {\dim_use:N \g__ltxtalk_current_left_margin_dim}
    \cs_gset:Npx \Gm@rmargin
      {\dim_use:N \g__ltxtalk_current_right_margin_dim}
    \cs_gset:Npx \Gm@tmargin
      {\dim_use:N \g__ltxtalk_current_top_margin_dim}
    \cs_gset:Npx \Gm@bmargin
      {\dim_use:N \g__ltxtalk_current_bottom_margin_dim}
    \dim_gset:Nn \textwidth
      {
        \paperwidth-\g__ltxtalk_current_left_margin_dim
        -\g__ltxtalk_current_right_margin_dim
      }
    \dim_gset:Nn \oddsidemargin
      {\g__ltxtalk_current_left_margin_dim-1in}
    \dim_gset_eq:NN \evensidemargin \oddsidemargin
    \dim_gset_eq:NN \columnwidth \textwidth
    \dim_gset_eq:NN \linewidth \textwidth
    \dim_gset_eq:NN \hsize \textwidth
    \dim_gset:Nn \textheight
      {
        \paperheight-\g__ltxtalk_current_top_margin_dim
        -\g__ltxtalk_current_bottom_margin_dim
      }
    % geometry is loaded without includehead: its top margin denotes the
    % beginning of the text body, while \topmargin is measured to the header
    % baseline machinery. Mirror geometry's conversion and refresh the
    % output routine dimensions, as \newgeometry would do, without forcing a
    % page break during an lttheme layout switch.
    \dim_gset:Nn \topmargin
      {
        \g__ltxtalk_current_top_margin_dim
        -1in-\headheight-\headsep
      }
    \dim_gset_eq:NN \@colht \textheight
    \dim_gset_eq:NN \@colroom \textheight
    \dim_gset_eq:NN \vsize \textheight
  }

\NewDocumentCommand \setltxtalkslotcontent { m m } {
  \prop_gput:Nnn \g__ltxtalk_slot_contents_prop {#1} {#2}
}

\NewDocumentCommand \useltxtalktheme { m } {
  \str_if_eq:nnTF {#1} {default}
    {
      \__ltxtalk_clear_theme_state:
      \tl_gset:Nn \g__ltxtalk_active_theme_tl {default}
      \__ltxtalk_update_text_area:
      \pagestyle{talk}
    }
    {
      % \ldeen{Das Setup in einer eigenen Variablen halten, nicht in
      %   \cs{l_tmpa_tl}: \cs{__ltxtalk_clear_theme_state:} ruft Fremdcode
      %   (osgstyler-Block-Traits), der \cs{l_tmpa_tl} überschreiben darf.}{
      %   Keep the setup in a dedicated variable, not \cs{l_tmpa_tl}:
      %   \cs{__ltxtalk_clear_theme_state:} calls out to third-party code
      %   (osgstyler block traits) that is free to clobber \cs{l_tmpa_tl}.}
      \prop_get:NnNTF \g__ltxtalk_themes_prop {#1} \l__ltxtalk_theme_setup_tl
        {
          \__ltxtalk_clear_theme_state:
          \tl_gset:Nn \g__ltxtalk_active_theme_tl {#1}
          \l__ltxtalk_theme_setup_tl
          \__ltxtalk_apply_class_templates:
        }
        { \msg_error:nnn {ltxtalk}{unknown-theme}{#1} }
    }
}

\NewDocumentCommand \addltxtalktheme { m } {
  \prop_get:NnNTF \g__ltxtalk_themes_prop {#1} \l_tmpa_tl
    { \l_tmpa_tl \__ltxtalk_apply_class_templates: }
    { \msg_error:nnn {ltxtalk}{unknown-theme}{#1} }
}

% \ldeen{Folientitel und -untertitel sind \emph{nur} im Textstrom des Frames
%   Strukturelemente; in Kopf-/Rand-/Fußbereichen sind sie reiner
%   Artefakt-Text (dort ist ohnehin ein Artefakt-MC offen). Damit gibt es
%   genau einen Tagging-Mechanismus, unabhängig davon, wo ein Theme den
%   Titel zeigt. Der Slottyp \code{frametitle} behält \cls*{ltx-talk}s
%   Strukturtyp \code{frametitle} (samt dessen abschnittstiefen-abhängigem
%   RoleMap) und wird per \code{firstkid} vor bereits vorhandenen Frame-Inhalt
%   gestellt, nutzt aber \cs{__ltxtalk_flow_struct:nn} statt
%   \cs{__talk_frame_title:n} (siehe dort zum Grund). Der Untertitel läuft
%   wie jeder andere Slot über seine deklarierte Rolle.}{Frame title and
%   subtitle are structure elements \emph{only} in the frame's text stream;
%   in header/margin/footer areas they are plain artifact text (an artifact
%   MC is open there anyway). This gives exactly one tagging mechanism,
%   regardless of where a theme shows the title. The \code{frametitle} slot
%   type keeps \cls*{ltx-talk}'s structure type \code{frametitle} (with its
%   section-depth-dependent role map) and is placed before already existing
%   frame content via \code{firstkid}, but uses \cs{__ltxtalk_flow_struct:nn}
%   instead of \cs{__talk_frame_title:n} (see there for the reason). The
%   subtitle goes through its declared role like any other slot.}
\cs_new:Npn \__ltxtalk_frame_title_struct_keys:
  {
    firstkid = true ,
    tag      = frametitle ,
    title    = { \text_purify:n { \g__talk_frame_title_tl } }
  }
\cs_new_protected:Npn \__ltxtalk_slot_content:n #1
  {
    \prop_get:NnN \g__ltxtalk_slot_types_prop {#1} \l__ltxtalk_slot_type_tl
    \bool_lazy_and:nnTF
      { ! \l__ltxtalk_slot_flow_bool }
      {
        \bool_lazy_or_p:nn
          { \str_if_eq_p:Vn \l__ltxtalk_slot_type_tl {frametitle} }
          { \str_if_eq_p:Vn \l__ltxtalk_slot_type_tl {framesubtitle} }
      }
      {
        \str_if_eq:VnTF \l__ltxtalk_slot_type_tl {frametitle}
          { \tl_use:N \g__talk_frame_title_tl }
          { \tl_use:N \g__talk_frame_subtitle_tl }
      }
      {
       \str_if_eq:VnTF \l__ltxtalk_slot_type_tl {frametitle}
        {
          \bool_if:NTF \g__talk_frame_tag_bool
            {
              \__ltxtalk_flow_struct:nn { \__ltxtalk_frame_title_struct_keys: }
                { \tl_use:N \g__talk_frame_title_tl }
            }
            { \tl_use:N \g__talk_frame_title_tl }
        }
        {
        \__ltxtalk_slot_accessibility_apply:nn {#1}
          {
            \str_case:VnF \l__ltxtalk_slot_type_tl
              {
                {title}         {\LTXTalkMetadata{short-title}}
                {subtitle}      {\LTXTalkMetadata{short-subtitle}}
                {author}        {\LTXTalkMetadata{short-author}}
                {date}          {\LTXTalkMetadata{date}}
                {institute}     {\LTXTalkMetadata{short-institute}}
                {section}       {\LTXTalkMetadata{section}}
                {subsection}    {\LTXTalkMetadata{subsection}}
                {framesubtitle} {\tl_use:N \g__talk_frame_subtitle_tl}
                {pagenumber}    {\LTXTalkMetadata{framenumber}}
              }
              { \prop_item:Nn \g__ltxtalk_slot_contents_prop {#1} }
          }
        }
      }
  }

\cs_new_protected:Npn \__ltxtalk_render_slot:n #1
  {
    \prop_get:NnNTF \g__ltxtalk_slot_grid_positions_prop {#1} \l_tmpa_tl
      {\exp_after:wN \__ltxtalk_render_grid_slot_aux:w
        \l_tmpa_tl \q_stop {#1}}
      {\prop_get:NnNT \g__ltxtalk_slot_positions_prop {#1} \l_tmpa_tl
        {\exp_after:wN \__ltxtalk_render_slot_aux:w
          \l_tmpa_tl \q_stop {#1}}}
  }
\cs_new_protected:Npn \__ltxtalk_render_grid_slot_aux:w
  #1#2#3#4 \q_stop #5
  {\__ltxtalk_render_grid_slot:nnnnn {#5}{#1}{#2}{#3}{#4}}
\cs_new_protected:Npn \__ltxtalk_render_grid_slot:nnnnn #1#2#3#4#5
  {
    \prop_get:NVN \g__ltxtalk_area_grid_columns_prop
      \l__ltxtalk_current_area_tl \l_tmpa_tl
    \prop_get:NVN \g__ltxtalk_area_grid_rows_prop
      \l__ltxtalk_current_area_tl \l_tmpb_tl
    \clist_set:NV \l_tmpa_clist \l_tmpa_tl
    \dim_zero:N \l_tmpa_dim
    \int_zero:N \l__ltxtalk_grid_star_count_int
    \clist_map_inline:Nn \l_tmpa_clist
      {\str_if_eq:nnTF {##1}{*}
        {\int_incr:N \l__ltxtalk_grid_star_count_int}
        {\dim_add:Nn \l_tmpa_dim {##1}}}
    \int_compare:nNnTF {\l__ltxtalk_grid_star_count_int} > {0}
      {
        \dim_set_eq:NN \l__ltxtalk_grid_star_width_dim
          \l__ltxtalk_current_area_width_dim
        \dim_sub:Nn \l__ltxtalk_grid_star_width_dim {\l_tmpa_dim}
        \dim_set:Nn \l__ltxtalk_grid_star_width_dim
          {\l__ltxtalk_grid_star_width_dim/\l__ltxtalk_grid_star_count_int}
      }
      {\dim_zero:N \l__ltxtalk_grid_star_width_dim}
    \dim_zero:N \l__ltxtalk_current_slot_x_dim
    \dim_zero:N \l__ltxtalk_current_slot_width_dim
    \int_zero:N \l_tmpa_int
    \clist_map_inline:Nn \l_tmpa_clist
      {
        \int_incr:N \l_tmpa_int
        \str_if_eq:nnTF {##1}{*}
          {\dim_set_eq:NN \l__ltxtalk_grid_column_width_dim
             \l__ltxtalk_grid_star_width_dim}
          {\dim_set:Nn \l__ltxtalk_grid_column_width_dim {##1}}
        \int_compare:nNnT {\l_tmpa_int} < {#2}
          {\dim_add:Nn \l__ltxtalk_current_slot_x_dim
            {\l__ltxtalk_grid_column_width_dim}}
        \int_compare:nT {\l_tmpa_int >= #2}
          {\int_compare:nT {\l_tmpa_int < #2+#4}
            {\dim_add:Nn \l__ltxtalk_current_slot_width_dim
              {\l__ltxtalk_grid_column_width_dim}}}
      }
    \dim_set:Nn \l_tmpa_dim
      {\l__ltxtalk_current_area_height_dim/\l_tmpb_tl}
    \dim_set:Nn \l__ltxtalk_current_slot_y_dim
      {\int_eval:n {#3-1}\l_tmpa_dim}
    \dim_set:Nn \l__ltxtalk_current_slot_height_dim
      {#5\l_tmpa_dim}
    \__ltxtalk_render_slot:nnnnn {#1}
      {\l__ltxtalk_current_slot_x_dim}{\l__ltxtalk_current_slot_y_dim}
      {\l__ltxtalk_current_slot_width_dim}{\l__ltxtalk_current_slot_height_dim}
  }
\cs_new_protected:Npn \__ltxtalk_render_slot_aux:w #1#2#3#4 \q_stop #5
  { \__ltxtalk_render_slot:nnnnn {#5}{#1}{#2}{#3}{#4} }
% \ldeen{Ermittelt die für einen Slot deklarierte Rolle (Vorgabe
%   \code{artifact}) in \cs{l__ltxtalk_slot_role_tl} -- dieselbe
%   Auswertung wie in \cs{__ltxtalk_slot_accessibility_apply:nn}, hier
%   separat aufrufbar, weil \cs{__ltxtalk_render_slot:nnnnn} sie schon
%   \emph{vor} dem Aufbau der Slot-\cs{parbox} braucht (siehe dort).}{
%   Determines the role declared for a slot (default \code{artifact})
%   into \cs{l__ltxtalk_slot_role_tl} -- the same evaluation as in
%   \cs{__ltxtalk_slot_accessibility_apply:nn}, callable separately here
%   because \cs{__ltxtalk_render_slot:nnnnn} needs it \emph{before}
%   building the slot's \cs{parbox} (see there).}
\cs_new_protected:Npn \__ltxtalk_slot_role:n #1
  {
    \tl_set:Nn \l__ltxtalk_slot_role_tl { artifact }
    \prop_get:NnNT \g__ltxtalk_slot_accessibility_prop {#1} \l_tmpa_tl
      { \keys_set:nV { ltxtalk / a11y } \l_tmpa_tl }
  }
\cs_new_protected:Npn \__ltxtalk_render_slot:nnnnn #1#2#3#4#5
  {
    \dim_set:Nn \l__ltxtalk_current_slot_width_dim {#4}
    \dim_set:Nn \l__ltxtalk_current_slot_height_dim {#5}
    \dim_set:Nn \l__ltxtalk_current_slot_x_dim
      {
        \str_case:nnF {#2}
          {
            {left}{0pt}
            {center}{(\l__ltxtalk_current_area_width_dim-#4)/2}
            {right}{\l__ltxtalk_current_area_width_dim-#4}
          }{#2}
      }
    \dim_set:Nn \l__ltxtalk_current_slot_y_dim
      {
        \str_case:nnF {#3}
          {
            {top}{0pt}
            {center}{(\l__ltxtalk_current_area_height_dim-#5)/2}
            {bottom}{\l__ltxtalk_current_area_height_dim-#5}
          }{#3}
      }
    % \ldeen{Die \cs{parbox} unten schließt intern immer mit einem
    %   impliziten \cs{par}. Für jede Rolle außer \code{content} (dort ist
    %   der automatische Hook gewollt) muss tagpdfs automatischer
    %   Absatz-Tagging-Hook deshalb schon \emph{vor} dem
    %   \cs{hcoffin_set:Nn}-Aufruf abgeschaltet werden -- das gilt auch für
    %   Rollen mit echtem Strukturelement (\code{heading}, \code{note}
    %   etc.): \cs{__ltxtalk_accessibility_struct:nn} schaltet den Hook
    %   zwar bereits \emph{innerhalb} ihres eigenen Struct-Tags ab, aber
    %   erst, nachdem \cs{__ltxtalk_slot_content:n} von hier aus (über
    %   \cs{UseInstance}) aufgerufen wurde -- und damit \emph{innerhalb}
    %   der \cs{parbox}, in einer eigenen, dort bereits wieder
    %   geschlossenen Gruppe. Ein dort lokal gesetztes \cs{tagpdfparaOff}
    %   ist also für das implizite \cs{par} der umschließenden
    %   \cs{parbox} schon wieder aufgehoben (ausprobiert und bestätigt:
    %   ein Rollen-Filter, der nur \code{navigation}/\code{artifact} hier
    %   abschaltete und \code{note}/\code{heading} dem inneren, zu spät
    %   greifenden Abschalten überließ, reichte \emph{nicht} -- erst das
    %   Abschalten für \emph{alle} Rollen außer \code{content} schon hier
    %   behob den Fehler). Kopf-/Rand-/Fußbereiche baut \cls{ltx-talk}
    %   erst beim Ausschiffen auf; ein dort vom automatischen Hook
    %   trotzdem erzeugtes Struct landet dann an einer zu diesem späten
    %   Zeitpunkt falschen/zufälligen Stelle im Baum -- beobachtet als
    %   \enquote{Parent-Child ... Relation is not allowed!} und, bei
    %   Inhalten, die sich von Folie zu Folie ändern, akkumulierend bis
    %   hin zu einem TeX-\enquote{capacity exceeded}-Abbruch. Kein
    %   umschließendes \cs{group_begin:}/\cs{group_end:}: \cs{hcoffin_set:Nn}
    %   setzt \cs{l__ltxtalk_slot_coffin} über \cs{hbox_set:Nn} -- also
    %   \emph{lokal} --, eine Gruppe hier würde den gesetzten Koffer-Inhalt
    %   vor dem folgenden \cs{coffin_join:NnnNnnnn} wieder verwerfen.
    %   \cs{tagpdfparaOff} wird deshalb ohne Gruppe gesetzt und danach
    %   explizit mit \cs{tagpdfparaOn} wieder aufgehoben -- dasselbe Muster
    %   wie \pkg{latex-lab}s \code{\textbackslash tagpdfparaOff\space
    %   \textbackslash par\space\textbackslash tagpdfparaOn} für denselben
    %   Zweck.}{The \cs{parbox} below always closes with an implicit
    %   \cs{par} internally. For every role except \code{content} (there
    %   the automatic hook is wanted), tagpdf's automatic per-paragraph
    %   tagging hook must therefore be switched off already \emph{before}
    %   the \cs{hcoffin_set:Nn} call -- this includes roles with a
    %   genuine structure element (\code{heading}, \code{note}, etc.):
    %   \cs{__ltxtalk_accessibility_struct:nn} does switch the hook off,
    %   but only \emph{inside} its own struct tag -- which only runs once
    %   \cs{__ltxtalk_slot_content:n} is called from here (via
    %   \cs{UseInstance}), i.e., \emph{inside} the \cs{parbox}, in its own
    %   group that has already closed again by then. A
    %   \cs{tagpdfparaOff} set locally in there is therefore already
    %   reverted again for the enclosing \cs{parbox}'s implicit \cs{par}
    %   (tried and confirmed: a role filter that switched off only
    %   \code{navigation}/\code{artifact} here, leaving \code{note}/
    %   \code{heading} to their inner, too-late switch-off, was \emph{not}
    %   enough -- only switching off for \emph{every} role except
    %   \code{content} already here fixed it). \cls{ltx-talk} only builds
    %   header/margin/footer areas at shipout; a struct the automatic hook
    %   still creates there ends up at a wrong/arbitrary point in the tree
    %   at that late moment -- observed as \enquote{Parent-Child ...
    %   Relation is not allowed!} and, for content that changes from frame
    %   to frame, accumulating all the way to a TeX \enquote{capacity
    %   exceeded} abort. No enclosing \cs{group_begin:}/\cs{group_end:}
    %   here: \cs{hcoffin_set:Nn} sets \cs{l__ltxtalk_slot_coffin} via
    %   \cs{hbox_set:Nn} -- i.e., \emph{locally} --, so a group here would
    %   discard the coffin content just set before the following
    %   \cs{coffin_join:NnnNnnnn} can use it. \cs{tagpdfparaOff} is
    %   therefore set without a group and explicitly reverted afterward
    %   with \cs{tagpdfparaOn} -- the same pattern \pkg{latex-lab} uses
    %   (\code{\textbackslash tagpdfparaOff\space\textbackslash par\space
    %   \textbackslash tagpdfparaOn}) for the same purpose.}
    \bool_if:NT \g__talk_frame_tag_bool
      {
        \__ltxtalk_slot_role:n {#1}
        \str_if_eq:VnF \l__ltxtalk_slot_role_tl { content }
          { \tagpdfparaOff }
      }
    \hcoffin_set:Nn \l__ltxtalk_slot_coffin
      {
        \parbox[c][#5][c]{#4}
          {\UseInstance {lttheme-slot}{#1}{\__ltxtalk_slot_content:n {#1}}}
      }
    \bool_if:NT \g__talk_frame_tag_bool { \tagpdfparaOn }
    \coffin_join:NnnNnnnn \l__ltxtalk_area_coffin {l}{t}
      \l__ltxtalk_slot_coffin {l}{t}
      {\l__ltxtalk_current_slot_x_dim}{-\l__ltxtalk_current_slot_y_dim}
  }

\cs_new_protected:Npn \__ltxtalk_render_area:nnn #1#2#3
  {
    \tl_set:Nn \l__ltxtalk_current_area_tl {#1}
    \dim_set:Nn \l__ltxtalk_current_area_width_dim {#2}
    \dim_set:Nn \l__ltxtalk_current_area_height_dim {#3}
    \vcoffin_set:Nnn \l__ltxtalk_area_coffin {#2}
      {\UseInstance {lttheme-area}{#1}{\rule{0pt}{#3}}}
    \seq_map_inline:cn {g__ltxtalk_#1_slots_seq}
      {\__ltxtalk_render_slot:n {##1}}
    \coffin_typeset:Nnnnn \l__ltxtalk_area_coffin {l}{t}{0pt}{0pt}
  }
% \ldeen{Zeigt ein Theme Titel oder Untertitel nicht im Textstrom (sondern
%   etwa nur in der Kopfzeile), wird der Text trotzdem hier -- und nur hier
%   -- getaggt, aber unsichtbar gesetzt: Textrendermodus 3 in einer Box ohne
%   Höhe, die die vertikale Liste nicht verändert (\cs{prevdepth} wird
%   wiederhergestellt). \cs{phantom} schiede aus, weil es keine Glyphen und
%   damit ein leeres Strukturelement erzeugt. Der Untertitel übernimmt das
%   Strukturelement aus der Rolle des (Kopf-)Slots seines Typs; hat dieser
%   keine Strukturrolle, entsteht auch kein Element. Leere Titel erzeugen
%   nichts, ebenso ein Titel, für den das Theme gar keinen Slot deklariert:
%   was nirgends sichtbar ist, wird auch nicht getaggt.}{If a theme does not show title or subtitle in the text stream
%   (but only in the header, say), the text is still tagged here -- and only
%   here --, but set invisibly: text rendering mode 3 in a box of zero
%   height that does not alter the vertical list (\cs{prevdepth} is
%   restored). \cs{phantom} is not an option, as it produces no glyphs and
%   hence an empty structure element. The subtitle takes its structure
%   element from the role of the (header) slot of its type; if that has no
%   structure role, no element is created either. Empty titles produce
%   nothing, and neither does a title for which the theme declares no slot
%   at all: what is visible nowhere is not tagged either.}
\bool_new:N \l__ltxtalk_content_slot_found_bool
\tl_new:N \l__ltxtalk_hidden_struct_keys_tl
\box_new:N \l__ltxtalk_hidden_struct_box
\cs_new_protected:Npn \__ltxtalk_hidden_struct:nn #1 #2
  {
    \mode_if_vertical:TF
      {
        \dim_set:Nn \l_tmpa_dim { \tex_prevdepth:D }
        \nointerlineskip
        \vbox_to_zero:n
          { \hbox:n { \__ltxtalk_hidden_struct_aux:nn {#1} {#2} } \tex_vss:D }
        \tex_prevdepth:D = \l_tmpa_dim
      }
      {
        \hbox_set:Nn \l__ltxtalk_hidden_struct_box
          { \__ltxtalk_hidden_struct_aux:nn {#1} {#2} }
        \box_set_ht:Nn \l__ltxtalk_hidden_struct_box { 0pt }
        \box_set_dp:Nn \l__ltxtalk_hidden_struct_box { 0pt }
        \hbox_overlap_right:n { \box_use_drop:N \l__ltxtalk_hidden_struct_box }
      }
  }
\cs_new_protected:Npn \__ltxtalk_hidden_struct_aux:nn #1 #2
  {
    \tag_struct_begin:e
      {
        parent = \int_use:N \g__talk_frame_struct_int ,
        #1
      }
    \tag_mc_begin:n { }
    \tex_pdfextension:D literal~page { 3~Tr }
    #2
    \tex_pdfextension:D literal~page { 0~Tr }
    \tag_mc_end:
    \tag_struct_end:
  }
\cs_new_protected:Npn \__ltxtalk_hidden_slot_keys:n #1
  {
    \tl_clear:N \l__ltxtalk_hidden_struct_keys_tl
    \prop_map_inline:Nn \g__ltxtalk_slot_types_prop
      {
        \str_if_eq:nnT {##2} {#1}
          {
            \prop_map_break:n
              {
                \group_begin:
                  \tl_set:Nn \l__ltxtalk_slot_role_tl { artifact }
                  \int_set:Nn \l__ltxtalk_heading_level_int { 1 }
                  \tl_clear:N \l__ltxtalk_alt_text_tl
                  \prop_get:NnNT \g__ltxtalk_slot_accessibility_prop {##1} \l_tmpa_tl
                    { \keys_set:nV { ltxtalk / a11y } \l_tmpa_tl }
                  \tl_set:Ne \l_tmpa_tl
                    {
                      \str_case:Vn \l__ltxtalk_slot_role_tl
                        {
                          { heading } { tag = \__ltxtalk_accessibility_heading_tag: }
                          { H1 }      { tag = H1 }
                          { H2 }      { tag = H2 }
                          { H3 }      { tag = H3 }
                          { note }    { tag = Note }
                        }
                    }
                \exp_args:NNNV \group_end:
                \tl_set:Nn \l__ltxtalk_hidden_struct_keys_tl \l_tmpa_tl
              }
          }
      }
  }
\cs_new_protected:Npn \__ltxtalk_if_slot_type_declared:nT #1 #2
  {
    \bool_set_false:N \l_tmpa_bool
    \prop_map_inline:Nn \g__ltxtalk_slot_types_prop
      {
        \str_if_eq:nnT {##2} {#1}
          { \prop_map_break:n { \bool_set_true:N \l_tmpa_bool } }
      }
    \bool_if:NT \l_tmpa_bool {#2}
  }
\cs_new_protected:Npn \__ltxtalk_hidden_frame_heading:n #1
  {
    \bool_if:NT \g__talk_frame_tag_bool
      {
        \str_case:nn {#1}
          {
            { frametitle }
              {
                \tl_if_empty:NF \g__talk_frame_title_tl
                  {
                    \__ltxtalk_if_slot_type_declared:nT { frametitle }
                      {
                        \__ltxtalk_hidden_struct:nn
                          { \__ltxtalk_frame_title_struct_keys: }
                          { \tl_use:N \g__talk_frame_title_tl }
                      }
                  }
              }
            { framesubtitle }
              {
                \tl_if_empty:NF \g__talk_frame_subtitle_tl
                  {
                    \__ltxtalk_hidden_slot_keys:n { framesubtitle }
                    \tl_if_empty:NF \l__ltxtalk_hidden_struct_keys_tl
                      {
                        \__ltxtalk_hidden_struct:nn
                          { \l__ltxtalk_hidden_struct_keys_tl }
                          { \tl_use:N \g__talk_frame_subtitle_tl }
                      }
                  }
              }
          }
      }
  }
% \ldeen{
%   Inhalts-Slots gehören zum Textstrom des Frames und nicht zum Seitenlayout.
%   Dieser schmale Adapter behält das Klassenkommando bei und fügt alle passenden 
%   Slots in der Reihenfolge ihrer Deklaration hinzu. Folglich kann ein Theme einen 
%   Titel im Hauptblock, in der Kopfzeile oder in beiden Bereichen platzieren, ohne 
%   dass die Themenengine das Theme kennt.
% }{
%   Content slots belong to the frame's text stream, not to the page layout.
%   This narrow adapter preserves the class command and adds all matching slots
%   in declaration order.  Consequently a theme may place a title in the main
%   block, in the header, or in both areas without the theme engine knowing the theme.
% }
\cs_new_protected:Npn \__ltxtalk_render_content_slots:n #1
  {
    \bool_set_false:N \l__ltxtalk_content_slot_found_bool
    \seq_map_inline:Nn \g__ltxtalk_content_slots_seq
      {
        \prop_get:NnNT \g__ltxtalk_slot_types_prop {##1} \l_tmpa_tl
          {
            \str_if_eq:VnT \l_tmpa_tl {#1}
              {
                \bool_set_true:N \l__ltxtalk_content_slot_found_bool
                \prop_get:NnNT \g__ltxtalk_slot_positions_prop {##1} \l_tmpb_tl
                  {
                    \exp_after:wN \__ltxtalk_render_content_slot_aux:w
                      \l_tmpb_tl \q_stop {##1}
                  }
              }
          }
      }
    \bool_if:NF \l__ltxtalk_content_slot_found_bool
      { \__ltxtalk_hidden_frame_heading:n {#1} }
  }
% \ldeen{Kein führendes \cs{par}\cs{noindent} vor dem Slot-Inhalt: Ein
%   vorangehender \cs{par} löste den automatischen Absatz-Tagging-Hook von
%   tagpdf für einen (leeren) Absatz aus; dieser Hook bliebe unausgeglichen
%   offen und tagpdf bräche den Lauf mit \emph{"the number of automatic
%   begin and end text-unit para hooks differ"} fatal ab. Für jede Rolle
%   außer \code{content} (und immer für den Slottyp \code{frametitle}) wird
%   der Absatz-Hook schon \emph{hier}, vor dem Aufbau des Slots, für die
%   ganze Slot-Gruppe abgeschaltet -- dieselbe Regel wie für Kopf-/Rand-/
%   Fußslots in \cs{__ltxtalk_render_slot:nnnnn}. Ein erst im Inneren (in
%   einer eigenen Gruppe) gesetztes \cs{tagpdfparaOff} wäre beim
%   schließenden \cs{par} der Slot-Box bereits wieder aufgehoben; deren
%   Absatzende schlösse dann zwei Strukturen, die nie geöffnet wurden, und
%   nähme \code{frame} und \code{Sect} vom Stapel (\enquote{there is no open
%   structure on the stack}). Steht der Aufruf mitten in einem Absatz (etwa
%   \cs{framesubtitle} nach Fließtext), wird dieser zuvor regulär beendet;
%   sonst landete der Slot in einem offenen Absatz, dessen Hooks danach
%   nicht mehr aufgehen. Das schließende \cs{par} nach dem Inhalt
%   bleibt nötig, damit der Slot sauber als eigener Absatz endet, bevor
%   nachfolgender Frame-Inhalt beginnt.}{
%   No leading \cs{par}\cs{noindent} before the slot content: a preceding
%   \cs{par} would fire tagpdf's automatic per-paragraph tagging hook for
%   an (empty) paragraph; that hook would stay unbalanced and tagpdf would
%   abort the run fatally with \emph{"the number of automatic begin and end
%   text-unit para hooks differ"}. For every role except \code{content}
%   (and always for the \code{frametitle} slot type) the paragraph hook is
%   switched off already \emph{here}, before the slot is built, for the
%   whole slot group -- the same rule as for header/margin/footer slots in
%   \cs{__ltxtalk_render_slot:nnnnn}. A \cs{tagpdfparaOff} set only inside
%   (in a group of its own) would already be reverted at the slot box's
%   closing \cs{par}; that paragraph end would then close two structures
%   that were never opened and take \code{frame} and \code{Sect} off the
%   stack (\enquote{there is no open structure on the stack}). If the call
%   sits in the middle of a paragraph (\cs{framesubtitle} after running
%   text, say), that paragraph is ended properly first; otherwise the slot
%   would land in an open paragraph whose hooks no longer balance. The trailing
%   \cs{par} after the content remains necessary so the slot cleanly ends
%   its own paragraph before subsequent frame content begins.}
\cs_new_protected:Npn \__ltxtalk_render_content_slot_aux:w
  #1#2#3#4 \q_stop #5
  {
    \mode_if_horizontal:T { \par }
    \group_begin:
      \bool_set_true:N \l__ltxtalk_slot_flow_bool
      \bool_if:NT \g__talk_frame_tag_bool
        {
          \__ltxtalk_slot_role:n {#5}
          \prop_get:NnN \g__ltxtalk_slot_types_prop {#5} \l__ltxtalk_slot_type_tl
          \bool_lazy_and:nnF
            { \str_if_eq_p:Vn \l__ltxtalk_slot_role_tl { content } }
            { ! \str_if_eq_p:Vn \l__ltxtalk_slot_type_tl { frametitle } }
            { \tagpdfparaOff }
        }
      \UseInstance {lttheme-slot}{#5}{\__ltxtalk_slot_content:n {#5}}
    \group_end:
    \par
  }
% \ldeen{Ist ein Abschnittstitel vorgemerkt, tritt er an die Stelle von
%   \cs{frametitle}s Text; ein gegebener Text wird stattdessen (sofort) als
%   Subtitel gesetzt und die aktuelle Foliennummer gemerkt, damit ein
%   \emph{eigener} nachfolgender \cs{framesubtitle}-Aufruf in derselben Folie
%   entfällt -- er träfe sonst auf einen bereits durch die Demotion belegten
%   Subtitel. Folgefolien desselben Abschnitts sind nicht betroffen, weil der
%   Merker mit dem Verbrauch gelöscht wird.}{If a section title is pending, it
%   takes the place of \cs{frametitle}'s text; any given text is instead set
%   (immediately) as the subtitle, and the current frame number is recorded so
%   an \emph{own} subsequent \cs{framesubtitle} call in the same frame is
%   dropped -- it would otherwise collide with the subtitle already occupied
%   by the demotion. Later frames in the same section are unaffected, since
%   the flag is cleared once consumed.}
% \ldeen{Die beiden Slot-Rendervorgänge (Titel, dann Subtitel) laufen bei
%   aktivem Tagging in einer gemeinsamen, lokalen \cs{tagpdfparaOff}-Hülle:
%   \cs{__ltxtalk_render_content_slot_aux:w} beendet jeden Slot mit einem
%   \cs{par} (nötig, damit der Slot als eigener Absatz endet) -- ohne diese
%   Hülle träfe dieses \cs{par} zwischen Titel- und Subtitel-Rendering auf
%   ein bereits wieder aktives \cs{tagpdfparaOff} nur \emph{innerhalb} des
%   ersten Aufrufs, feuerte also für einen (leeren) Zwischenabsatz erneut
%   tagpdfs automatischen Absatz-Tagging-Hook -- exakt dieselbe, oben bei
%   \cs{__ltxtalk_render_content_slots:n} dokumentierte Ursache für
%   \enquote{the number of automatic begin and end text-unit para hooks
%   differ}, hier nur durch das \emph{nachlaufende} statt vorangehende
%   \cs{par} ausgelöst. Mit echtem Text an derselben Folie riss das
%   in der Praxis bis zum \enquote{TeX capacity exceeded}.}{The two slot
%   renders (title, then subtitle) run inside one shared, local
%   \cs{tagpdfparaOff} wrapper when tagging is active:
%   \cs{__ltxtalk_render_content_slot_aux:w} ends every slot with a
%   \cs{par} (needed so the slot ends as its own paragraph) -- without this
%   wrapper, that \cs{par} between the title and subtitle render would hit
%   \cs{tagpdfparaOff} already reverted (it was only local \emph{inside}
%   the first call), firing tagpdf's automatic per-paragraph tagging hook
%   again for a (blank) in-between paragraph -- the exact same cause
%   documented above at \cs{__ltxtalk_render_content_slots:n} for
%   \enquote{the number of automatic begin and end text-unit para hooks
%   differ}, just triggered by the \emph{trailing} rather than a leading
%   \cs{par}. With real text given on the same frame this cascaded, in
%   practice, all the way to \enquote{TeX capacity exceeded}.}
% \ldeen{Gemeinsame Rendering-Logik für eine (numerierte) Überschrift
%   plus optionalem Subtitel, ausgelagert, damit sie identisch für drei
%   Aufrufer läuft: den ersten Verbrauch des
%   \enquote{vorgemerkt}-Schalters, jeden späteren Overlay-Schritt
%   derselben Folie (eine mehrseitige Folie soll ihre demotierte
%   Überschrift auf \emph{jeder} ihrer Seiten zeigen, nicht nur auf der
%   ersten -- siehe \cs{frametitle} unten) und \cs{contframetitle}
%   (weiter unten), das dieselbe Renderlogik mit einem zusätzlichen
%   Fortsetzungs-Suffix braucht. \cs{#1} ist die \cs{tl}-Variable mit dem
%   fertigen Titeltext, \cs{#2} der (ggf.\ leere) Subtiteltext.}{Shared
%   rendering logic for a (numbered) heading plus an optional subtitle,
%   factored out so it runs identically for three callers: the first
%   consumption of the "'pending"' flag, every later overlay step of the
%   same frame (a multi-page frame should show its demoted heading on
%   \emph{every} one of its pages, not just the first -- see
%   \cs{frametitle} below), and \cs{contframetitle} (further below),
%   which needs the same render logic with an added continuation
%   suffix. \cs{#1} is the \cs{tl} variable holding the finished title
%   text, \cs{#2} the (possibly empty) subtitle text.}
\cs_new_protected:Npn \__ltxtalk_apply_frame_heading:Nn #1#2
  {
    \tl_gset_eq:NN \g__talk_frame_title_tl #1
    \bool_if:NTF \g__talk_frame_tag_bool
      {
        \group_begin:
          \tagpdfparaOff
          \__ltxtalk_render_content_slots:n {frametitle}
          \tl_if_empty:nF {#2}
            {
              \int_gset:Nn \g__ltxtalk_auto_subtitle_frame_int
                { \g__talk_frame_int }
              \tl_gset:Nn \g__talk_frame_subtitle_tl {#2}
              \__ltxtalk_render_content_slots:n {framesubtitle}
            }
        \group_end:
      }
      {
        \__ltxtalk_render_content_slots:n {frametitle}
        \tl_if_empty:nF {#2}
          {
            \int_gset:Nn \g__ltxtalk_auto_subtitle_frame_int
              { \g__talk_frame_int }
            \tl_gset:Nn \g__talk_frame_subtitle_tl {#2}
            \__ltxtalk_render_content_slots:n {framesubtitle}
          }
      }
  }
\cs_new_protected:Npn \__ltxtalk_apply_auto_title:n #1
  { \__ltxtalk_apply_frame_heading:Nn \g__ltxtalk_pending_heading_title_tl {#1} }
\RenewDocumentCommand \frametitle { D <> { all } O {#3} m }
  {
    \__talk_if_overlay:nT {#1}
      {
        \bool_if:NTF \g__ltxtalk_pending_heading_title_bool
          {
            \bool_gset_false:N \g__ltxtalk_pending_heading_title_bool
            \int_gset:Nn \g__ltxtalk_auto_title_frame_int { \g__talk_frame_int }
            \__ltxtalk_apply_auto_title:n {#3}
          }
          {
            \int_compare:nNnTF
              { \g__ltxtalk_auto_title_frame_int } = { \g__talk_frame_int }
              { \__ltxtalk_apply_auto_title:n {#3} }
              {
                \tl_gset:Nn \g__talk_frame_title_tl {#3}
                \__ltxtalk_render_content_slots:n {frametitle}
              }
          }
      }
  }
% \ldeen{Manuelle Entsprechung zu \cs{frametitle} für
%   Fortsetzungsfolien: eine logische Überschrift, die sich über mehrere
%   \emph{separate} \cs{begin}\Arg{frame}-Blöcke erstreckt (nicht zu
%   verwechseln mit Overlays/\cs{pause} innerhalb \emph{einer} Folie, die
%   \cs{frametitle} bereits von selbst über alle Folienschritte hält).
%   Wiederholt die zuletzt von \cs{section}/\cs{subsection} gemerkte,
%   numerierte Überschrift (dieselbe Quelle wie die automatische
%   Demotion, aber bewusst \emph{unabhängig} von deren
%   \code{auto-section-title}-Schalter -- \cs{contframetitle} wird ja
%   gezielt vom Autor aufgerufen) mit angehängtem, sprachabhängigem
%   Fortsetzungs-Hinweis. Anders als \cs{frametitle} nimmt
%   \cs{contframetitle} \emph{kein} Pflichtargument (die Überschrift kommt
%   ja immer aus dem Merker) -- nur ein optionales
%   \cs{contframetitle}\oarg{Subtitel} in eckigen statt geschweiften
%   Klammern; ohne Argument bleibt der Subtitel leer.}{Manual counterpart
%   to \cs{frametitle} for continuation frames: one logical heading
%   spanning multiple \emph{separate} \cs{begin}\Arg{frame} blocks (not
%   to be confused with overlays/\cs{pause} within \emph{one} frame,
%   which \cs{frametitle} already keeps across all its steps on its
%   own). Repeats the numbered heading last recorded by
%   \cs{section}/\cs{subsection} (the same source as the automatic
%   demotion, but deliberately \emph{independent} of its
%   \code{auto-section-title} switch -- \cs{contframetitle} is, after
%   all, invoked deliberately by the author) with a language-dependent
%   continuation marker appended. Unlike \cs{frametitle},
%   \cs{contframetitle} takes \emph{no} mandatory argument (the heading
%   always comes from the recorded value) -- only an optional
%   \cs{contframetitle}\oarg{subtitle} in square rather than curly
%   brackets; without an argument the subtitle stays empty.}
\tl_new:N \l__ltxtalk_cont_title_tl
\NewDocumentCommand \contframetitle { D <> { all } O { } }
  {
    \__talk_if_overlay:nT {#1}
      {
        \tl_set_eq:NN \l__ltxtalk_cont_title_tl \g__ltxtalk_pending_heading_title_tl
        \tl_put_right:Nn \l__ltxtalk_cont_title_tl { \c_space_tl }
        \str_if_eq:eeTF {\languagename} {english}
          { \tl_put_right:Nn \l__ltxtalk_cont_title_tl { (cont.) } }
          { \tl_put_right:Nn \l__ltxtalk_cont_title_tl { (Forts.) } }
        \__ltxtalk_apply_frame_heading:Nn \l__ltxtalk_cont_title_tl {#2}
      }
  }
\RenewDocumentCommand \framesubtitle { D <> { all } O {#3} m }
  {
    \__talk_if_overlay:nT {#1}
      {
        \int_compare:nNnF
          { \g__ltxtalk_auto_subtitle_frame_int } = { \g__talk_frame_int }
          {
            \tl_gset:Nn \g__talk_frame_subtitle_tl {#3}
            \__ltxtalk_render_content_slots:n {framesubtitle}
          }
      }
  }

% \ldeen{
%   \cs{@oddhead} wird von der Ausgaberoutine an der Grundlinie des Seitenkopfs
%   gesetzt. Deren Abstand von der Papieroberkante ist
%   \cs{Gm@tmargin}~$-$~\cs{headsep} (der obere Rand abzüglich des Kopfabstands,
%   den \cls{ltx-talk} über \pkg{geometry} vergibt). Alle oben verankerten
%   Flächen -- Kopf, linke Spalte in \code{hawk}, die \code{sparrow}-Linien --
%   müssen daher um genau diesen Betrag angehoben werden, damit ihre Oberkante
%   auf der Papierkante liegt; ein Anheben um \cs{Gm@tmargin} allein schöbe sie
%   um \cs{headsep} zu weit nach oben. Rechte und linke Spalte ohne
%   \code{hawk}-Sonderfall beginnen statt an der Papierkante an der Unterkante
%   des Kopfbereichs, daher dort der zusätzliche Term \cs{headsep}.
% }{
%   \cs{@oddhead} is placed by the output routine at the baseline of the running
%   head. Its distance from the top paper edge is \cs{Gm@tmargin}~$-$~\cs{headsep}
%   (the top margin less the head separation that \cls{ltx-talk} assigns through
%   \pkg{geometry}). Every top-anchored area -- the header, the left column in
%   \code{hawk}, the \code{sparrow} rules -- must therefore be raised by exactly
%   that amount so its top edge sits on the paper edge; raising by \cs{Gm@tmargin}
%   alone would push it \cs{headsep} too high. The left and right columns outside
%   the \code{hawk} special case start at the bottom edge of the header area
%   rather than at the paper edge, hence the extra \cs{headsep} term there.
% }
\cs_new_nopar:Npn \ps@lttheme
  {
    \cs_set_nopar:Npn \@oddhead
      {
        \hbox_to_wd:nn {0pt}
          {
            \skip_horizontal:n {-\Gm@lmargin}
            \UseSocket{lttheme/page/background}
            \hss
          }
        \hbox_to_wd:nn {0pt}
          {
            \skip_horizontal:n {-\Gm@lmargin}
            \bool_if:NT \l__ltxtalk_show_left_margin_bool
              {
                \str_if_eq:VnTF \g__ltxtalk_active_theme_tl {hawk}
                  {
                    \raisebox{\dim_eval:n{\Gm@tmargin-\headsep}}[0pt][0pt]
                      {\UseSocket{lttheme/area/left}}
                  }
                  {
                    \bool_if:NTF \l__ltxtalk_show_header_bool
                      {
                        \raisebox
                          {-\dim_eval:n{\l__ltxtalk_header_height_dim-\Gm@tmargin+\headsep}}
                          [0pt][0pt]{\UseSocket{lttheme/area/left}}
                      }
                      {
                        \raisebox{\dim_eval:n{\Gm@tmargin-\headsep}}[0pt][0pt]
                          {\UseSocket{lttheme/area/left}}
                      }
                  }
              }
            \hss
          }
        \hbox_to_wd:nn {0pt}
          {
            \bool_if:NT \l__ltxtalk_show_right_margin_bool
              {
                \skip_horizontal:n
                  {
                    \dim_eval:n
                      {-\Gm@lmargin+\paperwidth-\l__ltxtalk_right_area_width_dim}
                  }
                \str_if_eq:VnTF \g__ltxtalk_active_theme_tl {goose}
                  {
                    \raisebox{\dim_eval:n{\Gm@tmargin-\headsep}}[0pt][0pt]
                      {\UseSocket{lttheme/area/right}}
                  }
                  {
                    \bool_if:NTF \l__ltxtalk_show_header_bool
                      {
                        \raisebox
                          {-\dim_eval:n{\l__ltxtalk_header_height_dim-\Gm@tmargin+\headsep}}
                          [0pt][0pt]
                          {\UseSocket{lttheme/area/right}}
                      }
                      {
                        \raisebox{\dim_eval:n{\Gm@tmargin-\headsep}}[0pt][0pt]
                          {\UseSocket{lttheme/area/right}}
                      }
                  }
              }
            \hss
          }
        \hbox_to_wd:nn {0pt}
          {
            \bool_if:NT \l__ltxtalk_show_header_bool
              {
                \str_if_eq:VnTF \g__ltxtalk_active_theme_tl {magpie}
                  {
                    \int_compare:nNnF {\@framenumber} = {1}
                      {
                        \skip_horizontal:n {-\Gm@lmargin}
                        \raisebox{\dim_eval:n{\Gm@tmargin-\headsep}}[0pt][0pt]
                          {\UseSocket{lttheme/area/header}}
                      }
                  }
                  {
                    \skip_horizontal:n {-\Gm@lmargin}
                    \raisebox{\dim_eval:n{\Gm@tmargin-\headsep}}[0pt][0pt]
                      {\UseSocket{lttheme/area/header}}
                  }
              }
            \hss
          }
        \hbox_to_wd:nn {0pt}
          {
            \skip_horizontal:n {-\Gm@lmargin}
            \UseSocket{lttheme/page/foreground}
            \hss
          }
        \hfil
      }
    \cs_set_nopar:Npn \@oddfoot
      {
        \hbox_to_wd:nn {0pt}
          {
            \bool_if:NT \l__ltxtalk_show_footer_bool
              {
                \skip_horizontal:n {-\Gm@lmargin}
                \raisebox
                  {
                    \dim_eval:n
                      {
                        \l__ltxtalk_footer_height_dim
                        -\Gm@bmargin+\footskip
                      }
                  }
                  [0pt][0pt]
                  {\UseSocket{lttheme/area/footer}}
              }
            \hss
          }
        \hfil
      }
    \cs_set_eq:NN \@evenhead \@oddhead
    \cs_set_eq:NN \@evenfoot \@oddfoot
  }

\cs_set_protected:Npn \__ltxtalk_apply_class_templates:
  {
    \__ltxtalk_update_text_area:
    \pagestyle{lttheme}
  }
\AddToHook { begindocument / end }
  {
    \str_if_eq:VnF \g__ltxtalk_active_theme_tl {default}
      {\__ltxtalk_update_text_area:}
  }

%</pkg>
%<*minimal>
% \subsection{Minimal theme}
\NeedsTeXFormat{LaTeX2e}
\ProvidesExplPackage{ltxtalk-theme-minimal}
{2026-10-05}
{v0.5.3}
{Minimal theme for ltx-talk}

\RequirePackage{ltxtalk-theme}

\cs_new_protected:Npn \__ltxtalk_minimal_theme_setup:
  {
    % === LAYOUT ===
    \ltxtalksetup{
      header = true,
      header-height = 1.2cm,
      footer = true,
      footer-height = 0.6cm,
    }
    
    % === TITEL-PLATZIERUNG ===
    \setltxtalktitleplacement{
      frametitle = content,
      section = none,
    }
    
    % === SLOTS ===
    \defineltxtalkslot{min-title}{header}{title}{
      role = note
    }
    \defineltxtalkslot{min-section}{header}{section}{
      role = note
    }
    \defineltxtalkslot{min-page}{header}{pagenumber}{
      role = navigation
    }
    \defineltxtalkslot{min-ftitle}{content}{frametitle}{
      role = heading, heading-level = 2
    }
    \defineltxtalkslot{min-fsubtitle}{content}{framesubtitle}{
      role = heading, heading-level = 3
    }
    \defineltxtalkslot{min-author}{footer}{author}{
      role = note
    }
    \defineltxtalkslot{min-footer-page}{footer}{pagenumber}{
      role = navigation
    }
    
    % === POSITIONIERUNG ===
    \positionltxtalkslot{min-title}{0.18cm}{0.3cm}{0.4\paperwidth}{0.6cm}
    \positionltxtalkslot{min-section}{center}{0.3cm}{0.3\paperwidth}{0.6cm}
    \positionltxtalkslot{min-page}{right}{0.3cm}{0.1\paperwidth}{0.6cm}
    \positionltxtalkslot{min-ftitle}{left}{1cm}{0.9\paperwidth}{2cm}
    \positionltxtalkslot{min-fsubtitle}{left}{3cm}{0.9\paperwidth}{1cm}
    \positionltxtalkslot{min-author}{0.18cm}{bottom}{0.4\paperwidth}{0.4cm}
    \positionltxtalkslot{min-footer-page}
      {\dim_eval:n{0.9\paperwidth-0.18cm}}{bottom}{0.1\paperwidth}{0.4cm}
    
    % === FORMATIERUNG ===
    \styleltxtalkslot{min-title}{
      font = \small,
      color = ltxtalk-secondary,
      align = left,
    }
    \styleltxtalkslot{min-section}{
      font = \small,
      color = ltxtalk-secondary!70,
    }
    \styleltxtalkslot{min-page}{
      font = \tiny,
      color = ltxtalk-secondary!50,
      align = right,
    }
    \styleltxtalkslot{min-ftitle}{
      font-slot = display,
      font = \LARGE\bfseries,
      color = ltxtalk-primary,
      align = left,
    }
    \styleltxtalkslot{min-fsubtitle}{
      font = \large\itshape,
      color = ltxtalk-secondary,
      align = left,
    }
    \styleltxtalkslot{min-author}{
      font = \tiny\itshape,
      color = ltxtalk-secondary!60,
      align = left,
    }
    \styleltxtalkslot{min-footer-page}{
      font = \tiny,
      color = ltxtalk-secondary!50,
      align = right,
    }
    
    % === BEREICHSDEKORATIONEN ===
    \decorateltxtalkarea{header}{
      frame = bottom,
      rule-color = ltxtalk-primary,
      rule-thickness = 1pt,
      margin-bottom = 10pt,
      artifact-type = layout,
    }
    \decorateltxtalkarea{footer}{
      frame = top,
      rule-color = ltxtalk-primary!30,
      rule-thickness = 0.4pt,
      margin-top = 5pt,
      artifact-type = decorative,
    }
    
    % === FARBEN ===
    \setltxtalkcolors{
      primary    = {model=HTML, value=333333},
      secondary  = {model=HTML, value=666666},
      accent     = {model=HTML, value=999999},
      text       = {model=HTML, value=222222},
      background = {model=HTML, value=FFFFFF},
      structure  = {model=HTML, value=2B3A67},
      alert      = {model=HTML, value=B00020},
      example    = {model=HTML, value=166534},
    }
  }

\RegisterLTXTalkTheme{minimal}{\__ltxtalk_minimal_theme_setup:}

%</minimal>
%<*magpie>
% \subsection{Magpie theme (inspired by Beamer Madrid)}
\NeedsTeXFormat{LaTeX2e}
\ProvidesExplPackage{ltxtalk-theme-magpie}
{2026-10-05}
{v0.5.3}
{Magpie theme for ltx-talk, inspired by Beamer Madrid}
\RequirePackage{ltxtalk-theme}
% Madrid blocks have rounded corners; \pkg{pgfcore} draws them (and the
% optional drop shadow).  Only this theme pulls it in.
\RequirePackage{pgfcore}
% \ldeen{Ladeoption \option{shadow}: legt einen weichen Schlagschatten
%   unter die Blöcke.}{Load option \option{shadow}: puts a soft drop shadow
%   under the blocks.}
\bool_new:N \g__ltxtalk_magpie_shadow_bool
\DeclareKeys [ ltxtalk-theme-magpie ]
  {
    shadow .bool_gset:N = \g__ltxtalk_magpie_shadow_bool,
    shadow .initial:n = false,
  }
\ProcessKeyOptions [ ltxtalk-theme-magpie ]
\cs_new_protected:Npn \__ltxtalk_magpie_theme_setup:
  {
    \ltxtalksetup{header=true,header-height=1.35cm,footer=true,footer-height=0.48cm}
    \setltxtalktitleplacement{frametitle=header,section=none}
    \defineltxtalkslot{magpie-frametitle}{header}{frametitle}
      {role=heading,heading-level=2}
    \defineltxtalkslot{magpie-framesubtitle}{header}{framesubtitle}
      {role=heading,heading-level=3}
    \defineltxtalkslot{magpie-author}{footer}{custom}{role=note}
    \defineltxtalkslot{magpie-title}{footer}{custom}{role=note}
    \defineltxtalkslot{magpie-page}{footer}{custom}{role=navigation}
    \setltxtalkslotcontent{magpie-author}{\@shortauthor\ (\@shortinstitute)}
    \setltxtalkslotcontent{magpie-title}{\@shorttitle}
    \setltxtalkslotcontent{magpie-page}{\@shortdate\quad\@framenumber}
    % Title and subtitle occupy adjacent, non-overlapping bands with a little
    % slack top and bottom, so their glyphs never collide.
    \positionltxtalkslot{magpie-frametitle}{0.22cm}{0.16cm}
      {\dim_eval:n{\paperwidth-0.44cm}}{0.60cm}
    \positionltxtalkslot{magpie-framesubtitle}{0.22cm}{0.82cm}
      {\dim_eval:n{\paperwidth-0.44cm}}{0.40cm}
    \positionltxtalkslot{magpie-author}{0.28cm}{center}{0.44\paperwidth}{0.48cm}
    \positionltxtalkslot{magpie-title}{0.46\paperwidth}{center}{0.30\paperwidth}{0.48cm}
    \positionltxtalkslot{magpie-page}
      {\dim_eval:n{0.78\paperwidth}}{center}{\dim_eval:n{0.22\paperwidth-0.28cm}}{0.48cm}
    \styleltxtalkslot{magpie-frametitle}{font-slot=display,font=\Large\bfseries,color=white,
      align=left,padding=3pt}
    \styleltxtalkslot{magpie-framesubtitle}
      {font=\small,color=white,align=left}
    \styleltxtalkslot{magpie-author}{font=\tiny,color=white,align=left}
    \styleltxtalkslot{magpie-title}{font=\tiny,color=white,align=center}
    \styleltxtalkslot{magpie-page}{font=\tiny,color=white,align=right}
    \decorateltxtalkarea{header}{background=ltxtalk-primary,artifact-type=layout}
    % Madrid-style three-part footer.  The cell shades are all tints of
    % ltxtalk-primary, so a colour-only overlay (anchovy, carp) that repaints
    % primary carries the whole footer with it and no cell drifts off-colour.
    \decorateltxtalkarea{footer}
      {
        background = ltxtalk-primary!52!black,
        background-split =
          { ltxtalk-primary!52!black *23, ltxtalk-primary!74!black *15,
            ltxtalk-primary *11 },
        artifact-type = layout,
      }
    \AssignSocketPlug { lttheme/page/background } { magpie-title }
    \AssignSocketPlug { lttheme/page/foreground } { magpie-title }
    \__ltxtalk_titlepage_defaults:n {vertical-alignment=top}
    \EditInstance {titlepage-element}{title}
      {color=white,font=\Large,before-skip=1.35cm,after-skip=0.1em}
    \EditInstance {titlepage-element}{subtitle}
      {color=white,font=\small,before-skip=0pt,after-skip=0.8em}
    \EditInstance {titlepage-element}{author}
      {color=ltxtalk-text,before-skip=0.8em,after-skip=0.7em}
    \EditInstance {titlepage-element}{institute}
      {color=ltxtalk-text,font=\scriptsize,after-skip=0.7em}
    \EditInstance {titlepage-element}{date}{color=ltxtalk-text}
    \setltxtalkcolors{primary={model=rgb,value={0.2,0.2,0.7}},
      secondary={model=rgb,value={0.15,0.15,0.525}},
      accent={model=rgb,value={0.2,0.2,0.7}},
      text={model=HTML,value=000000},background={model=HTML,value=FFFFFF},
      structure={model=HTML,value=2B3A67},alert={model=HTML,value=B00020},example={model=HTML,value=166534}}
    % Madrid signature: a rounded coloured title bar over a tinted body box,
    % with an optional drop shadow (load option "shadow").
    \__ltxtalk_theme_block:nnn {titlebar}
      {head-background=primary,body-background=primary!10}{block}
    \__ltxtalk_theme_block:nnn {titlebar}
      {head-background=alert,body-background=alert!10}{alertblock}
    \__ltxtalk_theme_block:nnn {titlebar}
      {head-background=example,body-background=example!10}{exampleblock}
    \clist_map_inline:nn { block, alertblock, exampleblock }
      {
        \styleltxtalkblock {##1} { corner-radius = 3pt }
        \bool_if:NT \g__ltxtalk_magpie_shadow_bool
          { \styleltxtalkblock {##1}
              { shadow = true, shadow-color = structure!35 } }
      }
  }
\RegisterLTXTalkTheme{magpie}{\__ltxtalk_magpie_theme_setup:}
%</magpie>
%<*hawk>
% \subsection{Hawk theme (inspired by Beamer Hannover)}
\NeedsTeXFormat{LaTeX2e}
\ProvidesExplPackage{ltxtalk-theme-hawk}
{2026-10-05}
{v0.5.3}
{Hawk theme for ltx-talk, inspired by Beamer Hannover}
\RequirePackage{ltxtalk-theme}
\cs_new_protected:Npn \__ltxtalk_hawk_theme_setup:
  {
    \ltxtalksetup{header=true,header-height=1.25cm,left-margin=true,
      margin-width=1.6cm,footer=false}
    \setltxtalktitleplacement{frametitle=header,section=none}
    \defineltxtalkslot{hawk-title}{left}{custom}{role=note}
    \defineltxtalkslot{hawk-author}{left}{custom}{role=note}
    \defineltxtalkslot{hawk-section}{left}{section}{role=navigation}
    \defineltxtalkslot{hawk-subsection}{left}{subsection}{role=navigation}
    \defineltxtalkslot{hawk-frametitle}{header}{frametitle}{role=heading,heading-level=2}
    \defineltxtalkslot{hawk-framesubtitle}{header}{framesubtitle}{role=heading,heading-level=3}
    \setltxtalkslotcontent{hawk-title}{\@shorttitle}
    \setltxtalkslotcontent{hawk-author}{\@shortauthor}
    \positionltxtalkslot{hawk-title}{center}{0.25cm}{1.45cm}{0.55cm}
    \positionltxtalkslot{hawk-author}{center}{0.9cm}{1.45cm}{0.5cm}
    \positionltxtalkslot{hawk-section}{0.12cm}{1.8cm}{1.36cm}{0.7cm}
    \positionltxtalkslot{hawk-subsection}{0.12cm}{2.65cm}{1.36cm}{0.7cm}
    % Non-overlapping title/subtitle bands with slack, so glyphs never collide.
    \positionltxtalkslot{hawk-frametitle}
      {\dim_eval:n{0.58\paperwidth-2cm}}{0.10cm}{0.42\paperwidth}{0.60cm}
    \positionltxtalkslot{hawk-framesubtitle}
      {\dim_eval:n{0.58\paperwidth-2cm}}{0.76cm}{0.42\paperwidth}{0.40cm}
    \styleltxtalkslot{hawk-title}{font-slot=display,font=\fontsize{5}{6}\selectfont,
      color=ltxtalk-text,align=center}
    \styleltxtalkslot{hawk-author}{font=\tiny,color=ltxtalk-secondary,align=center}
    % Hannover uses \tiny for sections on an even narrower default sidebar;
    % keep that proportion and set subsections one step quieter still.
    \styleltxtalkslot{hawk-section}
      {font-slot=accent,font=\tiny\bfseries,color=ltxtalk-primary,align=left}
    \styleltxtalkslot{hawk-subsection}
      {font=\fontsize{5}{6}\selectfont,color=ltxtalk-secondary,align=left}
    \styleltxtalkslot{hawk-frametitle}{font-slot=display,font=\Large,color=ltxtalk-primary,align=right}
    \styleltxtalkslot{hawk-framesubtitle}{font=\small,color=ltxtalk-secondary,align=right}
    \decorateltxtalkarea{left}{background=ltxtalk-primary!20,artifact-type=layout}
    \AssignSocketPlug { lttheme/area/left } { hawk }
    \__ltxtalk_titlepage_defaults:n {vertical-alignment=center}
    \EditInstance {titlepage-element}{title}
      {color=ltxtalk-primary,font=\Large,after-skip=0.15em}
    \EditInstance {titlepage-element}{subtitle}
      {color=ltxtalk-primary,font=\small,before-skip=0pt,after-skip=0.9em}
    \EditInstance {titlepage-element}{author}{color=ltxtalk-text,before-skip=0.8em}
    \EditInstance {titlepage-element}{institute}{color=ltxtalk-text,font=\scriptsize}
    \EditInstance {titlepage-element}{date}{color=ltxtalk-text}
    \setltxtalkcolors{primary={model=rgb,value={0.2,0.2,0.7}},
      secondary={model=rgb,value={0.15,0.15,0.525}},
      accent={model=rgb,value={0.2,0.2,0.7}},
      text={model=HTML,value=000000},background={model=HTML,value=FFFFFF},
      structure={model=HTML,value=2B3A67},alert={model=HTML,value=B00020},example={model=HTML,value=166534}}
    % Hannover uses beamer's plain default block: a coloured heading, the
    % body flush below it, no bar or fill.
    \__ltxtalk_theme_block:nnn {heading}{head-color=primary}{block}
    \__ltxtalk_theme_block:nnn {heading}
      {head-color=alert,head-rule-color=alert,foot-rule-color=alert!45}{alertblock}
    \__ltxtalk_theme_block:nnn {heading}
      {head-color=example,head-rule-color=example,foot-rule-color=example!45}{exampleblock}
  }
\RegisterLTXTalkTheme{hawk}{\__ltxtalk_hawk_theme_setup:}
%</hawk>
%<hawk>\endinput

% \subsection{Sparrow theme (inspired by Beamer Szeged)}
%<*sparrow>
\NeedsTeXFormat{LaTeX2e}
\ProvidesExplPackage{ltxtalk-theme-sparrow}
{2026-10-05}
{v0.5.3}
{Sparrow theme for ltx-talk, inspired by Beamer Szeged}
\RequirePackage{ltxtalk-theme}
\cs_new_protected:Npn \__ltxtalk_sparrow_theme_setup:
  {
    \ltxtalksetup{header=true,header-height=1.35cm,footer=true,footer-height=0.42cm}
    \setltxtalktitleplacement{frametitle=content,section=header}
    \defineltxtalkslot{sparrow-section}{header}{section}{role=navigation}
    \defineltxtalkslot{sparrow-subsection}{header}{subsection}{role=navigation}
    \defineltxtalkslot{sparrow-frametitle}{header}{frametitle}{role=heading,heading-level=2}
    \defineltxtalkslot{sparrow-framesubtitle}{header}{framesubtitle}{role=heading,heading-level=3}
    \defineltxtalkslot{sparrow-institute}{footer}{institute}{role=note}
    \defineltxtalkslot{sparrow-title}{footer}{title}{role=note}
    \defineltxtalkslot{sparrow-page}{footer}{pagenumber}{role=navigation}
    \positionltxtalkslot{sparrow-section}{0.18cm}{0.02cm}{0.44\paperwidth}{0.3cm}
    \positionltxtalkslot{sparrow-subsection}
      {\dim_eval:n{0.56\paperwidth-0.18cm}}{0.02cm}{0.44\paperwidth}{0.3cm}
    % Non-overlapping title/subtitle bands with slack, so glyphs never collide.
    \positionltxtalkslot{sparrow-frametitle}{0.25cm}{1.34cm}
      {\dim_eval:n{\paperwidth-0.5cm}}{0.56cm}
    \positionltxtalkslot{sparrow-framesubtitle}{0.25cm}{1.96cm}
      {\dim_eval:n{\paperwidth-0.5cm}}{0.34cm}
    \positionltxtalkslot{sparrow-institute}{0.18cm}{center}{0.3\paperwidth}{0.45cm}
    \positionltxtalkslot{sparrow-title}{center}{center}{0.4\paperwidth}{0.45cm}
    \positionltxtalkslot{sparrow-page}
      {\dim_eval:n{0.88\paperwidth-0.18cm}}{center}{0.12\paperwidth}{0.45cm}
    \styleltxtalkslot{sparrow-section}{font-slot=accent,font=\scriptsize\bfseries,color=ltxtalk-primary,align=left}
    \styleltxtalkslot{sparrow-subsection}{font=\scriptsize,color=ltxtalk-secondary,align=right}
    \styleltxtalkslot{sparrow-frametitle}
      {font-slot=display,font=\Large,color=ltxtalk-primary,align=left}
    \styleltxtalkslot{sparrow-framesubtitle}
      {font=\small,color=ltxtalk-secondary,align=left}
    \styleltxtalkslot{sparrow-institute}{font=\tiny,color=ltxtalk-secondary,align=left}
    \styleltxtalkslot{sparrow-title}{font=\tiny,color=ltxtalk-primary,align=center}
    \styleltxtalkslot{sparrow-page}{font=\tiny,color=ltxtalk-secondary,align=right}
    \decorateltxtalkarea{header}{background=white,artifact-type=layout}
    \decorateltxtalkarea{footer}{frame=top,rule-color=ltxtalk-primary!50,
      rule-thickness=1pt,background=ltxtalk-primary!5,artifact-type=layout}
    \AssignSocketPlug { lttheme/page/foreground } { sparrow-bars }
    \__ltxtalk_titlepage_defaults:n {vertical-alignment=center}
    \EditInstance {titlepage-element}{title}
      {color=ltxtalk-primary,font=\Large,after-skip=0.15em}
    \EditInstance {titlepage-element}{subtitle}
      {color=ltxtalk-primary,font=\small,before-skip=0pt,after-skip=0.9em}
    \EditInstance {titlepage-element}{author}{color=ltxtalk-text,before-skip=0.8em}
    \EditInstance {titlepage-element}{institute}{color=ltxtalk-text,font=\scriptsize}
    \EditInstance {titlepage-element}{date}{color=ltxtalk-text}
    \setltxtalkcolors{primary={model=rgb,value={0.2,0.2,0.7}},
      secondary={model=rgb,value={0.15,0.15,0.525}},
      accent={model=rgb,value={0.2,0.2,0.7}},
      text={model=HTML,value=000000},background={model=HTML,value=FFFFFF},
      structure={model=HTML,value=2B3A67},alert={model=HTML,value=B00020},example={model=HTML,value=166534}}
    % Szeged uses beamer's plain default block: a coloured heading only.
    \__ltxtalk_theme_block:nnn {heading}{head-color=primary}{block}
    \__ltxtalk_theme_block:nnn {heading}
      {head-color=alert,head-rule-color=alert,foot-rule-color=alert!45}{alertblock}
    \__ltxtalk_theme_block:nnn {heading}
      {head-color=example,head-rule-color=example,foot-rule-color=example!45}{exampleblock}
  }
\RegisterLTXTalkTheme{sparrow}{\__ltxtalk_sparrow_theme_setup:}
%</sparrow>
%<*bluebird>
% \subsection{Bluebird theme (inspired by Beamer Berlin)}
% \ldeen{Zeigt die Navigations-Renderer: \code{section-list} und
%   \code{section-dots} im Kopf, \code{section-progress} als Fortschritt.
%   Zusätzlich ein alternatives Titel-Layout (\code{bluebird/band}) und ein
%   Layout ohne Kopf/Fuß (\code{bluebird/plain}) für Betonungs- oder
%   Zitatfolien.}{Shows the navigation renderers: \code{section-list} and
%   \code{section-dots} in the header, \code{section-progress} as a progress
%   readout. Also an alternative title layout (\code{bluebird/band}) and a
%   chrome-free layout (\code{bluebird/plain}) for emphasis or quotation
%   frames.}
\NeedsTeXFormat{LaTeX2e}
\ProvidesExplPackage{ltxtalk-theme-bluebird}
{2026-10-05}
{v0.5.3}
{Bluebird theme for ltx-talk, inspired by Beamer Berlin}
\RequirePackage{ltxtalk-theme}

% \ldeen{Inhalt des \code{bluebird/band}-Titel-Frames -- als eigene Funktion,
%   da \cs{DeclareLTXTalkTitleLayout} ein kurzes Argument nimmt.}{Content of
%   the \code{bluebird/band} title frame -- a function of its own, since
%   \cs{DeclareLTXTalkTitleLayout} takes a short argument.}
\cs_new_protected:Npn \__ltxtalk_bluebird_title_band:
  {
    \centering \sffamily
    \null \vfill
    { \color{ltxtalk-primary} \rule{\linewidth}{2pt} } \par \medskip
    { \LARGE \bfseries \color{ltxtalk-primary} \LTXTalkMetadata{title} \par }
    \tl_if_blank:eF { \LTXTalkMetadata{subtitle} }
      { \medskip { \large \color{ltxtalk-secondary} \LTXTalkMetadata{subtitle} \par } }
    \medskip { \color{ltxtalk-primary} \rule{\linewidth}{2pt} } \par
    \bigskip
    { \large \LTXTalkMetadata{author} \par } \smallskip
    { \LTXTalkMetadata{institute} \par } \smallskip
    { \LTXTalkMetadata{date} \par }
    \vfill
  }

\cs_new_protected:Npn \__ltxtalk_bluebird_theme_setup:
  {
    \ltxtalksetup{header=true,header-height=1.65cm,footer=true,footer-height=0.7cm}
    \setltxtalktitleplacement{frametitle=header,section=none}

    % \ldeen{Berlin-Kopf: ein helles Navigationsband über einem satten Band
    %   mit dem Folientitel. Die Bänder sind \code{background-fill}-Slots, die
    %   vor den Textslots deklariert sind und daher hinter ihnen liegen.}{
    %   Berlin header: a light navigation band above a solid band carrying the
    %   frame title. The bands are \code{background-fill} slots declared before
    %   the text slots, so they sit behind them.}
    \defineltxtalkslot{bluebird-navband}{header}{custom}{role=artifact}
    \setltxtalkslotcontent{bluebird-navband}{}
    \positionltxtalkslot{bluebird-navband}{0cm}{0cm}{\paperwidth}{0.72cm}
    \styleltxtalkslot{bluebird-navband}
      {background=ltxtalk-primary!13,background-fill=true}
    \defineltxtalkslot{bluebird-titleband}{header}{custom}{role=artifact}
    \setltxtalkslotcontent{bluebird-titleband}{}
    \positionltxtalkslot{bluebird-titleband}{0cm}{0.72cm}{\paperwidth}{0.93cm}
    \styleltxtalkslot{bluebird-titleband}
      {background=ltxtalk-primary,background-fill=true}

    % --- header: section navigation on the light band ---
    \defineltxtalkslot{bluebird-seclist}{header}{custom}{role=navigation}
    \setltxtalkslotcontent{bluebird-seclist}{\LTXTalkNavigation{section-list}}
    \positionltxtalkslot{bluebird-seclist}{center}{0.1cm}{0.7\paperwidth}{0.5cm}
    \styleltxtalkslot{bluebird-seclist}{font=\footnotesize,align=center}
    \defineltxtalkslot{bluebird-dots}{header}{custom}{role=navigation}
    \setltxtalkslotcontent{bluebird-dots}{\LTXTalkNavigation{section-dots}}
    \positionltxtalkslot{bluebird-dots}{0.3cm}{0.18cm}{0.14\paperwidth}{0.4cm}
    \styleltxtalkslot{bluebird-dots}
      {font=\normalsize,align=left,color=ltxtalk-primary!55}
    \defineltxtalkslot{bluebird-progress}{header}{custom}{role=navigation}
    \setltxtalkslotcontent{bluebird-progress}{\LTXTalkNavigation{section-progress}}
    \positionltxtalkslot{bluebird-progress}
      {\dim_eval:n{0.83\paperwidth}}{0.2cm}{0.14\paperwidth}{0.4cm}
    \styleltxtalkslot{bluebird-progress}
      {font=\scriptsize,align=right,color=ltxtalk-primary!55}

    % --- frame title / subtitle on the solid band ---
    \defineltxtalkslot{bluebird-ftitle}{header}{frametitle}{role=heading,heading-level=2}
    \defineltxtalkslot{bluebird-fsub}{header}{framesubtitle}{role=heading,heading-level=3}
    \positionltxtalkslot{bluebird-ftitle}{0.3cm}{0.82cm}{0.75\paperwidth}{0.55cm}
    % Keep a small optical inset below descenders instead of letting the
    % subtitle slot end almost flush with the 1.65 cm header.
    \positionltxtalkslot{bluebird-fsub}{0.3cm}{1.28cm}{0.75\paperwidth}{0.3cm}
    \styleltxtalkslot{bluebird-ftitle}
      {font-slot=display,font=\Large\bfseries,color=white,align=left}
    \styleltxtalkslot{bluebird-fsub}
      {font=\footnotesize,color=ltxtalk-primary!20,align=left}

    % --- footer: two coloured lines (Berlin infolines) ---
    \defineltxtalkslot{bluebird-footline1}{footer}{custom}{role=artifact}
    \setltxtalkslotcontent{bluebird-footline1}{}
    \positionltxtalkslot{bluebird-footline1}{0cm}{0cm}{\paperwidth}{0.36cm}
    \styleltxtalkslot{bluebird-footline1}
      {background=ltxtalk-primary!62!black,background-fill=true}
    \defineltxtalkslot{bluebird-footline2}{footer}{custom}{role=artifact}
    \setltxtalkslotcontent{bluebird-footline2}{}
    \positionltxtalkslot{bluebird-footline2}{0cm}{0.36cm}{\paperwidth}{0.34cm}
    \styleltxtalkslot{bluebird-footline2}
      {background=ltxtalk-primary,background-fill=true}

    \defineltxtalkslot{bluebird-fauthor}{footer}{custom}{role=note}
    \setltxtalkslotcontent{bluebird-fauthor}
      {\LTXTalkMetadata{short-author}}
    \positionltxtalkslot{bluebird-fauthor}{0.3cm}{0cm}{0.6\paperwidth}{0.36cm}
    \styleltxtalkslot{bluebird-fauthor}{font=\tiny,color=white,align=left}
    \defineltxtalkslot{bluebird-finst}{footer}{custom}{role=note}
    \setltxtalkslotcontent{bluebird-finst}{\LTXTalkMetadata{short-institute}}
    \positionltxtalkslot{bluebird-finst}
      {\dim_eval:n{0.55\paperwidth}}{0cm}{\dim_eval:n{0.45\paperwidth-0.3cm}}{0.36cm}
    \styleltxtalkslot{bluebird-finst}{font=\tiny,color=white,align=right}
    \defineltxtalkslot{bluebird-ftitle-foot}{footer}{custom}{role=note}
    \setltxtalkslotcontent{bluebird-ftitle-foot}{\LTXTalkMetadata{short-title}}
    \positionltxtalkslot{bluebird-ftitle-foot}{0.3cm}{0.36cm}{0.6\paperwidth}{0.34cm}
    \styleltxtalkslot{bluebird-ftitle-foot}{font=\tiny,color=white,align=left}
    \defineltxtalkslot{bluebird-fpage}{footer}{pagenumber}{role=navigation}
    \setltxtalkslotcontent{bluebird-fpage}
      {\LTXTalkNavigation{section-progress}}
    \positionltxtalkslot{bluebird-fpage}
      {\dim_eval:n{0.7\paperwidth}}{0.36cm}{\dim_eval:n{0.3\paperwidth-0.3cm}}{0.34cm}
    \styleltxtalkslot{bluebird-fpage}{font=\tiny,color=white,align=right}

    % --- areas ---
    \decorateltxtalkarea{header}{artifact-type=layout}
    \decorateltxtalkarea{footer}{artifact-type=layout}

    % --- native title page ---
    \__ltxtalk_titlepage_defaults:n {vertical-alignment=center}
    \EditInstance{titlepage-element}{title}
      {color=ltxtalk-primary,font=\LARGE\bfseries,after-skip=0.15em}
    \EditInstance{titlepage-element}{subtitle}
      {color=ltxtalk-secondary,font=\large,before-skip=0pt,after-skip=0.9em}
    \EditInstance{titlepage-element}{author}{color=ltxtalk-text,before-skip=0.8em}
    \EditInstance{titlepage-element}{institute}{color=ltxtalk-text,font=\scriptsize}
    \EditInstance{titlepage-element}{date}{color=ltxtalk-text}

    % --- alternative title layout: a banded centred title ---
    \DeclareLTXTalkTitleLayout{bluebird/band}
      {header=false,footer=false}
      {\__ltxtalk_bluebird_title_band:}

    % --- chrome-free layout for emphasis / quotation frames ---
    \DeclareLTXTalkLayout{bluebird/plain}
      {header=false,footer=false}

    \setltxtalkcolors{primary={model=HTML,value=1F5C8A},
      secondary={model=HTML,value=5A7A8C},accent={model=HTML,value=E08D3C},
      text={model=HTML,value=1A2733},background={model=HTML,value=FFFFFF},
      structure={model=HTML,value=1F5C8A},alert={model=HTML,value=B00020},
      example={model=HTML,value=166534}}
    % Berlin: a coloured title bar over a tinted body, square corners.
    \__ltxtalk_theme_block:nnn {titlebar}
      {head-background=structure,body-background=structure!12}{block}
    \__ltxtalk_theme_block:nnn {titlebar}
      {head-background=alert,body-background=alert!10}{alertblock}
    \__ltxtalk_theme_block:nnn {titlebar}
      {head-background=example,body-background=example!10}{exampleblock}
  }
\RegisterLTXTalkTheme{bluebird}{\__ltxtalk_bluebird_theme_setup:}
%</bluebird>
%<bluebird>\endinput
%<*goose>
% \subsection{Goose theme (inspired by Beamer Goettingen)}
% \ldeen{Rechte Seitenleiste mit \code{toc}-Navigation (Abschnitte,
%   darunter die Unterabschnitte des aktuellen), im Kopf die
%   \code{subsection-list}; ohne Unterabschnitte erscheint dort ersatzweise
%   der aktuelle Abschnitt. Das Layout \code{goose/wide} blendet die
%   Seitenleiste für breite Abbildungen aus.}{Right sidebar with the
%   \code{toc} navigation (sections, with the current section's subsections
%   below it), \code{subsection-list} in the header (falling back to the
%   current section if it has no subsections). The \code{goose/wide} layout
%   drops the sidebar for wide figures.}
\NeedsTeXFormat{LaTeX2e}
\ProvidesExplPackage{ltxtalk-theme-goose}
{2026-10-05}
{v0.5.3}
{Goose theme for ltx-talk, inspired by Beamer Goettingen}
\RequirePackage{ltxtalk-theme}
\cs_new_protected:Npn \__ltxtalk_goose_header_navigation:
  {
    \LTXTalkNavigation{subsection-list}
    \int_compare:nNnT \g__ltxtalk_nav_map_int = { 0 }
      { \LTXTalkNavigation{current-section} }
  }
\cs_new_protected:Npn \__ltxtalk_goose_theme_setup:
  {
    \setltxtalktitleplacement{frametitle=content,section=none}

    % \ldeen{Göttingen-Muster: die rechte Spalte trägt alles und reicht über
    %   die volle Seitenhöhe (eigener Sockel-Plug \code{goose}). Oben Autor
    %   und Kurztitel, darunter das mitlaufende Inhaltsverzeichnis. Keine
    %   Fußzeile.}{Goettingen pattern: the right column carries everything and
    %   spans the full page height (its own \code{goose} socket plug). Author
    %   and short title at the top, the running table of contents below. No
    %   footer.}
    \AssignSocketPlug { lttheme/area/right } { goose }

    \defineltxtalkslot{goose-sidemeta}{right}{custom}{role=note}
    \setltxtalkslotcontent{goose-sidemeta}
      {
        {\color{ltxtalk-primary} \bfseries \LTXTalkMetadata{short-author}} \\ [0.2em]
        \LTXTalkMetadata{short-title}
      }
    \positionltxtalkslot{goose-sidemeta}{0.25cm}{0.55cm}{2.4cm}{1.5cm}
    \styleltxtalkslot{goose-sidemeta}
      {font=\scriptsize,color=ltxtalk-secondary,align=left}

    \defineltxtalkslot{goose-toc}{right}{custom}{role=navigation}
    \setltxtalkslotcontent{goose-toc}{\LTXTalkNavigation{toc}}
    \positionltxtalkslot{goose-toc}
      {0.25cm}{2.2cm}{2.4cm}{0.6\paperheight}
    \styleltxtalkslot{goose-toc}{font=\scriptsize,align=left}

    \defineltxtalkslot{goose-progress}{right}{custom}{role=navigation}
    \setltxtalkslotcontent{goose-progress}
      {\LTXTalkNavigation{section-progress}}
    \positionltxtalkslot{goose-progress}
      {0.25cm}{\dim_eval:n{\paperheight-1cm}}{2.4cm}{0.5cm}
    \styleltxtalkslot{goose-progress}
      {font=\scriptsize,color=ltxtalk-primary,align=left}

    % --- header: subsections of the current section ---
    \defineltxtalkslot{goose-subs}{header}{custom}{role=navigation}
    \setltxtalkslotcontent{goose-subs}{\__ltxtalk_goose_header_navigation:}
    \positionltxtalkslot{goose-subs}{0.3cm}{0.16cm}{0.86\paperwidth}{0.5cm}
    \styleltxtalkslot{goose-subs}
      {font=\scriptsize,align=left,color=ltxtalk-secondary}

    % --- content: frame title and subtitle (header slots -> absolute) ---
    \defineltxtalkslot{goose-ftitle}{header}{frametitle}{role=heading,heading-level=2}
    \defineltxtalkslot{goose-fsub}{header}{framesubtitle}{role=heading,heading-level=3}
    \positionltxtalkslot{goose-ftitle}{0.3cm}{0.85cm}{0.7\paperwidth}{0.75cm}
    \positionltxtalkslot{goose-fsub}{0.3cm}{1.55cm}{0.7\paperwidth}{0.45cm}
    \styleltxtalkslot{goose-ftitle}
      {font-slot=display,font=\Large\bfseries,color=ltxtalk-primary,align=left}
    \styleltxtalkslot{goose-fsub}
      {font=\normalsize\itshape,color=ltxtalk-secondary,align=left}

    % --- areas ---
    \decorateltxtalkarea{right}{
      background-gradient={ltxtalk-primary!22,ltxtalk-primary!2},frame=left,
      rule-color=ltxtalk-primary!40,rule-thickness=0.6pt,artifact-type=layout}
    \decorateltxtalkarea{header}{frame=bottom,rule-color=ltxtalk-primary!30,
      rule-thickness=0.4pt,artifact-type=decorative}

    % --- layouts: sidebar (standard) vs. full width (wide) ---
    \DeclareLTXTalkLayout{goose/standard}
      {header=true,header-height=0.72cm,footer=false,
       right-margin=true,right-area-width=2.7cm,content-inset-right=3.0cm}
    \DeclareLTXTalkLayout{goose/wide}
      {header=true,header-height=0.72cm,footer=false,
       right-margin=false,content-inset-right=0pt}

    % --- native title page ---
    \__ltxtalk_titlepage_defaults:n {vertical-alignment=center}
    \EditInstance{titlepage-element}{title}
      {color=ltxtalk-primary,font=\LARGE\bfseries,after-skip=0.15em}
    \EditInstance{titlepage-element}{subtitle}
      {color=ltxtalk-secondary,font=\large,before-skip=0pt,after-skip=0.9em}
    \EditInstance{titlepage-element}{author}{color=ltxtalk-text,before-skip=0.8em}
    \EditInstance{titlepage-element}{institute}{color=ltxtalk-text,font=\scriptsize}
    \EditInstance{titlepage-element}{date}{color=ltxtalk-text}

    \setltxtalkcolors{primary={model=HTML,value=4A6B2E},
      secondary={model=HTML,value=6E7F5C},accent={model=HTML,value=A8621B},
      text={model=HTML,value=20281A},background={model=HTML,value=FFFFFF},
      structure={model=HTML,value=4A6B2E},alert={model=HTML,value=B00020},
      example={model=HTML,value=166534}}
    % Goettingen keeps blocks plain: a coloured heading only, no bar or fill.
    \__ltxtalk_theme_block:nnn {heading}{head-color=structure}{block}
    \__ltxtalk_theme_block:nnn {heading}
      {head-color=alert,head-rule-color=alert,foot-rule-color=alert!45}{alertblock}
    \__ltxtalk_theme_block:nnn {heading}
      {head-color=example,head-rule-color=example,foot-rule-color=example!45}{exampleblock}

    \UseLTXTalkLayout{goose/standard}
  }
\RegisterLTXTalkTheme{goose}{\__ltxtalk_goose_theme_setup:}
%</goose>
%<goose>\endinput
%<*anchovy>
% \subsection{Anchovy colour theme (colours inspired by Beamer AnnArbor)}
\NeedsTeXFormat{LaTeX2e}
\ProvidesExplPackage{ltxtalk-theme-anchovy}
{2026-10-05}
{v0.5.3}
{Anchovy colour theme for ltx-talk, inspired by Beamer AnnArbor}
\RequirePackage{ltxtalk-theme}
% \ldeen{Blau-Gold nach dem Vorbild der University of Michigan: das Marineblau
%   trägt die Flächen (\code{primary}, \code{structure}), das Gold sitzt in den
%   Akzentslots. Layout-Themes, die \code{secondary} für Nebentext nutzen
%   (\code{minimal}, \code{sparrow}, \code{hawk}), zeigen das Gold sofort;
%   \code{magpie} färbt alle Flächen ausschließlich mit \code{primary} und
%   bleibt daher rein blau.}
%  {Blue and gold after the University of Michigan: the navy carries the filled
%   areas (\code{primary}, \code{structure}), the gold sits in the accent slots.
%   Layout themes that colour secondary text with \code{secondary}
%   (\code{minimal}, \code{sparrow}, \code{hawk}) surface the gold at once;
%   \code{magpie} fills every area from \code{primary} alone and therefore stays
%   all blue.}
\cs_new_protected:Npn \__ltxtalk_anchovy_theme_setup:
  {\setltxtalkcolors{primary={model=HTML,value=00274C},
    secondary={model=HTML,value=B8860B},
    accent={model=HTML,value=F2C230},text={model=HTML,value=111827},
    background={model=HTML,value=FFF7D6},
    structure={model=HTML,value=00274C},alert={model=HTML,value=B00020},
    example={model=HTML,value=166534}}}
\RegisterLTXTalkTheme{anchovy}{\__ltxtalk_anchovy_theme_setup:}
%</anchovy>
%<*carp>
% \subsection{Carp colour theme (colours inspired by Beamer CambridgeUS)}
\NeedsTeXFormat{LaTeX2e}
\ProvidesExplPackage{ltxtalk-theme-carp}
{2026-10-05}
{v0.5.3}
{Carp colour theme for ltx-talk, inspired by Beamer CambridgeUS}
\RequirePackage{ltxtalk-theme}
\cs_new_protected:Npn \__ltxtalk_carp_theme_setup:
  {\setltxtalkcolors{primary={model=rgb,value={0.8,0,0}},
    secondary={model=HTML,value=7F1D1D},
    accent={model=HTML,value=991B1B},text={model=HTML,value=111111},
    background={model=HTML,value=FFFFFF},
    structure={model=HTML,value=2B3A67},alert={model=HTML,value=B00020},
    example={model=HTML,value=166534}}}
\RegisterLTXTalkTheme{carp}{\__ltxtalk_carp_theme_setup:}
%</carp>
%<carp>\endinput
%<*font-sans>
\NeedsTeXFormat{LaTeX2e}
\ProvidesExplPackage{ltxtalk-theme-font-sans}
{2026-10-05}
{v0.5.3}
{Sans font theme for ltx-talk}
\RequirePackage{ltxtalk-theme}
\DeclareLTXTalkFontPalette { ltxtalk-font-sans }
  {
    main      = { font = { TeX Gyre Heros } },
    companion = { alias = main },
    display   = { alias = main },
    accent    = { alias = main },
    mono      = { font = { Latin Modern Mono } },
    symbol    = { alias = main }
  }
\cs_new_protected:Npn \__ltxtalk_font_sans_theme_setup:
  { \UseLTXTalkFontPalette { ltxtalk-font-sans } }
\RegisterLTXTalkTheme{font-sans}{\__ltxtalk_font_sans_theme_setup:}
%</font-sans>
%<font-sans>\endinput
%<*font-serif>
\NeedsTeXFormat{LaTeX2e}
\ProvidesExplPackage{ltxtalk-theme-font-serif}
{2026-10-05}
{v0.5.3}
{Serif font theme for ltx-talk}
\RequirePackage{ltxtalk-theme}
\DeclareLTXTalkFontPalette { ltxtalk-font-serif }
  {
    main      = { font = { TeX Gyre Pagella } },
    companion = { alias = main },
    display   = { alias = main },
    accent    = { alias = main },
    mono      = { font = { Latin Modern Mono } },
    symbol    = { alias = main }
  }
\cs_new_protected:Npn \__ltxtalk_font_serif_theme_setup:
  { \UseLTXTalkFontPalette { ltxtalk-font-serif } }
\RegisterLTXTalkTheme{font-serif}{\__ltxtalk_font_serif_theme_setup:}
%</font-serif>
%<font-serif>\endinput
%<*font-mixed>
\NeedsTeXFormat{LaTeX2e}
\ProvidesExplPackage{ltxtalk-theme-font-mixed}
{2026-10-05}
{v0.5.3}
{Mixed serif and sans font theme for ltx-talk}
\RequirePackage{ltxtalk-theme}
\DeclareLTXTalkFontPalette { ltxtalk-font-mixed }
  {
    main      = { font = { TeX Gyre Pagella } },
    companion = { font = { TeX Gyre Heros } },
    display   = { alias = companion },
    accent    = { alias = main },
    mono      = { font = { Latin Modern Mono } },
    symbol    = { alias = main }
  }
\cs_new_protected:Npn \__ltxtalk_font_mixed_theme_setup:
  { \UseLTXTalkFontPalette { ltxtalk-font-mixed } }
\RegisterLTXTalkTheme{font-mixed}{\__ltxtalk_font_mixed_theme_setup:}
%</font-mixed>
%<font-mixed>\endinput
%<*font-libertinus>
\NeedsTeXFormat{LaTeX2e}
\ProvidesExplPackage{ltxtalk-theme-font-libertinus}
{2026-10-05}
{v0.5.3}
{Libertinus font-family theme for ltx-talk}
\RequirePackage{ltxtalk-theme}
\DeclareLTXTalkFontPalette { ltxtalk-font-libertinus }
  {
    main      = { font = { Libertinus Serif } },
    companion = { font = { Libertinus Sans } },
    display   = { alias = companion },
    accent    = { alias = main },
    mono      = { font = { Libertinus Mono } },
    math      = { font = { Libertinus Math } },
    symbol    = { alias = main }
  }
\cs_new_protected:Npn \__ltxtalk_font_libertinus_theme_setup:
  { \UseLTXTalkFontPalette { ltxtalk-font-libertinus } }
\RegisterLTXTalkTheme{font-libertinus}{\__ltxtalk_font_libertinus_theme_setup:}
%</font-libertinus>
%<font-libertinus>\endinput
%<*font-newcm>
\NeedsTeXFormat{LaTeX2e}
\ProvidesExplPackage{ltxtalk-theme-font-newcm}
{2026-10-05}
{v0.5.3}
{New Computer Modern font-family theme for ltx-talk}
\RequirePackage{ltxtalk-theme}
\DeclareLTXTalkFontPalette { ltxtalk-font-newcm }
  {
    main      = { font = { NewComputerModern Serif } },
    companion = { font = { NewComputerModern Sans } },
    display   = { alias = companion },
    accent    = { alias = main },
    mono      = { font = { NewComputerModern Mono } },
    math      = { font = { NewComputerModern Math } },
    symbol    = { alias = main }
  }
\cs_new_protected:Npn \__ltxtalk_font_newcm_theme_setup:
  { \UseLTXTalkFontPalette { ltxtalk-font-newcm } }
\RegisterLTXTalkTheme{font-newcm}{\__ltxtalk_font_newcm_theme_setup:}
%</font-newcm>
%<font-newcm>\endinput
%<*font-texgyre>
\NeedsTeXFormat{LaTeX2e}
\ProvidesExplPackage{ltxtalk-theme-font-texgyre}
{2026-10-05}
{v0.5.3}
{TeX Gyre font-family theme for ltx-talk}
\RequirePackage{ltxtalk-theme}
\DeclareLTXTalkFontPalette { ltxtalk-font-texgyre }
  {
    main      = { font = { TeX Gyre Pagella } },
    companion = { font = { TeX Gyre Heros } },
    display   = { alias = companion },
    accent    = { alias = main },
    mono      = { font = { TeX Gyre Cursor } },
    math      = { font = { TeX Gyre Pagella Math } },
    symbol    = { alias = main }
  }
\cs_new_protected:Npn \__ltxtalk_font_texgyre_theme_setup:
  { \UseLTXTalkFontPalette { ltxtalk-font-texgyre } }
\RegisterLTXTalkTheme{font-texgyre}{\__ltxtalk_font_texgyre_theme_setup:}
%</font-texgyre>
%<font-texgyre>\endinput
