/* TypeTheme
   The chrome (controls / labels / pills) inherits the Lay Theme frontend
   typography and renders in black in light mode. Only the specimen shows the
   tested webfont — and it is driven entirely through CSS variables applied with
   !important + high specificity, so the theme's text-format typography (applied
   to content inside .lay-textformat-parent) cannot override the uploaded font.
   The controls + features live in a fixed footer bar (.typetheme-menu). */

.typetheme {
	--tt-ink: #000;
	--tt-line: rgba(0, 0, 0, 0.25);
	--tt-bg: transparent;
	/* Farbe von Slider-Linie und -Knopf. Bewusst eine EIGENE Variable: sie wird
	   beim Invertieren (und beim dunklen Hintergrund) nicht umgestellt, die
	   Regler bleiben also unverändert. */
	--tt-slider-ink: #000;
	--tt-menu-bg: transparent; /* footer background; editable in Settings */
	--tt-icon: 24px;           /* symbol size (SVG / uploaded icon / OT badge); editable in Settings */
	width: 100%;
	box-sizing: border-box;
	font-family: inherit; /* adopt the Lay Theme interface font */
	color: var(--tt-ink);
}

.typetheme *,
.typetheme *::before,
.typetheme *::after {
	box-sizing: border-box;
}

/* ---- specimen ---- */

.typetheme-stage {
	background: var(--tt-bg);
	padding: 40px; /* always padded; per-side overrides come from the Customizer */
	/* Die Bühne füllt das Fenster; die Leiste liegt darüber.
	   AUSSER BETRIEB (auf Wunsch entfernt, Stand 2026-08-05), aber aufgehoben:
	   die Variante, bei der die Bühne nur bis zur Oberkante der Leiste reicht —
	   dazu unten in typetheme.js MEASURE_STAGE_HEIGHT auf true setzen und hier
	   die folgende Zeile statt der darunter verwenden:
	   min-height: calc(100vh - var(--tt-menu-h, 0px)); */
	min-height: 100vh;
	display: flex;
	flex-direction: column;
	/* "safe" keeps the top from being clipped when the specimen is taller than
	   the viewport (plain "center" would push the top off-screen) */
	justify-content: safe center;
	transition: background 0.2s;
}

/* Solange die erste Zeile verankert ist (Regler/Tippen), richtet sich die Bühne
   oben aus — der Abstand kommt als margin-top am Specimen, damit die Bühne
   mitwächst statt den Text über ihren Rand hinauszuschieben. */
.typetheme.tt-anchored .typetheme-stage { justify-content: flex-start; }

.typetheme .typetheme-stage .typetheme-input {
	font-family: var(--tt-family), sans-serif !important;
	font-size: var(--tt-size, 80px) !important;
	line-height: var(--tt-lh, 1.1) !important;
	letter-spacing: var(--tt-ls, 0) !important;
	text-align: var(--tt-align, left) !important;
	font-feature-settings: var(--tt-feat, "liga" 1) !important;
	-webkit-font-feature-settings: var(--tt-feat, "liga" 1) !important;
	font-variation-settings: var(--tt-var, normal) !important;
	color: var(--tt-ink) !important;
	margin: 0 !important;
	padding: 0;
	min-height: 1em;
	outline: none;
	white-space: pre-wrap; /* keep manual line breaks (multi-line specimen text) */
	word-break: break-word;
	overflow-wrap: break-word;
}
.typetheme .typetheme-stage .typetheme-input:focus {
	outline: none;
}

/* Blinkender Cursor hinter dem letzten Zeichen, auch ohne Klick ins Feld
   (Einstellung "Standard" → "Cursor"). Beim Fokus übernimmt der echte Cursor. */
.typetheme.tt-blink .typetheme-input::after {
	content: '';
	display: inline-block;
	/* feste Strichstärke wie beim echten Cursor — nicht mitwachsend, sonst
	   springt die Breite beim Hineinklicken */
	width: 2px;
	height: 1em;
	vertical-align: -0.12em;
	margin-left: 1px;
	background: currentColor;
	animation: tt-blink 1.06s step-end infinite;
}
.typetheme.tt-blink .typetheme-input:focus::after { display: none; }
@keyframes tt-blink { 0%, 50% { opacity: 1; } 50.01%, 100% { opacity: 0; } }

/* ---- fixed footer toolbar (single row, two states) ---- */

.typetheme-menu {
	position: fixed;
	left: 0;
	right: 0; /* volle Fensterbreite; Seitenränder des Themes bleiben außen vor */
	bottom: 0;
	z-index: 9999;
	display: flex;
	flex-direction: row;
	align-items: center;
	/* NICHT umbrechen. "Eine Reihe" heisst eine Reihe — wird es eng, greift
	   zuerst .tt-crowded (Mindestbreiten frei, Beschriftungen gekuerzt). Erst
	   wenn selbst das nicht reicht, setzt die JS .tt-menu-wrap und der Umbruch
	   ist erlaubt (Regel weiter unten). Ein generelles flex-wrap hier hat die
	   crowded-Mechanik ausgehebelt: was umbricht, laeuft nicht ueber, also
	   meldete menuOverflow() nie etwas und die Leiste wurde zweizeilig,
	   obwohl sie einzeilig gepasst haette. */
	gap: var(--tt-gap, 2px);
	row-gap: var(--tt-row-gap, var(--tt-gap, 2px));
	padding: var(--tt-menu-pt, 10px) var(--tt-menu-pr, 14px) var(--tt-menu-pb, 10px) var(--tt-menu-pl, 14px);
	/* Die Leiste nimmt die Farbe der Bühne an, sobald der Besucher eine
	   Hintergrundfarbe wählt (--tt-bg-active setzt die JS); sonst gilt die
	   Farbe aus den Einstellungen (Karte "Bar"). */
	background: var(--tt-bg-active, var(--tt-menu-bg));
	/* Top divider is opt-in via the Footer setting (no border by default). */
	font-family: inherit;
	color: var(--tt-ink);
	box-sizing: border-box;
}

/* multiple testers on one page: hide the fixed footer of the tester that is not
   currently in view, so the toolbars don't overlap (JS toggles .tt-inactive
   on the root as the visitor scrolls). */
.typetheme.tt-inactive .typetheme-menu { display: none; }

/* three mutually-exclusive sections: Layout / Variable Fonts / OpenType.
   Opening one shows only its panel; the other two stay hidden. */
.typetheme-menu .tt-panel-layout,
.typetheme-menu .tt-panel-varfonts,
.typetheme-menu .tt-panel-opentype { display: none; }
.typetheme-menu.state-layout   .tt-panel-layout   { display: flex; }
.typetheme-menu.state-varfonts .tt-panel-varfonts { display: flex; }
.typetheme-menu.state-opentype .tt-panel-opentype { display: flex; }
/* the reset (↩) stays visible in every section */

/* the active middle panel grows to fill the space and NEVER scrolls — its
   items flex/shrink and their text truncates when space runs out */
.tt-state-panel {
	display: flex;
	align-items: center;
	gap: var(--tt-gap, 2px);
	flex: 1 1 auto;
	min-width: 0;
	overflow: hidden;
}

/* …except while a popover inside the panel is open: the panel's own clipping
   would cut off a pop-up that opens upward out of the bar */
.tt-state-panel.tt-sets-open { overflow: visible; }

/* Same for the bar itself: it computes to overflow:auto in the theme context,
   which clips every popover (cut list AND stylistic sets). The JS sets this
   class while a popover is open, so the bar only stops clipping then. */
/* `clip visible` statt `visible`: senkrecht darf weiterhin alles heraus (die
   Listen klappen nach oben aus der Leiste), waagerecht ist bei der Leistenkante
   Schluss. Das ist der letzte Riegel gegen einen Ueberlauf ueber den Viewport —
   er haelt auch dann, wenn eine Engine das Schrumpfen anders verteilt als die
   andere. `clip` ist dafuer der einzig taugliche Wert: `hidden` und `auto`
   zwingen die andere Achse auf `auto` und wuerden die Listen mit abschneiden. */
.typetheme .typetheme-menu.tt-popover-open { overflow: clip visible !important; }

.tt-varempty { font-size: 12px; opacity: 0.6; padding: 0 4px; }

/* ---- range sliders ----
   Die Linie IST das Input-Element: volle Breite, Farbe aus `background`.
   Damit deckt sich am Anschlag der Rahmen des Griffs exakt mit dem Rand der
   Linie — ein Range-Input laesst den Griff ohnehin nie darueber hinaus.
   (Eine Zwischenfassung zeichnete die Linie um eine Griffbreite kuerzer,
   damit die Griff-MITTE die Linienenden erreicht. Das ist zurueckgenommen:
   bündig war gewollt. Nebeneffekt der Rueckkehr zur normalen background-color:
   Radius und Rahmen der Linie wirken wieder, ein Hintergrundbild liess sich
   weder runden noch umranden.) */
.tt-slider {
	-webkit-appearance: none;
	appearance: none;
	width: 120px;
	height: 1px;
	background: var(--tt-slider-ink);
	outline: none;
	cursor: pointer;
}
/* ---- Firefox: Spur nur als Geometrie ----
   Firefox zentriert den Griff nicht auf dem Input, sondern auf
   `::-moz-range-track`. Ohne Angabe hat die Spur ihre eigene Standardhoehe —
   der Griff sitzt dann senkrecht anders als in Chrome, und sein Rahmen deckt
   sich nicht mit dem Rand der Linie.

   Die Spur bekommt deshalb die volle Hoehe des Inputs, bleibt aber
   TRANSPARENT: sie liefert nur die Bezugsgroesse, keine Farbe. Genau daran ist
   ein frueherer Versuch gescheitert — eingefaerbt lagen links vom Griff drei
   Ebenen uebereinander und die Linie wirkte bis dorthin dicker.
   `::-moz-range-progress` wird aus demselben Grund stillgelegt: Firefox faerbt
   den Bereich links vom Griff sonst mit der Systemfarbe.

   Eigene Regeln, NICHT in einer Liste mit den -webkit-Varianten: kennt ein
   Browser eines der Pseudoelemente nicht, verwirft er die ganze Regel. */
.tt-slider::-moz-range-track {
	height: 100%;
	border: 0;
	background: transparent;
}
.tt-slider::-moz-range-progress {
	height: 100%;
	border: 0;
	background: transparent;
}
/* handle: inactive = white circle with a 1px ring; active (drag/touch) = filled */
.tt-slider::-webkit-slider-thumb {
	-webkit-appearance: none;
	appearance: none;
	width: 14px;
	height: 14px;
	border-radius: 50%;
	background: #fff;
	border: 1px solid var(--tt-slider-ink);
	box-sizing: border-box;
	cursor: pointer;
	transition: background 0.1s;
}
.tt-slider::-moz-range-thumb {
	width: 14px;
	height: 14px;
	border-radius: 50%;
	background: #fff;
	border: 1px solid var(--tt-slider-ink);
	box-sizing: border-box;
	cursor: pointer;
}
/* only while actively pressed/dragged — releasing returns it to white */
.tt-slider:active::-webkit-slider-thumb { background: var(--tt-slider-ink); }
.tt-slider:active::-moz-range-thumb { background: var(--tt-slider-ink); }
/* ---- buttons (base look; overridable via Settings dynamic CSS) ---- */
.tt-btn {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	flex: 0 0 auto;
	/* Ein Symbol oder ein Zeichen passt in 40px; mehr Text macht den Button
	   breiter (die Breite wächst mit dem Inhalt). */
	min-width: 40px;
	font-family: inherit;
	font-size: 13px;
	line-height: 1;
	color: var(--tt-ink);
	background: transparent;
	border: 1px solid var(--tt-line);
	border-radius: 4px;
	box-sizing: border-box;
	min-height: 40px;      /* default control size (Settings padding can grow it) */
	min-width: 40px;       /* icon-only buttons render as a 40px square */
	padding: 0 10px;
	cursor: pointer;
	white-space: nowrap;
	transition: background 0.15s, border-color 0.15s, color 0.15s;
}
.tt-btn[hidden] { display: none; }
.tt-btn:hover { border-color: var(--tt-ink); }
.tt-btn.is-active {
	background: var(--tt-ink);
	color: #fff;
	border-color: var(--tt-ink);
}

/* state toggles share the exact button styling; the active one just uses
   .is-active like every other button (configurable in Settings). */

/* Zeichen-Symbole sind so groß wie ihr Zeichen: keine feste Kästchengröße mehr
   (früher 13x13), die Maße kommen aus Schriftgröße und Textformat.
   flex: 0 0 auto — der Flexbox-Kontext darf das Zeichen nicht schmaler ziehen. */
.tt-glyph {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	line-height: 1;
	flex: 0 0 auto;
	overflow: visible;
}
/* all inline SVG icons render in a --tt-icon box (default 24x24); the SVG's own
   preserveAspectRatio (xMidYMid meet) keeps them from distorting. */
.typetheme .tt-btn svg,
.typetheme .tt-glyph svg {
	width: var(--tt-icon, 24px);
	height: var(--tt-icon, 24px);
	display: block;
	flex: 0 0 auto;
}
/* uploaded icons are rendered as a CSS mask filled with currentColor, so they
   recolour with the button state (hover / active) exactly like the text/SVGs.
   `.tt-slider-icon` is the same mask in the symbol cell of a slider group — es
   teilt die Darstellung, aber NICHT die Zustaende (siehe unten). */
.tt-icon,
.tt-slider-icon {
	display: inline-block;
	flex: 0 0 auto;
	width: var(--tt-icon, 24px);
	height: var(--tt-icon, 24px);
	background-color: currentColor;
	-webkit-mask-repeat: no-repeat; mask-repeat: no-repeat;
	-webkit-mask-position: center; mask-position: center;
	-webkit-mask-size: contain; mask-size: contain;
}
.tt-fi-glyph { font-weight: 600; font-style: italic; }
.tt-caret { font-size: 11px; margin-left: 6px; }

/* Ausrichtung: ein beschrifteter Button wie die Schnitt-Auswahl, die drei
   Richtungen liegen in seinem Popover. */
.tt-align { flex: 0 1 auto; min-width: min-content; }
.tt-align-btn { gap: 7px; max-width: 100%; justify-content: flex-start; }
/* Beschriftung links, Symbol rechts — wie beim Schnitt-, Farb- und Sets-Button. */
.tt-align-label { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; min-width: 0; text-align: left; flex: 1 1 auto; }
.tt-align-list { min-width: 80px; }   /* wie die übrigen Popover (Einstellung: List) */
.tt-align-list .tt-popover-item { display: flex; align-items: center; justify-content: flex-start; width: 100%; }

/* "Nebeneinander": die Liste ist kein Popover mehr, sondern steht als Reihe
   rechts neben ihrem Button (der bleibt ganz links). Sie ist immer sichtbar,
   deshalb auch kein Auf-/Zuklappen und kein Fächer. */
.typetheme .tt-mi.tt-mode-inline {
	display: flex;
	flex-direction: row;
	align-items: center;
	gap: var(--tt-gap, 2px);
	flex: 0 1 auto;
	min-width: min-content;
}
.typetheme .tt-mi.tt-mode-inline > .tt-popover {
	position: static;
	flex-direction: row;
	width: auto !important;
	min-width: 0 !important;
	max-height: none;
	overflow: visible;
	padding: 0;
	margin: 0;
	background: none;
	border: 0;
	z-index: auto;
	animation: none;
	pointer-events: auto;
}
.typetheme .tt-mi.tt-mode-inline > .tt-popover:not(.tt-state-panel) > * {
	transform: none !important;
	width: auto !important;
	flex: 0 0 auto;
}
/* Ausgenommen sind die Panels der Zustandsschalter. Sie sind seit 1.6.0
   ebenfalls .tt-popover, verhalten sich in der Reihe aber wie eh und je als
   Sektion: ihre Inhalte TEILEN SICH die Breite der Leiste
   (`.tt-otbtn{flex:1 1 0}`, `.tt-slidergroup{flex:1 1 0}`). Mit der Regel
   darüber wären die OpenType-Buttons und die Reglergruppen auf ihre
   Inhaltsbreite geschrumpft. */
/* Gruppentitel der Schnitt-Liste ergeben in einer Reihe keinen Sinn. */
.typetheme .tt-mi.tt-mode-inline > .tt-popover > .tt-popover-group { display: none; }
/* Der Button selbst entfällt: die Einträge stehen ja schon alle in der Leiste,
   es gibt nichts mehr aufzuklappen. */
.typetheme .tt-mi.tt-mode-inline > .tt-btn { display: none !important; }

/* ---- Waagerechte Richtung: die Karten liegen UNTER dem Button und klappen von
   links nach rechts auf. Die Liste steht dabei IM Fluss der Leiste, direkt hinter
   ihrem Button und im Ruhezustand 0px breit — beim Aufklappen wächst ihre Breite
   und schiebt die Buttons rechts davon weg. ---- */
/* Zugeklappt sitzt die Liste (Breite 0) direkt am Button — offen ist der Abstand
   zum ersten Eintrag genauso groß wie der zwischen den Einträgen. */
.typetheme .tt-mi.tt-dir-left,
.typetheme .tt-mi.tt-dir-right {
	display: flex;
	flex-direction: row;
	align-items: center;
	gap: 0;
	transition: gap var(--tt-anim-dur, 140ms) var(--tt-anim-ease, ease);
}
.typetheme .tt-mi.tt-dir-left:has(> .tt-popover.is-open),
.typetheme .tt-mi.tt-dir-right:has(> .tt-popover.is-open) { gap: var(--tt-pop-gap, 2px); }
/* Der Button liegt IMMER über dem Stapel — die Karten schauen nur seitlich
   hervor und verdecken ihn nie. */
.typetheme .tt-mi.tt-dir-left > .tt-btn,
.typetheme .tt-mi.tt-dir-right > .tt-btn { position: relative; z-index: 20; }
.typetheme .tt-mi.tt-dir-left > .tt-popover,
.typetheme .tt-mi.tt-dir-right > .tt-popover {
	position: static;          /* im Fluss, direkt hinter dem Button */
	/* Die JS setzt die Breite (zu = Überstand, offen = volle Breite); der
	   Flexbox darf sie nicht wieder wegschrumpfen — Platz geben die anderen. */
	flex: 0 0 auto;
	flex-direction: row;
	align-items: center;
	/* Die Karten haengen an der Kante, die beim Aufklappen NICHT mitwaechst —
	   sonst wandert der ganze Stapel mit der Breite mit und die gestaffelten
	   Karten geben diese Kante kurz frei. Welche das ist, haengt an der
	   Richtung: nach links dehnt sich die Liste nach links, die rechte Kante
	   steht (flex-end); nach rechts ist es spiegelbildlich die linke
	   (flex-start, siehe die Regel gleich unten). */
	justify-content: flex-end;
	/* !important, weil die Mindestbreite "auto" den Listen width:100% !important
	   gibt; die Breite (zugeklappt = sichtbarer Überstand, offen = volle Breite)
	   setzt die JS inline, ebenfalls !important. */
	width: 0 !important;
	min-width: 0 !important;
	max-height: none;
	overflow: visible;
	padding: 0;
	margin: 0;
	background: none;
	z-index: auto;
	animation: none;
	transition: width var(--tt-anim-dur, 140ms) var(--tt-anim-ease, ease);
}
/* Spiegelbild fuer "klappt nach rechts auf". Ohne diese Regel liefen die
   Karten in die FALSCHE Richtung aus dem viel schmaleren Ruhe-Kasten heraus:
   bei zehn OpenType-Buttons (zusammen ~950px) in einem 60px-Kasten landete
   die erste Karte bei x = -603, alle zehn lagen ausserhalb des Fensters und
   vom Faecher war nichts zu sehen. */
.typetheme .tt-mi.tt-dir-right > .tt-popover { justify-content: flex-start; }

.typetheme .tt-mi.tt-dir-left > .tt-popover > *,
.typetheme .tt-mi.tt-dir-right > .tt-popover > * {
	flex: 0 0 auto;
	width: auto !important;
	transform: translateX(var(--tt-fan-dx, 0px));
	transition: transform var(--tt-anim-dur, 140ms) var(--tt-anim-ease, ease);
}
.typetheme .tt-mi.tt-dir-left > .tt-popover.tt-anim-fan > *,
.typetheme .tt-mi.tt-dir-right > .tt-popover.tt-anim-fan > * {
	transition-delay: calc(var(--tt-i, 0) * var(--tt-anim-stagger, 0ms));
}
.typetheme .tt-mi.tt-dir-left > .tt-popover.is-open > *,
.typetheme .tt-mi.tt-dir-right > .tt-popover.is-open > * { transform: none; }
.typetheme .tt-mi.tt-dir-left > .tt-popover.tt-fan-still > *,
.typetheme .tt-mi.tt-dir-right > .tt-popover.tt-fan-still > * { transition: none; }
/* Beim Messen MUSS auch die Verschiebung weg — sonst misst die JS die bereits
   verschobenen Karten und die Staffelung rechnet sich auf 0 herunter (der
   Fächer verschwand beim Wechsel der Sektion). */
.typetheme .tt-mi.tt-dir-left > .tt-popover.tt-fan-measure > *,
.typetheme .tt-mi.tt-dir-right > .tt-popover.tt-fan-measure > * {
	transition: none;
	transform: none !important;
}
.typetheme .tt-mi.tt-dir-left > .tt-popover.tt-fan-measure,
.typetheme .tt-mi.tt-dir-right > .tt-popover.tt-fan-measure { transition: none; }
/* Beim Aufklappen kann der Platz knapp werden: beschriftete Buttons dürfen
   schrumpfen (bis auf ihre 40px Mindestbreite, die Beschriftung kürzt sich).
   Bewusst NUR flex-shrink — ein vollständiges `flex` würde das Wachsen der
   OpenType-Buttons (`.tt-otbtn{flex:1 1 0}`) überschreiben und in der Leiste
   entstünde rechts eine Lücke. */
.typetheme .typetheme-menu .tt-mi { flex-shrink: 1; min-width: min-content; }
.typetheme .typetheme-menu .tt-btn { flex-shrink: 1; }

/* Reicht der Platz nicht mehr (die JS setzt dann .tt-crowded), geben auch die
   eingestellten Mindestbreiten der Beschriftungen nach: die Buttons schrumpfen
   bis auf ihre 40px, der Text kürzt sich mit Ellipse. So ragt die Leiste nie
   über den Bildschirmrand hinaus. */
/* Buttons schrumpfen nur bis 40px. Die fest in der Leiste stehenden Listen
   ("Nebeneinander") und ihre Einträge bleiben unangetastet — sie sollen immer
   vollständig sichtbar sein; den Platz gibt zuerst das mittlere Panel her. */
.typetheme .typetheme-menu.tt-crowded .tt-mi { min-width: 40px; }
.typetheme .typetheme-menu.tt-crowded .tt-mi.tt-mode-inline { min-width: min-content; flex-shrink: 0; }
/* Ein AUFGEKLAPPTER waagerechter Stapel behält ebenfalls seine Mindestbreite:
   die 40px oben ließen das .tt-mi unter die Breite seiner eigenen Liste
   schrumpfen — die hing dann aus ihm heraus und lag ÜBER den Nachbarn, statt
   sie wegzuschieben. Mit min-content schiebt sie wieder, und reicht der Platz
   trotzdem nicht, kürzt die JS beim Aufklappen gezielt ihre Breite (setPop).
   Nur im offenen Zustand: zugeklappt muss das .tt-mi weiter auf 40px schrumpfen
   dürfen, sonst stünde der Stapel im Gedränge neben seinem Button statt
   dahinter. */
.typetheme .typetheme-menu.tt-crowded .tt-mi.tt-dir-left:has(> .tt-popover.is-open),
.typetheme .typetheme-menu.tt-crowded .tt-mi.tt-dir-right:has(> .tt-popover.is-open) { min-width: min-content; }
/* Waagerecht aufklappende Liste: sie bleibt in ihrer Zone — was nicht
   hineinpasst, wird abgeschnitten statt über die Nachbarn gelegt.
   ABER: nach links darf der Stapel unter den Button laufen, sonst endet er hart
   an dessen Kante und in seinen runden Ecken scheint der Seitenhintergrund
   durch. Deshalb kein `overflow`, sondern ein Zuschnitt, der nach links um die
   Buttonbreite (`--tt-fan-bleed`, von der JS gesetzt) erweitert ist: die Karten
   füllen die Ecken von hinten aus, ragen aber nie über den Button hinaus. */
.typetheme .tt-mi.tt-dir-left > .tt-popover,
.typetheme .tt-mi.tt-dir-right > .tt-popover {
	overflow: visible;
	clip-path: inset(0 0 0 calc(-1 * var(--tt-fan-bleed, 40px)));
}

/* ---- Aufgeklappt: die Leiste geht IMMER vor ------------------------------
   Zugeklappt ist die Gruppe nie schmaler als ihr Inhalt (Button + hervor-
   schauender Stapel) — sonst laege der Button ueber dem Nachbarn. AUFGEKLAPPT
   darf genau das nicht mehr gelten: der Stapel ist dann breiter als die ganze
   Leiste, die Gruppe wuerde sich auf diese Breite versteifen und die Leiste
   liefe aus dem Bild. Also gibt der Stapel nach — die Gruppe haelt nur noch die
   Breite ihres Buttons (--tt-btn-w misst die JS), und der Stapel selbst darf
   schrumpfen; was nicht mehr hineinpasst, ist abgeschnitten.

   Das ist bewusst CSS und nicht (nur) die Kuerzung in setPop(): die Flexbox
   rechnet das in jeder Engine gleich aus, waehrend eine nachgemessene Kuerzung
   davon abhaengt, was der Browser im selben Frame schon im Layout stehen hat.
   Firefox lief hier ueber den Viewport, wo Chromium noch passte. */
.typetheme .typetheme-menu .tt-mi.tt-mi.tt-dir-left:has(> .tt-popover.is-open),
.typetheme .typetheme-menu .tt-mi.tt-mi.tt-dir-right:has(> .tt-popover.is-open) {
	/* Nie schmaler als der Button selbst — sonst laege er wieder ueber dem
	   Nachbarn. --tt-btn-w misst die JS am Button. */
	min-width: var(--tt-btn-w, 40px) !important;
	/* Die Gruppe gibt ZULETZT nach. Flexbox kennt keine Reihenfolge, wohl aber
	   Gewichte: verteilt wird nach Schrumpffaktor MAL Ausgangsbreite. Mit 1
	   schrumpfte ausgerechnet die aufgeklappte Gruppe zuerst (gemessen bei
	   1400px: Gruppe auf ihren 143px-Boden, waehrend das Reglerfeld daneben
	   noch 300px Luft hatte). Mit einem winzigen Faktor kommt sie erst an die
	   Reihe, wenn alle anderen auf ihrer Mindestbreite eingefroren sind. */
	flex-shrink: 0.001 !important;
	/* Und wenn auch das nicht reicht, wird abgeschnitten statt uebergelaufen.
	   `clip` ist hier das Entscheidende: es beschneidet NUR waagerecht und
	   laesst senkrecht `visible` zu — mit `hidden` waeren die nach oben
	   aufklappenden Listen mit abgeschnitten. Damit kann die Leiste den
	   Viewport gar nicht mehr verlassen, unabhaengig davon, wie die jeweilige
	   Engine das Schrumpfen verteilt. */
	overflow: clip visible;
}
/* Innerhalb der aufgeklappten Gruppe gibt der Stapel nach, nicht der Button:
   sonst verschwindet die Beschriftung ("Schriftschnitte"), waehrend daneben
   die Karten in voller Breite stehen. */
.typetheme .typetheme-menu .tt-mi.tt-dir-left:has(> .tt-popover.is-open) > .tt-btn,
.typetheme .typetheme-menu .tt-mi.tt-dir-right:has(> .tt-popover.is-open) > .tt-btn {
	flex-shrink: 0 !important;
}
.typetheme .typetheme-menu .tt-mi.tt-dir-left > .tt-popover.is-open,
.typetheme .typetheme-menu .tt-mi.tt-dir-right > .tt-popover.is-open {
	min-width: 0 !important;
	flex-shrink: 1 !important;
}

/* ---- "Klappt nach rechts auf": dasselbe Verhalten, seitenverkehrt. Der Stapel
   liegt auf der ANDEREN Seite des Buttons — die Liste steht im Fluss VOR ihm
   (order:-1), die Karten hängen an ihrer linken Kante und schauen im
   Ruhezustand nach links unter dem Button hervor. Steht bewusst hinter den
   gemeinsamen Regeln: gleiche Spezifität, also gewinnt die spätere. ---- */
.typetheme .tt-mi.tt-dir-right > .tt-popover {
	order: -1;
	justify-content: flex-start;
	/* Zuschnitt gespiegelt: nach RECHTS unter den Button erweitert. */
	clip-path: inset(0 calc(-1 * var(--tt-fan-bleed, 40px)) 0 0);
}
.typetheme .typetheme-menu.tt-crowded .tt-btn-label,
.typetheme .typetheme-menu.tt-crowded .tt-otlabel,
.typetheme .typetheme-menu.tt-crowded .tt-weight-label,
.typetheme .typetheme-menu.tt-crowded .tt-bgcolor-label,
.typetheme .typetheme-menu.tt-crowded .tt-align-label,
.typetheme .typetheme-menu.tt-crowded .tt-otsets-label { min-width: 0 !important; }
.typetheme .typetheme-menu.tt-crowded .tt-weight-btn,
.typetheme .typetheme-menu.tt-crowded .tt-bgcolor-btn,
.typetheme .typetheme-menu.tt-crowded .tt-align-btn,
.typetheme .typetheme-menu.tt-crowded .tt-otsets-btn { min-width: 40px !important; }

/* "Nur Icon": Beschriftung am Button UND in den Listeneinträgen ausblenden.
   (Die Schnitt-Liste behält ihre Namen — dort gibt es kein Symbol je Eintrag.) */
.tt-mode-icon .tt-btn-label,
.tt-mode-icon .tt-popover-item > .tt-otlabel,
.tt-mode-icon .tt-swatch-label { display: none !important; }

/* Die OpenType-FUNKTIONSBUTTONS als reine Zeichen — das gilt ausdrücklich NUR
   in der dreizeiligen Leiste. Am Desktop sitzt das OpenType-Panel ebenfalls in
   einem .tt-mi mit "Nur Icon" (das betrifft dort den Zustandsschalter), und
   ohne diese Einschränkung verlören die Funktionsbuttons dort ihre Namen. */
.typetheme .typetheme-menu.tt-bar-triple .tt-mi.tt-mode-icon .tt-otbtn > .tt-otlabel { display: none !important; }
/* Ohne Beschriftung soll ein OpenType-Button nicht mehr die Breite verteilen,
   sondern auf sein Zeichen zusammenschrumpfen — sonst stuenden vier riesige
   leere Flaechen nebeneinander. */
.typetheme .typetheme-menu.tt-bar-triple .tt-mi.tt-mode-icon .tt-otbtn {
	flex: 0 0 auto;
	/* Zeichen mittig — waagerecht wie senkrecht. Der seitliche Innenabstand aus
	   den Einstellungen (dort für beschriftete Buttons gedacht) passt nicht in
	   ein 40px-Feld: er drückte das Zeichen nach links und ließ den Rest
	   überlaufen. Ohne ihn hat das Zeichen die volle Breite zum Mittigsein.
	   Dasselbe tut das Stylesheet weiter oben schon für andere Symbol-Buttons. */
	justify-content: center;
	align-items: center;
	padding-left: 0 !important;
	padding-right: 0 !important;
	text-align: center;
}
/* Der Abstand zur Beschriftung (Einstellung „Abstand Beschriftung ↔ Symbol")
   kommt mit !important aus den Einstellungen. Ohne Beschriftung hat er nichts
   zu trennen und schob das Zeichen aus der Mitte — hier also weg. */
.typetheme .typetheme-menu.tt-bar-triple .tt-mi.tt-mode-icon .tt-otbtn > .tt-otnum { margin: 0 !important; }

/* Umgekehrt: die Eintraege der Schnitt-Liste tragen ihr Symbol IMMER im
   Markup, weil der Modus je Breakpoint wechseln kann und nachtraeglich kein
   Symbol mehr entstehen koennte. Zu sehen ist es nur mit "Nur Icon" — sonst
   staende neben jedem Schnittnamen noch sein Symbol. Andere Listen sind nicht
   betroffen: dort gehoert das Symbol (Ausrichtung, Farbe, OT-Zeichen) in
   beiden Modi zum Eintrag. */
.typetheme .tt-mi.tt-weight:not(.tt-mode-icon) .tt-popover-item > .tt-otnum { display: none; }
/* Ohne Beschriftung sitzt das Symbol mittig im Button — und der Button ist so
   schmal wie jeder andere Icon-Button (40px). Eine eingestellte Mindestbreite
   gilt nur für den beschrifteten Zustand, deshalb hier vier Klassen im
   Selektor, damit die Regel sie schlägt. */
.tt-mode-icon .tt-btn { justify-content: center; }
.typetheme .tt-mi.tt-mode-icon > .tt-btn { min-width: 40px !important; }
/* … und ein Eintrag ist dann quadratisch: genau so breit wie hoch (40px),
   egal ob er im Popover oder nebeneinander in der Leiste steht. Die vier
   Klassen im Selektor sind nötig, damit die Regel die Mindestbreiten-Regel
   aus den Einstellungen (0,3,0 + !important) schlägt. */
.typetheme .tt-mi.tt-mode-icon .tt-popover-item {
	width: 40px !important;
	min-width: 40px !important;
	padding-left: 0 !important;
	padding-right: 0 !important;
	/* display:flex, damit die Zentrierung überhaupt greift — ein Eintrag ohne
	   eigene display-Regel wäre ein Block und das Symbol klebte links. */
	display: flex !important;
	align-items: center;
	justify-content: center !important;
}
.typetheme .tt-mi.tt-mode-icon .tt-popover-item > .tt-otnum { margin-right: 0 !important; }
/* Farbfläche füllt den quadratischen Eintrag komplett aus. */
.typetheme .tt-mi.tt-mode-icon .tt-popover-item.tt-swatch > .tt-swatch-dot {
	flex: 1 1 auto;
	width: auto;
}

/* ---- weight / variable-fonts pop-overs (open upward) ---- */
.tt-mi { position: relative; flex: 0 0 auto; }
/* Symbol links, Beschriftung linksbündig daneben (wie bei den OpenType- und
   Sets-Buttons). Das Symbol ist je nach Einstellung ein Pfeil-Zeichen, ein
   Glyph oder ein hochgeladenes Icon — deshalb greift die Regel auf alles, was
   NICHT die Beschriftung ist. */
/* Beschriftung links, Symbol rechts: die Beschriftung nimmt den freien Platz,
   das Symbol sitzt dadurch am rechten Rand. Der Abstand dazwischen kommt
   AUSSCHLIESSLICH aus dem gap des Buttons (Einstellung "Abstand Beschriftung
   <-> Symbol"); Standard 7px wie bei den OpenType-Buttons (dort im
   margin-right von .tt-otnum). Der eingebaute Pfeil gibt seinen eigenen
   Abstand deshalb ab, sonst käme er doppelt. */
.tt-weight-btn { gap: 7px; justify-content: flex-start; }
.tt-weight-btn > .tt-weight-label { flex: 1 1 auto; }
.tt-weight-btn .tt-caret,
.tt-otsets-btn .tt-caret,
.tt-bgcolor-btn .tt-caret { margin: 0; }
.tt-popover {
	position: absolute;
	bottom: calc(100% + var(--tt-pop-offset, 2px)); /* Abstand zum Button (Einstellung) */
	left: 0;
	min-width: 80px;   /* Standard-Mindestbreite (Einstellung: List) */
	max-height: 55vh;
	overflow-y: auto;
	background: none; /* der Kasten selbst ist transparent — die Einträge tragen die Fläche */
	color: #000;
	border: 0; /* kein Standard-Rahmen — kommt bei Bedarf aus den Einstellungen */
	border-radius: 8px;
	box-shadow: none;
	padding: 6px;
	display: flex;
	flex-direction: column;
	gap: var(--tt-pop-gap, 2px); /* Abstand zwischen den Einträgen (Einstellung) */
	z-index: 10001;
	transform-origin: bottom left;
	animation: tt-pop 0.14s ease;
}
/* Kein Scrollbalken an einer aufgeklappten Liste: das Popover bleibt scrollbar
   (sehr lange Listen bleiben erreichbar), zeigt die Leiste aber nicht an. */
.tt-popover { scrollbar-width: none; -ms-overflow-style: none; }
.tt-popover::-webkit-scrollbar { width: 0; height: 0; display: none; }

@keyframes tt-pop { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }
.tt-popover[hidden] { display: none; }

/* ---- Animationsarten (Einstellung "Animationsart"; die Klasse setzt die JS)
   Dauer, Beschleunigung und Versatz je Eintrag kommen als Variablen aus den
   Einstellungen. --tt-i ist der Index des Eintrags (von der JS gesetzt). ---- */
.tt-popover.tt-anim-none  { animation: none; }
.tt-popover.tt-anim-fade  { animation: tt-pop-fade var(--tt-anim-dur, 140ms) var(--tt-anim-ease, ease) var(--tt-anim-delay, 0ms) both; }
.tt-popover.tt-anim-slide { animation: tt-pop var(--tt-anim-dur, 140ms) var(--tt-anim-ease, ease) var(--tt-anim-delay, 0ms) both; }
@keyframes tt-pop-fade { from { opacity: 0; } to { opacity: 1; } }

/* ---- Eigene Bewegung ("Element-Animation") -------------------------------
   Eine einzige Keyframe-Regel für alle Eigenschaften; welche davon wirken,
   entscheiden die Variablen, die das PHP je Einstellung setzt. Eine
   ausgeschaltete Eigenschaft steht auf ihrem neutralen Wert (Deckkraft 1,
   Versatz 0, Maßstab 1, Weichzeichner 0, Drehung/Neigung 0°) und fällt damit
   von selbst weg. Die Vorgaben hier sind die Werte von "Gleiten" — ohne
   ausgegebene Variablen sieht "Eigene" also aus wie bisher. */
@keyframes tt-pop-custom {
	from {
		opacity: var(--tt-pop-opacity, 0);
		transform: translate(var(--tt-pop-x, 0px), var(--tt-pop-y, 6px))
		           scale(var(--tt-pop-scale, 1))
		           rotate(var(--tt-pop-rotate, 0deg))
		           skew(var(--tt-pop-skewx, 0deg), var(--tt-pop-skewy, 0deg));
		filter: blur(var(--tt-pop-blur, 0px));
	}
	to { opacity: 1; transform: none; filter: none; }
}
.tt-popover.tt-anim-custom {
	animation: tt-pop-custom var(--tt-anim-dur, 140ms) var(--tt-anim-ease, ease) var(--tt-anim-delay, 0ms) both;
}

/* "Jeden Eintrag einzeln": der Kasten selbst bewegt sich nicht mehr, dafür
   laufen seine Einträge nacheinander ein — --tt-i ist ihr Index (JS). */
/* Nur zusammen mit der eigenen Bewegung. Ohne diese Bindung liefe die Regel
   auch im Fächer-Modus und ihr `transform: none` im Zielbild würde — wegen
   `fill-mode: both` — die Ruhelagen des Fächers überschreiben. */
.tt-popover.tt-anim-custom.tt-anim-each { animation: none; }
.tt-popover.tt-anim-custom.tt-anim-each > * {
	animation: tt-pop-custom var(--tt-anim-dur, 140ms) var(--tt-anim-ease, ease) both;
	animation-delay: calc(var(--tt-anim-delay, 0ms) + var(--tt-i, 0) * var(--tt-anim-stagger, 0ms));
}
/* Auffächern ohne Fächer-Ruhezustand: die Einträge laufen nacheinander ein. */
.tt-popover.tt-anim-fan { animation: none; }
.tt-popover.tt-anim-fan > * {
	animation: tt-pop var(--tt-anim-dur, 140ms) var(--tt-anim-ease, ease) both;
	animation-delay: calc(var(--tt-i, 0) * var(--tt-anim-stagger, 0ms));
}

/* ---- Fächer-Modus: das Popover bleibt sichtbar, die Einträge liegen hinter
   dem Button und schauen ein Stück hervor; beim Klick fächern sie auf.
   Die Verschiebung je Eintrag (--tt-fan-dy) rechnet die JS aus. ---- */
.tt-popover.tt-fan {
	/* kein Scrollen: die gestapelten Einträge stehen bewusst über den Kasten
	   hinaus, ein Scrollrahmen würde sie abschneiden */
	overflow: visible;
	max-height: none;
	animation: none;
	/* IMMER hinter dem Button — auch während des Auffächerns, sonst blitzen die
	   Karten beim Öffnen kurz über ihm auf. */
	z-index: -1;
	pointer-events: none;   /* im Ruhezustand schaltet nur der Button */
}
.tt-popover.tt-fan.is-open { pointer-events: auto; }
/* Eigener Stapelkontext, damit z-index:-1 hinter dem Button landet und nicht
   hinter dem Hintergrund der Leiste verschwindet. */
.tt-mi:has(> .tt-popover.tt-fan) { z-index: 10001; }
.tt-popover.tt-fan > * {
	transform: translateY(var(--tt-fan-dy, 0px));
	transition: transform var(--tt-anim-dur, 140ms) var(--tt-anim-ease, ease);
	animation: none;
}
/* Versatz je Eintrag nur bei der Animationsart "Auffächern". */
.tt-popover.tt-fan.tt-anim-fan > * { transition-delay: calc(var(--tt-i, 0) * var(--tt-anim-stagger, 0ms)); }
/* "Ohne": der Fächer springt auf und zu. */
.tt-popover.tt-fan.tt-anim-none > * { transition: none; }
.tt-popover.tt-fan.is-open > * { transform: none; }
/* Waagerechter Stapel: Karten UND Button behalten rundum ihre Rundung — die
   Karten stecken einfach hintereinander (die linke Hälfte ist verdeckt). Damit
   in den runden Ecken kein weißer Kartenhintergrund durchblitzt, füllt die
   Farbfläche den Eintrag samt Rundung: der Eintrag clippt (overflow:hidden,
   siehe .tt-swatch) und die Fläche bekommt denselben Radius. */
.typetheme .tt-bgcolor-list .tt-swatch-dot { border-radius: inherit; }

/* Beim Messen (JS) kurz ohne Versatz und ohne Bewegung. */
.tt-popover.tt-fan.tt-fan-measure > * { transform: none; transition: none; }
/* Die Ruhelage beim Seitenaufbau (und beim Neuberechnen) wird ohne Bewegung
   eingenommen — animiert wird nur das Auf- und Zufächern per Klick. */
.tt-popover.tt-fan.tt-fan-still > * { transition: none; }
.tt-popover-item {
	text-align: left;
	background: #fff; /* der Eintrag ist die sichtbare Fläche (Einstellung: Item) */
	border: 0;
	padding: 8px 10px;
	border-radius: 5px;
	cursor: pointer;
	color: var(--tt-ink);
	font: inherit;
	white-space: nowrap;
	/* Standard-Mindestbreite (Einstellung: Item) — nie schmaler als der Button,
	   an dem die Liste hängt: gleich breite oder schmalere Einträge übernehmen
	   dessen Breite (--tt-btn-w, von der JS gemessen), breitere behalten ihre. */
	min-width: max(80px, var(--tt-btn-w, 0px));
	min-height: 40px;  /* Standardhöhe (Einstellung: Item) */
	box-sizing: border-box;
}
.tt-popover-item:hover { background: rgba(127, 127, 127, 0.16); }
.tt-popover-item.is-active { background: var(--tt-ink); color: #fff; }

/* stylistic sets (ss01…) bundled into their own popover — opt-in setting,
   kicks in from four available sets. The entries keep .tt-otbtn (so the
   feature logic still finds them) and gain .tt-popover-item for the look. */
/* min-content statt 0: der Wrapper darf schrumpfen (die Beschriftung kürzt sich
   mit Ellipse), aber nicht unter die Mindestbreite seines Buttons — sonst wäre
   er 0 breit und ein Popover mit Mindestbreite "auto" (= 100 % des Wrappers)
   ebenfalls, sodass Symbol und Beschriftung der Einträge übereinanderlägen. */
.tt-otsets { flex: 0 1 auto; min-width: min-content; }
/* Symbol links, Beschriftung linksbündig daneben */
.tt-otsets-btn { gap: 7px; max-width: 100%; justify-content: flex-start; }
.tt-otsets-label { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; min-width: 0; text-align: left; flex: 1 1 auto; }
.tt-otsets-list { min-width: 80px; }   /* wie die übrigen Popover (Einstellung: List) */
.tt-otsets-list .tt-otbtn { flex: 0 0 auto; width: 100%; justify-content: flex-start; }

/* weight/style list uses the same text format as the whole toolbar */
/* Die Schnitt-Liste ist standardmäßig transparent — die Fläche tragen die
   Einträge. (Eine Farbe in den Einstellungen "List" überschreibt das.) */
.tt-weight-list { background: none; }

/* Hintergrundfarben-Button: Beschriftung links, Symbol rechts — wie beim
   Schnitt- und beim Sets-Button. */
.tt-bgcolor { flex: 0 1 auto; min-width: min-content; }
.tt-bgcolor-btn { gap: 7px; max-width: 100%; justify-content: flex-start; }
.tt-bgcolor-label { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; min-width: 0; text-align: left; flex: 1 1 auto; }

/* Hintergrundfarben-Popover: ein Eintrag je Farbe — links die Farbfläche über
   die volle Höhe, rechts der Hex-Wert. Der Eintrag selbst hat kein Innenpadding
   (sonst käme die Farbfläche nicht an den Rand); die Höhe macht das Label. */
.tt-bgcolor-list { font-family: inherit; }
.typetheme .tt-bgcolor-list .tt-popover-item.tt-swatch {
	display: flex;
	align-items: stretch;
	gap: 0;
	padding: 0 !important;
	overflow: hidden;
	/* Der Eintrag ist so breit wie das Popover (und das ist bei Mindestbreite
	   "auto" so breit wie der Button); die Höhe macht die Beschriftung. */
	width: 100%;
	min-height: 40px;
	font-size: 12px;
}
.typetheme .tt-bgcolor-list .tt-swatch-dot {
	display: block;
	/* feste Breite 40px, Höhe = Höhe des Eintrags */
	flex: 0 0 40px;
	width: 40px;
	align-self: stretch;
	border: 0;
	border-radius: 0;
}
.typetheme .tt-bgcolor-list .tt-swatch-label {
	flex: 1 1 auto;
	display: flex;
	align-items: center;
	justify-content: flex-start;
	padding: 8px 10px;
	white-space: nowrap;
	letter-spacing: 0.02em;
}

.tt-weight-list { font-family: inherit; }
.tt-weight-list .tt-popover-item { font-size: 13px; }
/* family header in the [typetheme] (all families) picker */
.tt-popover-group {
	font-size: 10px;
	letter-spacing: 0.06em;
	text-transform: uppercase;
	opacity: 0.5;
	padding: 8px 10px 2px;
	white-space: nowrap;
}
.tt-popover-group:first-child { padding-top: 2px; }

/* ---- slider groups (Layout + Variable-fonts) ----
   Three zones: a left icon cell and a right clear cell, each the same
   40x40/8px-padding box as an icon-only button (see .tt-btn:has(...) below),
   separated from the middle slider track by a 1px divider. The middle stays
   unfilled (no background of its own) so only the two end cells read as
   "buttons"; the group's own border/radius draw the shared outline. */
.tt-slidergroup {
	display: inline-flex;
	align-items: center;    /* icon/clear cells are already a fixed 40px tall;
	                           center keeps the 1px slider track (and its thumb)
	                           vertically centred instead of stretched */
	gap: 0;                 /* the dividers replace the old flat gap; the
	                           slider/value area gets its own margin below */
	flex: 1 1 0;            /* flexible width, shares the panel, no scroll */
	/* Nie schmaler als ihr Inhalt. Mit den festen 40px von frueher schrumpfte
	   die Gruppe unter Symbol + Regler + Wert + Zuruecksetzen — die Zellen
	   lagen dann uebereinander bzw. wurden am Rand abgeschnitten. Was beim
	   Schrumpfen nachgibt, ist weiterhin allein der Regler (.tt-slider). */
	min-width: min-content;
	overflow: hidden;       /* clips the icon/clear cells to the rounded corners */
	background: transparent;
	border: 1px solid var(--tt-line);
	border-radius: 4px;     /* same default radius as .tt-btn */
	box-sizing: border-box;
	/* exactly the same outer height as an icon-only button (border included), so
	   the group never sticks out of the 40px control row */
	height: max(40px, calc(var(--tt-icon, 24px) + 16px));
}
/* the range itself absorbs the shrinking; icon/value/clear stay fixed */
/* Ausgangsbreite 0, nicht `auto`: ein <input type="range"> bringt eine eigene
   Wunschbreite von rund 130px mit, und die zaehlt bei `auto` in die
   Mindestbreite der ganzen Reglergruppe hinein — drei Gruppen forderten damit
   839px statt 524px, und in einer vollen Leiste blieb fuer einen aufgeklappten
   Stapel nichts mehr uebrig (gemessen bei 1400px). Mit 0 waechst der Regler
   weiterhin in den freien Platz, verlangt ihn aber nicht mehr. */
.tt-slidergroup .tt-slider { flex: 1 1 0; min-width: 24px; width: 24px; margin: 0 10px; }
/* Left icon cell: same size/padding as an icon-only button (24px icon in a
   40x40 box). It is a passive label, not a real button — no divider, no
   hover/active state.
   There is no wrapper element: the symbol IS the cell. Ein hochgeladenes Icon
   traegt hier `.tt-slider-icon` (dieselbe CSS-Maske wie `.tt-icon`, aber eine
   eigene Klasse), ein Zeichen-Symbol `.tt-glyph`. Die eigene Klasse existiert
   genau deshalb, weil diese Zelle keine Hover-/Aktiv-Zustaende annehmen darf —
   mit der gemeinsamen `.tt-icon` liess sie sich nicht vom Icon eines Buttons
   unterscheiden. */
.typetheme .tt-slidergroup > .tt-slider-icon,
.typetheme .tt-slidergroup > .tt-glyph {
	flex: 0 0 auto;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: max(40px, calc(var(--tt-icon, 24px) + 16px));
	height: 100%;   /* fills the group's inner height (its border is on the group) */
	padding: 8px;
	box-sizing: border-box;
	line-height: 1;
	overflow: hidden;
	white-space: nowrap;
	text-align: center;
	/* The mask is laid out in the PADDING box, not the (now 40px) border box —
	   otherwise mask-size:contain would blow the symbol up to the full cell.
	   This keeps it at --tt-icon, exactly like an icon inside a button. */
	-webkit-mask-origin: content-box;
	mask-origin: content-box;
}
/* Variable-font axes are labelled with a NAME ("Weight", "y transparent"), not
   a 24px icon — so that cell grows with its text instead of staying square. */
.typetheme .tt-slidergroup-varfonts > .tt-glyph {
	width: auto;
	padding: 0 10px;
	font-size: 12px;
	white-space: nowrap;
	overflow: hidden;
	text-overflow: ellipsis;
	max-width: 40%;
	justify-content: flex-start;
}
.tt-val {
	/* Fixed width so the value column never changes size with its content —
	   otherwise the flexible slider would grow/shrink and the line would jump
	   as the number goes 0 → 80 → 300. tabular-nums keeps digits equal-width.
	   Right-aligned so it sits right before the clear cell's divider. */
	flex: 0 0 46px;
	width: 46px;
	/* Der Wert ist ein UI-Text wie jeder andere: Farbe, Textformat und die
	   Zustände kommen aus den Einstellungen (die Karte "Design" setzt
	   `color:inherit` auf .tt-val, er nimmt also die Farbe seiner Gruppe an).
	   Bewusst KEIN eigenes `opacity` und kein Sonderweg beim Fokus — sonst
	   stünde er gedimmt neben Beschriftungen, die dieselbe Farbe tragen. */
	color: var(--tt-ink);
	font-variant-numeric: tabular-nums;
	font-size: 12px;
	text-align: right;
	padding: 0 10px 0 4px;
	cursor: text;          /* the value is an editable number field */
	caret-color: var(--tt-ink);
}
/* Beim Bearbeiten bleibt nur der Fokusrahmen weg — die Farbe ändert sich
   nicht, der Wert sieht in jedem Zustand aus wie die übrigen UI-Texte. */
.typetheme .tt-slidergroup .tt-val:focus {
	outline: none;
}
/* Right clear cell: mirrors the icon cell — same size/padding/colours as an
   icon-only button, divider border on the left instead of the right. */
/* The axis rows carry the same two cells: play/pause and stop (which halts a
   running animation and puts the axis back on its default). Same look. */
.tt-clear,
.tt-stop,
.tt-anim {
	flex: 0 0 auto;
	width: max(40px, calc(var(--tt-icon, 24px) + 16px));
	height: 100%;   /* fills the group's inner height (its border is on the group) */
	box-sizing: border-box;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	border: 0;
	border-left: 1px solid var(--tt-line);
	background: transparent;
	cursor: pointer;
	color: var(--tt-ink);
	font-size: 12px;
	line-height: 1;
	padding: 8px;
}
/* Der Zurücksetzen-Button ist ein ganz normaler .tt-btn — Verhalten, Hover,
   Transition und die Einstellungen greifen über .tt-btn. Nur Rahmen und Radius
   bleiben aus: die Gruppe hat ihren eigenen Rahmen, ein zweiter Rahmen darin
   würde sie zerteilen. Eigener Selektor mit .tt-slidergroup, damit er die
   Icon-only-Regel für .tt-btn (feste 40px Höhe) schlägt — hier füllt die Zelle
   die Innenhöhe der Gruppe. Und mit .tt-btn.tt-clear liegt sie über der
   Icon-only-Regel, die gleich spezifisch, aber später notiert ist. */
.typetheme .tt-slidergroup > .tt-btn.tt-clear {
	border: 0;
	/* Trennlinie zum Slider — in JEDER Gruppe, also auch bei den drei
	   Layout-Reglern (Groesse / Zeilenhoehe / Laufweite). Bis hierher war sie
	   dort per eigener Regel abgeschaltet und blieb nur in den Achsenzeilen. */
	border-left: 1px solid var(--tt-line);
	border-radius: 0;
	/* Die Leiste lässt Buttons schrumpfen (.typetheme-menu .tt-btn{flex-shrink:1}).
	   In der Gruppe absorbiert das der Slider — die Zelle bleibt fest, wie die
	   Stopp-/Animations-Zellen der Achsenzeilen daneben. */
	/* Die Breite steht mit !important da: die Einstellung "Breite" fuer
	   Bedienelemente (Standard 100%) zielt auf .tt-btn — 100% waere hier die
	   ganze Gruppe, Symbol, Regler und Wert daneben fielen heraus. Diese Zelle
	   ist so breit wie ein Symbol-Button, Punkt. */
	flex: 0 0 auto;
	width: max(40px, calc(var(--tt-icon, 24px) + 16px)) !important;
	height: 100%;
	min-height: 0;
	min-width: 0;
	padding: 8px;
}
/* Dasselbe fuer die beiden Zellen der Achsenzeilen (Abspielen / Stopp): auch
   sie sind .tt-btn und wuerden sonst die eingestellte Breite annehmen.
   Fuenf Klassen im Selektor sind noetig, nicht vier: die Breiten-Einstellung
   trifft die Zelle ueber `.typetheme .typetheme-menu .tt-mi .tt-btn` (0,4,0 +
   !important) und stuende bei Gleichstand spaeter — die dynamische CSS haengt
   hinter dem Stylesheet. */
.typetheme .typetheme-menu .tt-slidergroup > .tt-btn.tt-clear,
.typetheme .typetheme-menu .tt-slidergroup > .tt-btn.tt-stop,
.typetheme .typetheme-menu .tt-slidergroup > .tt-btn.tt-anim {
	width: max(40px, calc(var(--tt-icon, 24px) + 16px)) !important;
	flex: 0 0 auto !important;
}

/* ---- OpenType feature buttons (OpenType state): flexible width, no scroll,
   label truncates when the button gets too small ---- */
.tt-otbtn {
	gap: 0;
	/* Auf Ansage flexibel: die OpenType-Buttons teilen sich die Reihe zu
	   gleichen Teilen. Symbol und Beschriftung darin bleiben linksbuendig und
	   inhaltsbreit (.tt-otnum / .tt-otlabel). */
	flex: 1 1 0;
	min-width: 0;
	overflow: hidden;
	justify-content: flex-start; /* badge + label left-aligned */
	text-align: left;
}
/* Der Button ist mit `flex: 1 1 0` breiter als sein Inhalt — der muss trotzdem
   links stehen. Die Zeile darueber reicht dafuer nicht: der umgebende
   `.tt-mi.tt-state-otfeat` traegt `tt-mode-icon`, und `.tt-mode-icon .tt-btn`
   (0,2,0) zentriert und schlaegt `.tt-otbtn` (0,1,0). Ausgenommen bleibt die
   dreizeilige Leiste: dort ist die Beschriftung ausgeblendet, der Button traegt
   nur sein Symbol, und das gehoert mittig. */
.typetheme .typetheme-menu:not(.tt-bar-triple) .tt-otbtn { justify-content: flex-start; }
.tt-otnum {
	display: inline-flex;
	align-items: center;
	/* Vorgabe: linksbuendig, Breite auto — das Symbol haelt keine feste
	   Badge-Breite mehr, sondern richtet sich nach seinem Inhalt. */
	justify-content: flex-start;
	width: auto;
	height: var(--tt-icon, 24px);
	border-radius: 50%;
	border: 1px solid currentColor;
	font-size: 11px;
	margin-right: 7px;
	flex: 0 0 auto;
	overflow: hidden;
}
/* a custom per-feature symbol (char/icon) drops the number circle */
.tt-otnum.has-symbol {
	width: auto;
	height: auto;
	min-width: 0;
	border: 0;
	border-radius: 0;
}
/* Vorgabe: linksbuendig, Breite auto (passt sich der Textlaenge an). */
.tt-otlabel { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; min-width: 0; width: auto; text-align: left; }

/* ---- inverted mode: flips only the specimen box; the fixed menu stays
   readable on its own background ---- */

/* Die helle und die dunkle Farbe kommen aus den Einstellungen. */
.typetheme.is-inverted .typetheme-stage {
	--tt-ink: var(--tt-light, #fff);
	background: var(--tt-dark, #000);
}
/* Automatischer Schriftfarbwechsel: erkennt das JS einen dunklen Hintergrund
   (Grauwert unter 50 %), setzt es .tt-dark-bg — die Schrift wird dann hell.
   Der Invertieren-Button dreht das Ergebnis weiterhin um. */
.typetheme.tt-dark-bg .typetheme-stage {
	--tt-ink: var(--tt-light, #fff);
}
.typetheme.tt-dark-bg.is-inverted .typetheme-stage {
	--tt-ink: var(--tt-dark, #000);
}
/* Setting "nur Schriftfarbe umkehren": the ink still flips to white, but the
   background stays whatever it is — the default or a colour the visitor picked. */
.typetheme.tt-invert-text-only.is-inverted .typetheme-stage {
	background: var(--tt-bg);
}

/* Die Leiste trägt immer dieselbe Farbe wie die Bühne: beim Invertieren also
   die dunkle Farbe, bei "nur Schriftfarbe umkehren" bleibt sie, wie sie war.
   Dazu die Schriftfarbe, damit die Bedienelemente lesbar bleiben. */
.typetheme.is-inverted .typetheme-menu {
	background: var(--tt-dark, #000);
	--tt-ink: var(--tt-light, #fff);
}
.typetheme.tt-dark-bg .typetheme-menu {
	--tt-ink: var(--tt-light, #fff);
}
.typetheme.tt-dark-bg.is-inverted .typetheme-menu {
	--tt-ink: var(--tt-dark, #000);
}
.typetheme.tt-invert-text-only.is-inverted .typetheme-menu {
	background: var(--tt-bg-active, var(--tt-menu-bg));
}
/* Scrollt die Seite, liegt die Leiste wieder ÜBER der Bühne — dann gilt für
   ihren Hintergrund die Einstellung aus der Karte "Bar" (Farbe + Deckkraft),
   nicht die Farbe der Bühne. Die Klasse steht doppelt, damit die Regel auch
   die Invertier-Regeln darüber schlägt. */
.typetheme.tt-page-scrolls.tt-page-scrolls .typetheme-menu {
	background: var(--tt-menu-bg);
}

/* ---- small screens: let the toolbar scroll horizontally ---- */

@media (max-width: 700px) {
	.typetheme-menu {
		overflow-x: auto;
		justify-content: flex-start;
	}
	.tt-slider {
		width: 90px;
	}
}

/* icon-only buttons (single glyph/icon child) drop the horizontal padding and
   sit at the exact 32px default square; text buttons keep growing naturally */
/* icon-only buttons: the icon (--tt-icon, default 24px) in an 8px-padded square
   — 40x40 at the default size, growing only when the symbol needs more room, so
   a larger symbol is never clipped. */
.tt-btn:has(> .tt-glyph:only-child),
.tt-btn:has(> .tt-icon:only-child),
.tt-btn:has(> svg:only-child),   /* built-in SVG symbols sit directly in the button */
.tt-btn:has(> .tt-align-label:only-child) {   /* Ausrichtung: Symbol in seiner Beschriftung */
	width: max(40px, calc(var(--tt-icon, 24px) + 16px));
	height: max(40px, calc(var(--tt-icon, 24px) + 16px));
	padding: 8px;
}

/* ---- Gridder integration: keep the fixed toolbar above later rows ----
   Lay gives every Gridder .col its own stacking context (position:relative;
   z-index:1). The tester's fixed footer toolbar is trapped inside the column
   of its row, so a LATER row's column (higher in DOM paint order, same
   z-index) would paint over the toolbar buttons. Raising the column that
   hosts a tester lifts its whole stacking context — including the trapped
   fixed toolbar — above the rows that follow it. */
.lay-content .col:has(.typetheme) {
	z-index: 30;
}

/* ---- single-line buttons, even against the host theme ----
   Lay's text-format CSS applies white-space:normal / word-break to shortcode
   content with !important, which made long labels ("Stilistisches Set 2")
   wrap onto several lines. Win it back with higher specificity + !important so
   every toolbar button stays one line and clips its overflow. */
.typetheme .typetheme-menu .tt-btn,
.typetheme .typetheme-menu .tt-font-btn {
	white-space: nowrap !important;
	overflow: hidden !important;
	word-break: normal !important;
	overflow-wrap: normal !important;
}
.typetheme .typetheme-menu .tt-otlabel,
.typetheme .typetheme-menu .tt-weight-label,
.typetheme .typetheme-menu .tt-otsets-label,
.typetheme .typetheme-menu .tt-bgcolor-label,
.typetheme .typetheme-menu .tt-align-label,
.typetheme .typetheme-menu .tt-swatch-label,
.typetheme .typetheme-menu .tt-val {
	white-space: nowrap !important;
	overflow: hidden !important;
	text-overflow: ellipsis !important;
	word-break: normal !important;
	overflow-wrap: normal !important;
	min-width: 0;
}
/* Die Beschriftungen halten eine Mindestbreite, damit die Buttons beim Wechsel
   des Inhalts nicht springen (Einstellung: Buttons → Mindestbreite); der Text
   steht dabei linksbündig in dieser Breite. Gleicher Standard für alle
   beschrifteten Dropdown-Buttons. */
/* Die Beschriftungen halten keine feste Breite mehr — der Button ist so breit
   wie sein Inhalt, mindestens 40px (siehe .tt-btn). Eine feste Mindestbreite
   gibt es weiterhin über die Einstellungen. */
.typetheme .typetheme-menu .tt-weight-label,
.typetheme .typetheme-menu .tt-bgcolor-label,
.typetheme .typetheme-menu .tt-align-label {
	text-align: left !important;
}
/* The labels need `overflow:hidden` for the ellipsis, which clips at the
   padding box — with the text format's line-height of exactly 1 that cut the
   descenders off ("Regular" lost the tail of its g). A little leading gives
   them room; the labels are centred flex items, so the button height is
   unaffected. */
/* Gilt für JEDE Beschriftung in der Leiste und in den Popovers — sonst schneidet
   das overflow:hidden die Unterlängen ab (das "g" in "Hintergrundfarben").
   Dasselbe gilt für Zeichen-Symbole: .tt-glyph hat zwar overflow:visible, wird
   aber vom Button darum (overflow:hidden) beschnitten. */
.typetheme .typetheme-menu .tt-glyph,
.typetheme .typetheme-menu .tt-otlabel,
.typetheme .typetheme-menu .tt-weight-label,
.typetheme .typetheme-menu .tt-otsets-label,
.typetheme .typetheme-menu .tt-bgcolor-label,
.typetheme .typetheme-menu .tt-align-label,
.typetheme .typetheme-menu .tt-swatch-label {
	line-height: 1.3 !important;
}

/* ==== Zustandsschalter als .tt-mi ========================================
   Layout, Variable Fonts und OpenType laufen seit 1.6.0 durch dieselbe
   Mechanik wie die vier Popover-Buttons — mit zwei Unterschieden, die hier
   geradegezogen werden:

   1. "Nebeneinander" heisst bei ihnen NICHT, dass der Button verschwindet.
      Bei den vier anderen ist er entbehrlich, sobald alle Eintraege in der
      Leiste stehen; hier schaltet er die Sektion um und muss bleiben.
   2. Ihr Panel fuellt in dieser Betriebsart die Leiste aus (frueher trug das
      Panel selbst flex:1 1 auto — jetzt ist der Wrapper das Flex-Kind).
   ======================================================================== */

.typetheme .tt-mi.tt-state.tt-mode-inline > .tt-btn { display: inline-flex !important; }
/* Nur der Block, dessen Sektion GERADE gilt, nimmt den freien Platz ein — die
   beiden anderen sind in diesem Moment bloss ihr Button und dürfen nicht
   mitschrumpfen. (Ohne diese Unterscheidung teilten sich alle drei die Breite
   und die beiden zugeklappten Buttons wurden schmaler als 40px.) */
.typetheme .tt-mi.tt-state.tt-mode-inline { flex: 0 0 auto; }
.typetheme .typetheme-menu.state-layout   .tt-mi.tt-state-sliders.tt-mode-inline,
.typetheme .typetheme-menu.state-varfonts .tt-mi.tt-state-varfonts.tt-mode-inline,
.typetheme .typetheme-menu.state-opentype .tt-mi.tt-state-otfeat.tt-mode-inline { flex: 1 1 auto; min-width: 0; }
.typetheme .tt-mi.tt-state.tt-mode-inline > .tt-state-panel {
	flex: 1 1 auto;
	/* Nie schmaler als seine Reglergruppen. Mit dem geerbten min-width:0 gab
	   das Panel im Gedraenge so viel Platz her, dass die Gruppen darin nicht
	   mehr nebeneinander passten — sie ragten aus dem Panel heraus und wurden
	   von seinem overflow abgeschnitten. Platz gibt jetzt zuerst der Button
	   der Sektion her (er darf bis auf seine Mindestbreite schrumpfen).
	   Mit !important, weil die Regel fuer Popover in der Reihe
	   (.typetheme .tt-mi.tt-mode-inline > .tt-popover) min-width:0 !important
	   setzt — ohne Gleichstand in der Wichtigkeit gaebe es kein Durchkommen. */
	min-width: min-content !important;
	overflow: hidden;
	/* Als Sektion in der Reihe hatte das Panel nie einen Innenabstand — den
	   bekommt es erst, seit es ein .tt-popover ist (Einstellung „List" →
	   Innenabstand). Er verkürzte die Reihe um 24px und die Regler füllten sie
	   nicht mehr aus. */
	padding: 0 !important;
}
/* … außer während der Sets-Stapel offen ist: dann darf das Panel nicht
   beschneiden, sonst endet der Stapel an seiner Kante. Die Regel dafür steht
   weiter oben (.tt-state-panel.tt-sets-open), wurde aber von der Zeile darüber
   überstimmt, seit die Panels eine eigene, spezifischere Regel haben. */
.typetheme .tt-mi.tt-state.tt-mode-inline > .tt-state-panel.tt-sets-open { overflow: visible; }

/* Als Liste: das Panel ist ein Popover. Die Zustandsregeln weiter oben
   (.typetheme-menu .tt-panel-* { display:none }) duerfen es dann nicht mehr
   ein- und ausblenden — das macht die Popover-Mechanik ueber [hidden]. */
.typetheme .tt-mi.tt-state:not(.tt-mode-inline) > .tt-state-panel {
	display: flex;
	flex: 0 0 auto;
	flex-direction: column;
	align-items: stretch;
	overflow-y: auto;
	/* Eine Reglerzeile ist deutlich breiter als ihr Button (Symbol + Zahl +
	   Zuruecksetzen). Ohne max-content presst die Ausrichtung eines absolut
	   positionierten Kastens die Liste auf die Breite des Buttons zusammen —
	   der Wert wurde abgeschnitten und der Zuruecksetzen-Knopf fiel heraus.
	   Die Deckelung haelt sie trotzdem auf dem Schirm. */
	width: max-content;
	max-width: 88vw;
}
/* ---- Zustands-Panel in waagerechter Richtung -----------------------------
   Die Regel fuer Zustands-Panels oben ist SPEZIFISCHER als die des
   waagerechten Faechers (`.tt-state` + `:not(.tt-mode-inline)` = eine Klasse
   mehr) und steht ausserdem spaeter — sie hat dessen `flex-direction: row`
   mit `column` ueberschrieben. Die Karten stapelten sich deshalb senkrecht:
   das Panel wurde so hoch wie alle Karten zusammen (3 Regler = 126px) und
   hing als schmaler Streifen unter der Leiste, statt eine Karte hoch neben
   dem Button zu liegen.
   Dazu das Scrollen: `overflow-y: auto` macht den Kasten zum Scroll-Container,
   und weil dann keine Achse mehr `visible` sein kann, rechnet auch
   `overflow-x` auf `auto` — die per transform herausragenden Karten des
   Faechers waeren abgeschnitten. */
.typetheme .tt-mi.tt-dir-left.tt-state:not(.tt-mode-inline) > .tt-state-panel,
.typetheme .tt-mi.tt-dir-right.tt-state:not(.tt-mode-inline) > .tt-state-panel {
	flex-direction: row;
	align-items: center;
	overflow: visible;
	width: 0 !important;
	max-width: none;
}
.typetheme .tt-mi.tt-dir-left.tt-state:not(.tt-mode-inline) > .tt-state-panel { justify-content: flex-end; }
.typetheme .tt-mi.tt-dir-right.tt-state:not(.tt-mode-inline) > .tt-state-panel { justify-content: flex-start; }

/* Senkrechter Faecher: derselbe Scroll-Fallstrick, nur auf der anderen Achse. */
.typetheme .tt-mi.tt-state:not(.tt-mode-inline) > .tt-state-panel.tt-fan {
	overflow: visible;
}

.typetheme .tt-mi.tt-state > .tt-state-panel[hidden] { display: none; }
/* In der Liste steht jede Reglergruppe / jeder Funktionsbutton untereinander,
   wie die Eintraege der uebrigen Popover. Bewusst OHNE `width:100%`: das
   Popover ist absolut positioniert und richtet seine Breite nach dem breitesten
   Kind — ein Kind mit width:100% traegt dazu nichts bei, und die Liste blieb
   auf der Mindestbreite stehen (Wert abgeschnitten, Zuruecksetzen-Knopf weg).
   `align-items:stretch` zieht die Zeilen ohnehin auf volle Breite. */
.typetheme .tt-mi.tt-state:not(.tt-mode-inline) > .tt-state-panel > * {
	flex: 0 0 auto;
}

/* Der Zustandsbutton ist im Symbolmodus ein Quadrat wie bisher. Die Regel
   `.tt-btn:has(> svg:only-child)` greift nicht mehr, seit die (ausgeblendete)
   Beschriftung dauerhaft im Markup steht — :only-child sieht sie trotzdem. */
.typetheme .tt-mi.tt-state.tt-mode-icon > .tt-btn {
	/* MINDEST-, keine Festgroesse. Vorher stand hier width/height: der Button
	   blieb dann bei Symbol+16px stehen, auch wenn der eingestellte
	   Innenabstand mehr verlangte — bei Symbol 48px und Innenabstand 20/28
	   hatte ein 48px-Symbol nur 16px Platz und lief aus seiner eigenen Box.
	   Als Mindestmass bleibt die Vorgabe unveraendert (24+16 = 40) und der
	   Button waechst nur, wenn die Einstellungen es verlangen. */
	min-width: max(40px, calc(var(--tt-icon, 24px) + 16px));
	min-height: max(40px, calc(var(--tt-icon, 24px) + 16px));
	padding: 8px;
}
/* Mit Beschriftung: Text links, Symbol rechts — wie beim Schnitt-Button. */
.typetheme .tt-mi.tt-state:not(.tt-mode-icon) > .tt-btn { gap: 7px; justify-content: flex-start; }
.tt-state-label { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; min-width: 0; text-align: left; flex: 1 1 auto; }

/* ==== Regler oder reine Werteingabe =====================================
   Bei "Nur Werteingabe" faellt allein die Reglerbahn weg. Symbol, Zahlenfeld
   (ohnehin ein Eingabefeld) und Zuruecksetzen bleiben stehen, und die Gruppe
   waechst nicht mehr ueber ihren Inhalt hinaus.
   ======================================================================== */
.typetheme.tt-sliders-value .tt-slidergroup > .tt-slider { display: none; }
.typetheme.tt-sliders-value .tt-slidergroup { flex: 0 0 auto; }
/* Ohne Regler traegt die Zahl den Streifen — genug Platz zum Tippen, und der
   Abstand, den sonst die Reglerbahn hielt, kommt als Innenabstand zurueck. */
.typetheme.tt-sliders-value .tt-slidergroup > .tt-val { min-width: 48px; margin: 0 10px; text-align: center; }
/* In der Liste traegt die Zahl den freien Platz der Zeile, zwischen Symbol und
   Zuruecksetzen. */
.typetheme .tt-mi.tt-state:not(.tt-mode-inline) .tt-slidergroup { flex: 0 0 auto; }
.typetheme .tt-mi.tt-state:not(.tt-mode-inline) .tt-slidergroup > .tt-val { flex: 1 1 auto; }

/* ==== Dreizeilige Leiste ==================================================
   Einstellung „List" → Leiste, Stufe Mobile. Aufbau:
     Zeile 1  Schnitte · Ausrichtung · OpenType · Farben · Invertieren · Zurücksetzen
     Zeile 2  Layout (Breite auto) + Stilistische Sets
     Zeile 3  Variable Fonts — nur wenn die Schrift Achsen hat

   Der Unterschied zur einreihigen Leiste ist nicht bloß der Umbruch: JEDER
   Stapel steht hier IM FLUSS über seinem Button, statt darüber zu schweben.
   Er wächst damit nach oben und schiebt die Zeilen darüber mit — die Leiste
   hängt am unteren Rand, also bleibt der gedrückte Button, wo er ist.
   Der Fächer ist in dieser Betriebsart aus: er rechnet mit absoluten
   Ruhelagen, die es im Fluss nicht gibt.
   ======================================================================== */

.typetheme .typetheme-menu.tt-bar-triple {
	flex-direction: column;
	align-items: stretch;
	/* Der waagerechte Rückfall der schmalen Ansicht gilt hier nicht mehr —
	   die Zeilen brechen um, statt zu scrollen. */
	overflow-x: visible;
	/* Getrennt, weil der eingestellte Abstand prozentual sein darf: waagerecht
	   bezieht sich das auf die Zeilenbreite (gewollt), senkrecht auf die Höhe
	   der Leiste — die steht hier nicht fest und der Abstand fiele auf 0.
	   --tt-row-gap liefert dafür einen px-Wert (siehe gap_css() in PHP). */
	row-gap: var(--tt-row-gap, var(--tt-gap, 2px));
	column-gap: var(--tt-gap, 2px);
}
.typetheme .tt-bar-row {
	display: flex;
	flex-direction: row;
	/* Die Buttons stehen auf der Unterkante ihrer Zeile, damit ein wachsender
	   Stapel nach oben geht und den Button nicht mitnimmt. */
	align-items: flex-end;
	gap: var(--tt-gap, 2px);
	row-gap: var(--tt-row-gap, var(--tt-gap, 2px));
	min-width: 0;
}

/* Letzte Stufe, wenn selbst .tt-crowded den Inhalt nicht mehr unterbringt:
   umbrechen, damit nichts unerreichbar aus dem Bild laeuft (auf 390px lagen
   sonst "Invertieren" und "Zuruecksetzen" bei x 407 und 465). Die JS setzt
   .tt-menu-wrap erst, wenn nach dem Kuerzen immer noch etwas uebersteht. */
.typetheme .typetheme-menu.tt-menu-wrap { flex-wrap: wrap; align-content: center; }
.typetheme .typetheme-menu.tt-menu-wrap .tt-bar-row { flex-wrap: wrap; align-content: flex-end; }
.typetheme .tt-bar-row[hidden] { display: none; }

/* Stapel im Fluss: column-reverse setzt die Liste ÜBER ihren Button, ohne
   dass jemand Koordinaten ausrechnen muss. */
.typetheme .typetheme-menu.tt-bar-triple .tt-mi:not(.tt-dir-left):not(.tt-dir-right) {
	display: flex;
	flex-direction: column-reverse;
	/* stretch, damit ein Button die Breite seines .tt-mi wirklich einnimmt.
	   Der Stapel darüber bleibt davon unberührt — er ist 0px breit (siehe
	   unten) und wächst ohnehin über seine Kante hinaus. */
	align-items: stretch;
	gap: var(--tt-pop-gap, 2px);
}
/* Die beiden beschrifteten Zustandsschalter füllen ihre Zeile aus. In Zeile 3
   sind das die vollen 335px, in Zeile 2 alles außer den 40px, die der
   Sets-Stapel daneben braucht. */
.typetheme .typetheme-menu.tt-bar-triple .tt-mi.tt-state-sliders,
.typetheme .typetheme-menu.tt-bar-triple .tt-mi.tt-state-varfonts {
	flex: 1 1 auto;
	min-width: 0;
}
.typetheme .typetheme-menu.tt-bar-triple .tt-mi:not(.tt-dir-left):not(.tt-dir-right) > .tt-popover {
	position: static;
	/* Breite 0, Inhalt sichtbar: der Stapel bringt seine HÖHE in die Zeile ein
	   (dafür schiebt er alles darüber nach oben), aber KEINE Breite. Sonst
	   würde ein offener Stapel sein .tt-mi so breit machen wie sich selbst und
	   die übrigen Buttons der Zeile zur Seite schieben — in Zeile 1 riss das
	   eine Lücke zwischen OpenType und den Farben. */
	width: 0 !important;
	min-width: 0 !important;
	max-height: none;
	overflow: visible;
	padding: 0 !important;
	clip-path: none !important;
}
/* Fächer im Fluss: die Karten liegen hinter dem Button (Transformation), der
   KASTEN behielte aber seine volle Höhe und risse ein leeres Band über die
   Leiste. Ein negativer oberer Außenabstand nimmt genau den Teil wieder aus
   dem Fluss, der hinter dem Button verschwindet — sichtbar bleibt der
   Überstand der Karten. Beim Aufklappen geht er auf 0: der Stapel beansprucht
   seine volle Höhe und schiebt die Zeilen darüber hoch. Den Wert misst die JS
   (--tt-fan-collapse), die Bewegung nimmt Dauer und Kurve der Karte „List". */
.typetheme .typetheme-menu.tt-bar-triple .tt-mi:not(.tt-dir-left):not(.tt-dir-right) > .tt-popover.tt-fan {
	margin-top: var(--tt-fan-collapse, 0px);
	transition: margin-top var(--tt-anim-dur, 140ms) var(--tt-anim-ease, ease);
}
.typetheme .typetheme-menu.tt-bar-triple .tt-mi:not(.tt-dir-left):not(.tt-dir-right) > .tt-popover.tt-fan.is-open { margin-top: 0; }
.typetheme .typetheme-menu.tt-bar-triple .tt-mi > .tt-popover.tt-fan-still { transition: none; }
.typetheme .typetheme-menu.tt-bar-triple .tt-mi:not(.tt-dir-left):not(.tt-dir-right) > .tt-popover > *:not(.tt-mi) {
	/* Alle Einträge eines Stapels sind so breit wie der Button, an dem er hängt.
	   In CSS allein geht das nicht: der Kasten ist 0 px breit (siehe oben), eine
	   Prozentangabe hätte also nichts, worauf sie sich beziehen könnte. Die JS
	   misst den Button und legt das Maß als --tt-stack-w ab; solange es fehlt,
	   behält der Eintrag seine Eigenbreite. */
	width: var(--tt-stack-w, max-content) !important;
	max-width: none;
	flex: 0 0 auto;
}

/* Die Reglergruppe ist so breit wie ihr Button (--tt-stack-w, siehe oben).
   Die Bahn nimmt darin den freien Platz ein: alles, was Symbolzelle, Zahl und
   Zurücksetzen übriglassen. Eine feste Bahnbreite stand hier, solange die
   Gruppe noch nach Inhalt lief — jetzt bliebe daneben nur Leerraum. */
.typetheme .typetheme-menu.tt-bar-triple .tt-slidergroup { flex: 0 0 auto; }
.typetheme .typetheme-menu.tt-bar-triple .tt-slidergroup > .tt-slider {
	flex: 1 1 auto;
	width: auto;
	min-width: 24px;
}
/* Der freie Platz gehört der Bahn, nicht der Zahl — sonst teilen sich beide
   den Zuwachs und die Bahn bleibt kurz. Die Regel weiter oben (Zahl trägt den
   Rest) gilt für die einreihige Liste, wo die Zeile schmal ist; der lange
   Selektor hier ist nötig, um sie zu schlagen. */
.typetheme .typetheme-menu.tt-bar-triple .tt-mi > .tt-popover > .tt-slidergroup > .tt-val {
	flex: 0 0 auto;
}

/* Ein Stapel, der WAAGERECHT aufklappt, ist von den Fluss-Regeln oben
   ausgenommen: er steht neben seinem Button statt darüber, und seine Breite
   setzt die JS (zu = Überstand, offen = volle Breite). Mobil betrifft das den
   Sets-Button, der als Eintrag IN der OpenType-Liste liegt — nach oben hätte
   er dort keinen Platz. Er darf deshalb auch nicht auf Buttonbreite gestutzt
   werden wie die übrigen Einträge. */
.typetheme .typetheme-menu.tt-bar-triple .tt-mi.tt-dir-left,
.typetheme .typetheme-menu.tt-bar-triple .tt-mi.tt-dir-right {
	width: auto !important;
	flex: 0 0 auto;
}


/* ---- Stilistische Sets: Teil der OpenType-Sektion ------------------------
   Der Sets-Button hängt IM .tt-mi von OpenType und fährt beim Klick auf den
   OT-Button nach RECHTS heraus. Absolut gesetzt, damit er die Spalte aus Button und Stapel nicht
   auseinanderzieht; den Platz hält stattdessen ein linker Innenabstand frei,
   der nur entsteht, solange der Button auch da ist (tt-hat-sets). So wächst
   die OpenType-Sektion in Zeile 1 um genau eine Buttonbreite, statt dass sich
   etwas überlagert. */
.typetheme .typetheme-menu.tt-bar-triple .tt-mi.tt-state-otfeat { position: relative; }
.typetheme .typetheme-menu.tt-bar-triple .tt-mi.tt-state-otfeat.tt-hat-sets {
	padding-right: calc(40px + var(--tt-gap, 2px));
}
.typetheme .typetheme-menu.tt-bar-triple .tt-mi.tt-state-otfeat > .tt-mi.tt-otsets {
	position: absolute;
	right: 0;
	bottom: 0;
}

/* Ausgeblendet heißt ausgeblendet. Sowohl die Fluss-Regel als auch das
   `display:contents` weiter unten geben einem .tt-mi eine eigene Anzeigeart und
   schlagen damit die Browservorgabe für [hidden]. Ohne diese Zeile blieben der
   Sets-Button (dreizeilig) und der Variable-Fonts-Schalter bei einer Schrift
   ohne Achsen (einreihig) sichtbar. */
.typetheme .tt-mi[hidden] { display: none !important; }

/* ==== Einreihige Leiste: Reihenfolge wie vor der Umstellung ==============
   Seit die Zustandsschalter mit ihrem Panel in einem .tt-mi zusammenliegen,
   stünde am Desktop jeder Button direkt vor seinem eigenen Panel — bis dahin
   standen erst alle drei Schalter, dann die drei Panels. `display:contents`
   löst die Klammer für die einreihige Leiste wieder auf, `order` stellt die
   ursprüngliche Folge her:
   Schnitte · Ausrichtung · Layout · Variable Fonts · OpenType · die drei
   Panels · Farben · Invertieren · Zurücksetzen.
   In der dreizeiligen Leiste bleibt die Klammer bestehen — dort trägt sie den
   Fluss-Stapel.
   ======================================================================== */
.typetheme .typetheme-menu:not(.tt-bar-triple) .tt-mi.tt-state { display: contents; }
.typetheme .typetheme-menu:not(.tt-bar-triple) .tt-mi.tt-weight            { order: 1; }
.typetheme .typetheme-menu:not(.tt-bar-triple) .tt-mi.tt-align             { order: 2; }
.typetheme .typetheme-menu:not(.tt-bar-triple) .tt-state-sliders  > .tt-btn { order: 3; }
.typetheme .typetheme-menu:not(.tt-bar-triple) .tt-state-varfonts > .tt-btn { order: 4; }
.typetheme .typetheme-menu:not(.tt-bar-triple) .tt-state-otfeat   > .tt-btn { order: 5; }
.typetheme .typetheme-menu:not(.tt-bar-triple) .tt-panel-layout            { order: 6; }
.typetheme .typetheme-menu:not(.tt-bar-triple) .tt-panel-varfonts          { order: 7; }
.typetheme .typetheme-menu:not(.tt-bar-triple) .tt-panel-opentype          { order: 8; }
.typetheme .typetheme-menu:not(.tt-bar-triple) .tt-mi.tt-bgcolor           { order: 9; }
.typetheme .typetheme-menu:not(.tt-bar-triple) > .tt-mi.tt-invert-mi       { order: 10; }
.typetheme .typetheme-menu:not(.tt-bar-triple) > .tt-mi.tt-reset-mi        { order: 11; }

