/*
Theme Name: Frank Vohle · Didaktikbüro
Theme URI: https://frank-vohle.de
Author: Didaktikbüro Hamburg
Description: Child-Theme von Twenty Twenty-Four für frank-vohle.de. Bringt Farben, Schriften und
  Layout der zusammengeführten Seite mit. Farben und Typografie stehen in theme.json, hier steht
  nur, was sich dort nicht ausdrücken lässt.
Template: twentytwentyfour
Version: 1.21.12
Requires at least: 6.5
Tested up to: 7.0
Requires PHP: 8.0
License: GNU General Public License v2 or later
License URI: http://www.gnu.org/licenses/gpl-2.0.html
Text Domain: frank-vohle
*/

/* =========================================================================
   Grundlagen
   ========================================================================= */

/* Archivo Black ist sehr breit laufend. Ohne Silbentrennung sprengen lange
   deutsche Komposita ("Transformationshelfer") auf schmalen Displays die
   Seitenbreite und erzeugen horizontales Scrollen. */
h1,
h2,
h3,
h4,
.wp-block-post-title {
	overflow-wrap: break-word;
	hyphens: auto;
}

/* Im Fließtext stehen vereinzelt nackte URLs als Linktext — auf /publikationen/
   eine mit 105 Zeichen am Stück. Ohne Umbruchpunkt schiebt so ein "Wort" die
   Seite auf schmalen Displays über die Bildschirmbreite hinaus und erzeugt
   horizontales Scrollen. `break-word` bricht nur, wenn die Zeile sonst
   überliefe — am Desktop-Satz ändert sich dadurch nichts. Die Eigenschaft
   vererbt sich, erfasst also auch die Links darin. */
.wp-block-post-content {
	overflow-wrap: break-word;
}

/* =========================================================================
   Zitate und Listen

   Das Dreieck ist im verbindlichen Prototyp Bestandteil des Logos, kein
   Textschmuck. Es steht deshalb nur noch dort, wo es ausdrücklich gewählt
   wird: im Block-Stil „Dreieck" für Listen.
   ========================================================================= */

/* Zitate: schlicht und konventionell — feine Linie links, eingerückt, Text
   leicht zurückgenommen.

   Ohne Dreieck. Im verbindlichen Prototyp kommt das Dreieck ausschließlich als
   Bestandteil des Logos vor (`.logo-mark .tri`, `.corner-logo .tri`); es ist
   dort kein Textmarker, und Zitate gibt es im Entwurf gar nicht. Es an Zitate
   zu hängen war eine eigene Zutat, die keiner Vorgabe entspricht.

   Der Innenabstand wird auf allen vier Seiten gesetzt, nicht nur links: TT4
   legt über theme.json eine Kachel um Zitate — Hintergrund, runde Ecken und
   ringsum Polsterung. Der Hintergrund greift hier ins Leere, weil unsere
   Palette kein `base-2` kennt, die Polsterung aber sehr wohl. Wird nur
   `padding-left` überschrieben, bleibt der obere Abstand stehen.

   Drei der alten Beiträge enthalten ein nacktes `<blockquote>` ohne
   Block-Klasse, neun die Block-Fassung. Beide Formen stehen deshalb im
   Selektor — das bloße `blockquote` allein zählt zu schwach und verlöre gegen
   die TT4-Regel, sobald die Klasse doch da ist. */
blockquote,
.wp-block-quote,
blockquote.wp-block-quote {
	margin: var(--wp--preset--spacing--40) 0;
	padding: 0 0 0 var(--wp--preset--spacing--30);
	border: 0;
	border-left: 2px solid var(--wp--preset--color--line);
	border-radius: 0;
	background: none;
	font-style: italic;
	color: var(--wp--preset--color--contrast-soft);
}

/* Enthält das Zitat einen Absatz-Block statt bloßem Text, säßen dessen
   Außenabstände sonst innerhalb der Einrückung. */
blockquote > :first-child {
	margin-top: 0;
}

blockquote > :last-child {
	margin-bottom: 0;
}

/* Listen im Fließtext: normale Einrückung, Punkte innerhalb der Textspalte.

   Warum das nötig ist: TT4 setzt Listen `padding-left:
   var(--wp--preset--spacing--10)`. Unsere Abstandsskala begann aber erst bei
   `20` — die Variable war undefiniert, die Deklaration damit ungültig, und
   `padding-left` fiel auf den Anfangswert 0 zurück. Die Aufzählungspunkte
   standen dadurch bündig am Text statt eingerückt. In theme.json ist die Stufe
   `10` inzwischen ergänzt; hier steht der eigentliche Leseabstand, denn 0.5rem
   reichen nicht, um Punkt und Text sauber zu trennen.

   `:where()` hält den Selektor niedrig, die `:not()` nehmen zwei Listen aus:
   die Dreiecksliste, die ihre Einrückung selbst setzt, und die Beitragsschleife
   `wp-block-post-template`. Letztere ist technisch eine <ul>, aber inhaltlich
   eine Beitragsliste — auf /projekte/ liegt sie im Seiteninhalt, wodurch diese
   Regel dort Aufzählungspunkte vor jedes Projekt gesetzt hat. Der Core stellt
   sie auf `list-style: none`, verliert aber gegen den spezifischeren Selektor
   hier.
   Gilt für Übersicht und Einzelseite gleichermaßen, weil beide denselben
   Inhaltsblock verwenden. */
.wp-block-post-content :where(ul, ol):not(.is-style-tri-list):not(.wp-block-post-template) {
	padding-left: 1.6rem;
}

/* Aufzählungszeichen ausdrücklich je Ebene setzen, gemessen ab dem Inhalt.

   Nötig, weil die Blogübersicht den Beitrag in eine Hülle steckt: Der
   Query-Loop rendert als `<ul class="wp-block-post-template">` mit einem <li>
   je Beitrag. Jede Liste im Beitragstext liegt dort also innerhalb einer <ul>
   und fällt unter die Browserregel `ul ul { list-style-type: circle }` — hohler
   Kreis. Auf der Einzelseite fehlt die Hülle, dieselbe Liste ist erste Ebene
   und bekommt den gefüllten Punkt. Dieselben Beiträge sahen dadurch an zwei
   Stellen unterschiedlich aus.

   Die Hülle liegt außerhalb von `.wp-block-post-content`, kann also nicht als
   mittleres `ul` in diesen Selektoren dienen — die Zählung beginnt damit
   verlässlich beim Inhalt. Das `:not()` steht auf allen drei Ebenen, damit sie
   dieselbe Spezifität-Stufung behalten und die tiefere jeweils gewinnt. */
.wp-block-post-content ul:not(.is-style-tri-list):not(.wp-block-post-template) {
	list-style-type: disc;
}

.wp-block-post-content ul ul:not(.is-style-tri-list):not(.wp-block-post-template) {
	list-style-type: circle;
}

.wp-block-post-content ul ul ul:not(.is-style-tri-list):not(.wp-block-post-template) {
	list-style-type: square;
}

/* Optionale Listenvariante, im Editor als Block-Stil "Dreieck" wählbar */
ul.is-style-tri-list {
	list-style: none;
	padding-left: 0;
}

ul.is-style-tri-list li {
	position: relative;
	padding-left: 20px;
	margin-bottom: 8px;
}

/* Das Dreieck sitzt mittig zur ersten Textzeile: halbe Zeilenhöhe minus halbe
   Dreieckshöhe (10px). `lh` rechnet mit der tatsächlichen Zeilenhöhe und hält
   die Ausrichtung auch bei abweichender Schriftgröße; der em-Wert davor ist der
   Rückfall für ältere Browser und entspricht der Grund-Zeilenhöhe 1.6. */
ul.is-style-tri-list li::before {
	content: "";
	position: absolute;
	left: 0;
	top: calc(0.8em - 5px);
	top: calc(0.5lh - 5px);
	width: 0;
	height: 0;
	border-top: 5px solid transparent;
	border-bottom: 5px solid transparent;
	border-left: 8px solid var(--wp--preset--color--amber);
}

/* =========================================================================
   Header
   ========================================================================= */

.fv-header {
	border-bottom: 3px solid var(--wp--preset--color--rule);
}

/* Wortmarke und Logo bewusst etwas kräftiger als der Prototyp: bei 1rem und
   200px wirkte die Kopfzeile zerbrechlich. Der Zuwachs ist so bemessen, dass
   Marke, Trenner, Logo und die fünf Menüpunkte bei 1024px noch nebeneinander
   passen — darüber liegt der Umschaltpunkt zum Burger. */
.fv-brand-name {
	font-family: var(--wp--preset--font-family--archivo-black);
	font-size: 1.05rem;
	letter-spacing: -0.01em;
	text-decoration: none;
	white-space: nowrap;
}

.fv-brand-divider {
	display: inline-block;
	width: 1px;
	height: 22px;
	background: var(--wp--preset--color--rule);
	flex-shrink: 0;
}

/* Das Logo ist 864x71 - ohne Deckelung würde es die Kopfzeile sprengen.

   `aspect-ratio` ist hier kein Schmuck, sondern behebt einen Sprung beim Laden:
   Die SVG-Datei trägt nur einen `viewBox` und keine `width`/`height`. Mit
   `height: auto` kennt der Browser das Seitenverhältnis deshalb erst, wenn die
   Datei da ist — bis dahin steht die Höhe nicht fest und die Kopfzeile ruckt
   beim Nachladen zurecht. Das Verhältnis aus dem viewBox (864.57 : 70.87) hier
   anzugeben reserviert die Höhe von Anfang an. */
.fv-logo img,
.fv-logo .custom-logo {
	width: 230px;
	max-width: 100%;
	height: auto;
	aspect-ratio: 864.57 / 70.87;
	/* Gurt und Hosenträger: Die Maße stehen bereits als width/height am <img>
	   (siehe frank_vohle_logo_dimensions in functions.php) und wirken damit
	   sofort. Falls das Attribut einmal ausfällt - anderes Logo, geänderter
	   Core -, deckelt dies die Darstellung, bevor unser Stylesheet greift. */
	contain-intrinsic-size: 230px 19px;
}

/* Die Kopfzeile in einer Zeile, ohne Zucken beim Laden.

   Drei Dinge greifen hier ineinander:

   1. `nowrap` — sonst rutscht der Menüknopf auf schmalen Displays unter die
      Wortmarke.
   2. `column-gap` — `space-between` verteilt nur den Rest. Ist die Zeile fast
      ausgefüllt, rücken Logo und Menü aneinander und „HH" klebt an „BLOG".
   3. `flex-shrink: 0` auf allen Kindern — ohne das gibt das Logo nach, sobald
      die Zeile rechnerisch eng wird. Eng ist sie genau in dem Moment, in dem
      die Seite noch nicht fertig formatiert ist: Das Menü trägt dann die
      Grundschrift statt 0.78rem Versalien und ist spürbar breiter. Das Logo
      wich aus und sprang eine Zehntelsekunde später zurück — das war das
      sichtbare Zucken beim Navigieren. Wird es auf schmalen Fenstern wirklich
      eng, greifen die Bruchpunkte weiter unten.

   Dieselben Werte stehen zusätzlich im kritischen CSS (functions.php), damit
   sie schon vor diesem Stylesheet feststehen. Änderungen bitte an beiden
   Stellen. */
.fv-header .wp-block-group.alignwide.is-layout-flex {
	flex-wrap: nowrap;
	column-gap: var(--wp--preset--spacing--50);
}

.fv-header .wp-block-group.alignwide > .wp-block-group:first-child,
.fv-header .fv-logo,
.fv-header .fv-brand-name,
.fv-header .fv-nav {
	flex-shrink: 0;
}


@media (max-width: 781px) {
	.fv-logo img,
	.fv-logo .custom-logo {
		width: 190px;
	}
}

@media (max-width: 480px) {
	.fv-brand-name {
		font-size: 0.95rem;
	}

	.fv-logo img,
	.fv-logo .custom-logo {
		width: 150px;
	}
}

/* =========================================================================
   Navigation
   ========================================================================= */

/* Mit der größeren Wortmarke (1.2rem) wirkten 0.78rem im Menü zu leicht.
   0.76rem: Versalien lesen sich optisch größer als gemischte Schrift, das Menü
   bleibt damit lesbar, ohne mit Marke und Logo zu konkurrieren. Die kleinere
   Stufe gibt Breite frei — die geht ans Logo, das mit 320px der eigentliche
   Blickfang der Kopfzeile ist. */
.fv-nav .wp-block-navigation-item__label {
	font-family: var(--wp--preset--font-family--archivo);
	font-weight: 700;
	font-size: 0.78rem;
	letter-spacing: 0.02em;
	text-transform: uppercase;
}

/* Aktiver Punkt: Unterstreichung in Amber. Die Klasse setzt
   `frank_vohle_mark_active_nav()` in functions.php — WordPress kann das bei
   freien Links nicht selbst.

   Der Rahmen liegt auf *allen* Punkten, beim inaktiven nur durchsichtig. Wäre
   er nur am aktiven gesetzt, wäre dieser Punkt 4px höher als die übrigen — die
   ganze Kopfzeile würde mitwachsen und die Trennlinie darunter verspringen,
   je nachdem welche Seite gerade offen ist. So bleibt die Höhe konstant und
   nur die Farbe wechselt. */
.fv-nav .wp-block-navigation-item > a,
.fv-nav .wp-block-navigation-item > .wp-block-navigation-item__content {
	border-bottom: 2px solid transparent;
	padding-bottom: 2px;
}

.fv-nav .wp-block-navigation-item.current-menu-item > a,
.fv-nav .wp-block-navigation-item.current-menu-item > .wp-block-navigation-item__content,
.fv-nav .wp-block-navigation-item[aria-current="page"] > a {
	color: var(--wp--preset--color--amber-deep);
	border-bottom-color: var(--wp--preset--color--amber-deep);
}

/* Im Untermenü und im Mobil-Overlay trägt eine Unterstreichung nicht — dort
   trennen eigene Linien, und die Kästen sind schmal. Nur die Farbe bleibt. */
.fv-nav .wp-block-navigation__submenu-container .wp-block-navigation-item > a,
.fv-nav .is-menu-open .wp-block-navigation-item > a,
.fv-nav .is-menu-open .wp-block-navigation-item > .wp-block-navigation-item__content {
	border-bottom: 0;
}

/* Untermenüs: im Prototyp bewusst kantig statt abgerundet.
   Der Klassen-Doppelgriff ist nötig, weil die Core-Regel für den Rahmen sonst
   bei gleicher Spezifität gewinnt. */
.fv-nav.wp-block-navigation .wp-block-navigation__submenu-container {
	border: 1.5px solid var(--wp--preset--color--rule);
	border-radius: 0;
	box-shadow: 0 8px 20px rgba(0, 0, 0, 0.08);
	padding: 8px 0;
}

.fv-nav .wp-block-navigation__submenu-container .wp-block-navigation-item__label {
	text-transform: none;
	font-size: 0.76rem;
	font-weight: 600;
}

/* -------------------------------------------------------------------------
   Umschaltpunkt zum Burger

   Der Navigation-Block wechselt von Haus aus erst bei 600px ins Overlay. Mit
   fünf Punkten plus Wortmarke und Logo wird es aber schon deutlich früher eng -
   der erste Punkt schiebt sich dann über den Trenner. Mit der größeren Marke
   (1.2rem), dem breiteren Logo (230px) und dem größeren Menü (0.86rem) braucht
   die Kopfzeile rund 1010px, deshalb jetzt 1080px statt 1024px.
   ------------------------------------------------------------------------- */

@media (max-width: 1080px) {
	.fv-nav .wp-block-navigation__responsive-container-open:not(.always-shown) {
		display: flex;
	}

	.fv-nav .wp-block-navigation__responsive-container:not(.is-menu-open) {
		display: none;
	}
}

/* -------------------------------------------------------------------------
   Mobil-Overlay: eine Liste, keine schwebenden Kästchen.
   ------------------------------------------------------------------------- */

.fv-nav .is-menu-open .wp-block-navigation__container {
	gap: 0;
	width: 100%;
}

/* Trennlinie je Hauptpunkt. Bei Punkten mit Untermenü umschließt das <li> die
   ganze Gruppe, die Linie sitzt also korrekt unter dem letzten Unterpunkt. */
.fv-nav .is-menu-open .wp-block-navigation__container > .wp-block-navigation-item {
	width: 100%;
	padding: 0;
	border-bottom: 1px solid var(--wp--preset--color--line);
}

/* Punkte mit Untermenü sind drei Geschwister: Link, Pfeil-Knopf, Unterliste.
   Link und Pfeil in eine Zeile, die Liste bekommt eine eigene. */
.fv-nav .is-menu-open .wp-block-navigation__container > .wp-block-navigation-item.has-child {
	flex-direction: row;
	flex-wrap: wrap;
	align-items: center;
}

.fv-nav .is-menu-open .wp-block-navigation__container > .wp-block-navigation-item > .wp-block-navigation-item__content {
	display: flex;
	align-items: center;
	flex: 1 1 auto;
	padding: 0.72rem 0;
	color: var(--wp--preset--color--contrast);
}

.fv-nav .is-menu-open .wp-block-navigation__container > .wp-block-navigation-item > .wp-block-navigation-item__content .wp-block-navigation-item__label {
	font-size: 0.95rem;
	font-weight: 700;
	text-transform: uppercase;
	letter-spacing: 0.03em;
}

/* WordPress blendet den Aufklapp-Knopf im Overlay aus und zeigt die Untermenüs
   stattdessen dauerhaft. Wir holen den Knopf zurück: er trägt bereits
   data-wp-on--click und pflegt aria-expanded, taugt also unverändert als
   Akkordeon-Schalter. Der Elternpunkt bleibt daneben ein echter Link und führt
   weiter auf seine Seite. */
.fv-nav.wp-block-navigation .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__submenu-icon {
	display: flex;
	align-items: center;
	justify-content: center;
	flex: 0 0 auto;
	margin-left: auto;
	/* Quadratische Trefferfläche: so umschließt der Fokusrahmen den Pfeil,
	   statt als leerer Kasten daneben zu stehen. 44px ist das übliche Mindestmaß
	   für Touch. */
	width: 44px;
	height: 36px;
	padding: 0;
	background: none;
	border: 0;
	color: var(--wp--preset--color--contrast);
	cursor: pointer;
}

/* Ohne feste Maße fällt das Icon im Flex-Knopf auf Breite 0 zusammen. */
.fv-nav .is-menu-open .wp-block-navigation__submenu-icon svg {
	flex: 0 0 auto;
	width: 14px;
	height: 14px;
	fill: currentColor;
	transition: transform 0.2s;
}

.fv-nav .is-menu-open .wp-block-navigation__submenu-icon[aria-expanded="true"] svg {
	transform: rotate(180deg);
}

/* Offen ist der Normalfall. Die Klasse fv-collapsed setzt assets/js/nav.js,
   zusammen mit aria-expanded - siehe dort, warum nicht über WordPress' Zustand. */
.fv-nav .is-menu-open .wp-block-navigation__container > .has-child > .wp-block-navigation__submenu-container {
	display: flex;
	flex: 0 0 100%;
}

.fv-nav .is-menu-open .wp-block-navigation__container > .has-child.fv-collapsed > .wp-block-navigation__submenu-container {
	display: none;
}

.fv-nav .is-menu-open .wp-block-navigation__submenu-container {
	border: 0;
	box-shadow: none;
	background: transparent;
	padding: 0 0 0.35rem 0.7rem;
	width: 100%;
}

/* Unterpunkte bewusst ruhiger: normale Schrift, keine Versalien. */
.fv-nav .is-menu-open .wp-block-navigation__submenu-container .wp-block-navigation-item {
	border: 0;
}

.fv-nav .is-menu-open .wp-block-navigation__submenu-container a {
	padding: 0.42rem 0;
	color: var(--wp--preset--color--contrast);
}

.fv-nav .is-menu-open .wp-block-navigation__submenu-container .wp-block-navigation-item__label {
	font-size: 0.9rem;
	font-weight: 400;
	text-transform: none;
	letter-spacing: 0;
}

/* =========================================================================
   Wiederkehrende Bausteine aus dem Prototyp
   ========================================================================= */

/* Grünes Label über Abschnittsüberschriften */
.fv-tag-label {
	display: inline-block;
	background: var(--wp--preset--color--green-deep);
	color: var(--wp--preset--color--base);
	font-family: var(--wp--preset--font-family--archivo);
	font-weight: 700;
	font-size: 0.69rem;
	letter-spacing: 0.05em;
	text-transform: uppercase;
	padding: 5px 12px;
	margin-bottom: 12px;
}

/* Beide Knöpfe gleich groß.

   Zwei Ursachen, beide vom Umriss-Stil:
   1. Der Core setzt `padding:.667em 1.333em` — bei Schriftgröße „klein" (13px)
      sind das 8,7/17,3px statt der 13/22px aus theme.json.
   2. WordPress erzeugt für den Knopf zusätzlich die Stilvariante
      `is-style-outline--2` mit `border-width: 1px`, während der gefüllte Knopf
      die 2px aus theme.json trägt. Das allein macht 2px Höhenunterschied.

   Beide Regeln stecken in `:root :where(…)` und zählen deshalb nur einfach;
   der Selektor hier ist spezifischer und setzt Polsterung und Rahmen gleich.

   Der erste Selektor kommt ohne `wp-element-button` aus. Diese Klasse hängt
   WordPress erst beim Ausliefern an — im Block-Editor fehlt sie, weshalb die
   Regel dort nicht griff und der Umriss-Knopf anders aussah als auf der Seite.
   Beide Fassungen stehen bewusst da: die zweite hält die höhere Spezifität für
   den Fall, dass eine Core-Regel dazwischenfunkt.

   Rahmenfarbe und Textfarbe stehen ebenfalls hier und nicht mehr am Block. Im
   Block hinterlegt erzeugten sie einen ungültigen Block: Die Attribute
   verlangten eine Klasse `has-border-color`, die im gespeicherten Markup fehlte
   — der Editor meldete daraufhin „unerwarteter oder ungültiger Inhalt". Im
   Stylesheet gibt es das Problem nicht, und das Markup bleibt schlicht. */
/* Der gefüllte Knopf behält seine Farben auch im Editor.

   theme.json legt Hintergrund und Schrift über `:root :where(.wp-element-button,
   .wp-block-button__link)` fest — eine Regel mit sehr schwacher Spezifität. Auf
   der Seite genügt das, im Editor nicht: Sobald der Knopf zum Bearbeiten
   angeklickt wird, überschreibt der Editor den Hintergrund, und die weiße
   Schrift steht auf Weiß. Man sieht den Text dann nur noch, solange er markiert
   ist.

   Hier stehen dieselben Werte mit tragfähiger Spezifität. Kein `!important`:
   Wählt jemand im Editor eine eigene Farbe, landet die als Inline-Stil am
   Element und gewinnt weiterhin. */
.wp-block-button:not(.is-style-outline) > .wp-block-button__link {
	background-color: var(--wp--preset--color--amber-deep);
	color: var(--wp--preset--color--base);
}

.wp-block-button.is-style-outline > .wp-block-button__link,
.wp-block-button.is-style-outline > .wp-block-button__link.wp-element-button {
	padding: 13px 22px;
	border: 2px solid var(--wp--preset--color--rule);
	color: var(--wp--preset--color--contrast);
	background-color: transparent;
}

/* Sobald die Knöpfe untereinander rutschen, sähen unterschiedlich breite Kästen
   nach Versehen aus. Dann nehmen beide die volle Breite. */
@media (max-width: 480px) {
	.wp-block-buttons > .wp-block-button {
		width: 100%;
	}

	.wp-block-buttons > .wp-block-button > .wp-block-button__link {
		display: block;
		text-align: center;
	}
}

/* Dicke Trennlinie über Listen, wie im Prototyp */
.fv-rule-top {
	border-top: 2px solid var(--wp--preset--color--rule);
}

/* Beitragsliste: Datum links, Text rechts */
.fv-post-row {
	border-bottom: 1px solid var(--wp--preset--color--line);
}

/* Blog als Journal: vollständige Beiträge untereinander statt Anrisse.
   Das alte Zweispalter-Layout (Datum in fester 110px-Spalte links) trägt nur
   Anrisse; neben einem kompletten Artikel steht das Datum sonst verloren oben
   in der Ecke. Deshalb hier gestapelt: Datum, Titel, Text — je über die volle
   Textbreite, getrennt durch eine feine Linie. */
.fv-journal-entry {
	border-bottom: 1px solid var(--wp--preset--color--line);
}

/* Innerhalb eines Eintrags sitzen die Überschriften der Beiträge selbst
   (h2 im Fließtext der alten Beiträge) sonst zu dicht am Titel. */
.fv-journal-entry .wp-block-post-content > :first-child {
	margin-top: 0;
}

/* Sprungleiste der Publikationen: 13 Abschnitte auf einer sehr langen Seite.
   Gleiche Anmutung wie die Jahresliste im Blog — beides ist Wegweiser, kein
   Fließtext. Der Trenner „·" steht im Text, deshalb hier nur Farbe und Abstand. */
.fv-pub-nav {
	line-height: 2;
	color: var(--wp--preset--color--muted);
	margin-bottom: var(--wp--preset--spacing--30);
}

.fv-pub-nav a {
	font-weight: 700;
	color: var(--wp--preset--color--muted);
	text-decoration: none;
}

.fv-pub-nav a:hover,
.fv-pub-nav a:focus-visible {
	color: var(--wp--preset--color--amber-deep);
	text-decoration: underline;
}

/* Anker-Sprünge sollen nicht unter der Kopfzeile landen */
:target {
	scroll-margin-top: var(--wp--preset--spacing--40);
}

/* Suche: vorhanden, aber leise.

   Sie wird selten gebraucht — als Feld über die volle Satzbreite mit großem
   Knopf drängt sie sich vor die Beiträge. Deshalb auf Eingabebreite gedeckelt,
   feine Linie statt kräftigem Rahmen und ein Knopf im Maß der Jahreszahlen. */
.wp-block-search {
	max-width: 330px;
}

.wp-block-search .wp-block-search__inside-wrapper {
	border: 1px solid var(--wp--preset--color--line);
}

.wp-block-search .wp-block-search__input {
	border: 0;
	padding: 7px 10px;
	font-size: 0.8125rem;
}

.wp-block-search .wp-block-search__button {
	padding: 7px 14px;
	font-size: 0.75rem;
	border-width: 0;
}

/* Jahresliste als Journal-Navigation: eine Zeile Jahreszahlen statt
   Kategorien. Der Kern-Block „Archive" liefert die Liste, hier wird sie nur
   waagerecht gelegt. Die Klasse sitzt am `ul` selbst, nicht an einer Hülle. */
ul.fv-year-list {
	list-style: none;
	margin: 0;
	padding-left: 0;
	display: flex;
	flex-wrap: wrap;
	gap: 6px 18px;
}

.fv-year-list a {
	font-weight: 700;
	font-size: 0.8125rem;
	color: var(--wp--preset--color--muted);
	text-decoration: none;
}

.fv-year-list a:hover,
.fv-year-list a:focus-visible {
	color: var(--wp--preset--color--amber-deep);
	text-decoration: underline;
}

.fv-post-date {
	font-weight: 700;
	font-size: 0.75rem;
	color: var(--wp--preset--color--muted);
}

/* Rasterzellen mit feinen Innenlinien (Leistungen, Statement-Grid) */
.fv-grid-cell {
	border-right: 1px solid var(--wp--preset--color--line);
	border-bottom: 1px solid var(--wp--preset--color--line);
	padding: 22px 20px;
}

/* Die rechte Linie trennt Zellen voneinander - hinter der letzten Zelle einer
   Reihe hat sie nichts mehr zu trennen und stünde nur als Rand am Rand des
   Rasters. Der Prototyp lässt sie dort ausdrücklich weg (.q:last-child). Gilt
   für das Statement-Raster; das Leistungen-Raster regelt seine eigene letzte
   Zelle spezifischer weiter unten. */
.fv-grid-cell:last-child {
	border-right: 0;
}

/* Sobald die Spalten untereinander stehen, ist die rechte Linie ohnehin eine
   Linie ins Nichts - dann trennt nur noch die untere. Gilt für das
   Statement-Raster, das auf dem Spalten-Block sitzt und beim Core-Bruchpunkt
   781px umbricht. */
@media (max-width: 781px) {
	.fv-grid-cell {
		border-right: 0;
	}
}

/* Leistungen: fünf Zellen statt vier.

   Fünf nebeneinander gehen bei 900px Satzbreite nicht auf — 180px pro Spalte
   abzüglich Innenabstand lassen 140px Text, „Bildungstechnologien" braucht in
   Archivo Black rund 240px. Deshalb ein Raster mit 260px Mindestbreite: drei
   Spalten am Schreibtisch, zwei auf dem Tablet, eine auf dem Handy. Die letzte
   Zelle spannt über zwei Spalten, damit die Reihe schließt und kein
   angeschnittenes Feld stehen bleibt.

   Die Bruchpunkte sind gerechnet, nicht geraten: Satzbreite ist
   min(900px, Fenster − 56px Randabstand), Spalten = abgerundet Breite/260.

   Der Prototyp umschließt die Leistungen als geschlossenen Kasten: oben und
   links je eine Linie am Raster selbst (`.services`), rechts und unten hält
   jede Zelle ihre eigene Linie (`.svc`) - ohne Ausnahme für die letzte Spalte
   einer Reihe. Dadurch schließt bei jeder Spaltenzahl automatisch die
   rechteste Zelle einer Reihe den Kasten nach rechts, ganz gleich ob drei,
   zwei oder eine Spalte nebeneinanderstehen - dasselbe Geviert, das der Punkt
   „saubere Rahmen" bei /leistungen/ einforderte. Frühere Fassungen strichen
   die rechte Linie eigens am Zeilenende (nth-child, :last-child) und rissen
   damit die rechte Kastenwand auf - genau die Lücke, die hier zu sehen war.
   Die Randlinie ist dieselbe Zeile am Bildschirm, egal wie viele Zellen eine
   Reihe füllt - `border-left` am Raster reicht. */
.fv-service-grid {
	border-left: 1px solid var(--wp--preset--color--line);
}

.fv-service-grid .fv-grid-cell {
	border-right: 1px solid var(--wp--preset--color--line);
}

/* ab zwei Spalten schließt die letzte Zelle die Reihe */
@media (min-width: 576px) {
	.fv-service-grid .fv-grid-cell:last-child {
		grid-column: span 2;
	}
}

.fv-grid-cell .fv-num {
	font-family: var(--wp--preset--font-family--archivo-black);
	font-size: 1.35rem;
	color: var(--wp--preset--color--green);
	-webkit-text-stroke: 1px var(--wp--preset--color--contrast);
}

/* DOI-Knopf der Schriftenreihe */
.fv-doi a {
	display: inline-block;
	border: 2px solid var(--wp--preset--color--rule);
	padding: 6px 12px;
	font-weight: 700;
	font-size: 0.69rem;
	color: var(--wp--preset--color--amber-deep);
	text-decoration: none;
	white-space: nowrap;
}

.fv-doi a:hover,
.fv-doi a:focus {
	background: var(--wp--preset--color--contrast);
	color: var(--wp--preset--color--base);
}

/* Swoosh unter einem Wort in der Hero-Überschrift */
.fv-swoosh {
	position: relative;
	display: inline-block;
	max-width: 100%;
}

/* Auf schmalen Displays trägt der Schwung nicht mehr: das SVG liegt absolut über
   dem ganzen Kasten und zöge bei getrennten Silben eine Linie quer über beide
   Zeilen. Statt seiner tritt dort eine echte Unterstreichung an — die folgt dem
   Umbruch und trennt sauber mit. Stärke und Farbe entsprechen dem Schwung:
   Strichbreite 7 von 40 Einheiten auf 0.5em Höhe sind rund 0.09em. */
@media (max-width: 600px) {
	.fv-swoosh {
		display: inline;
	}

	.fv-swoosh::after {
		display: none;
	}

	.fv-swoosh,
	.fv-swoosh > span {
		text-decoration: underline;
		text-decoration-color: var(--wp--preset--color--green);
		text-decoration-thickness: 0.09em;
		text-underline-offset: 0.1em;
		text-decoration-skip-ink: none;
	}
}

/* Der Schwung liegt im CSS, nicht im Text.

   Ursprünglich stand ein <svg> direkt in der Überschrift. Das war nicht
   überlebensfähig: Überschriften-Blöcke lassen nur bestimmte Auszeichnungen zu,
   der Editor entfernt alles andere beim Speichern. Als Frank die Zeile
   umformulierte, war der Schwung deshalb weg - und die verschachtelten <span>
   meldete der Editor als unerwarteten Inhalt.

   Jetzt zeichnet ein Hintergrundbild den Schwung. Es hängt nur noch an der
   Klasse `fv-swoosh`; der Text darin darf beliebig geändert werden. Die Kurve
   ist dieselbe wie vorher (M6,26 C90,10 250,6 394,20), `preserveAspectRatio`
   bleibt aus, damit sie sich auf die Wortbreite streckt. */
.fv-swoosh::after {
	content: "";
	position: absolute;
	left: -3%;
	bottom: -0.12em;
	width: 106%;
	height: 0.5em;
	background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 400 40' preserveAspectRatio='none'%3E%3Cpath d='M6,26 C90,10 250,6 394,20' stroke='%236B9E4E' stroke-width='7' stroke-linecap='round' fill='none'/%3E%3C/svg%3E") no-repeat center / 100% 100%;
	pointer-events: none;
}

/* =========================================================================
   Barrierefreiheit
   ========================================================================= */

/* Fokusring: sichtbar für die Tastatur, unsichtbar für Maus und Touch.

   Twenty Twenty-Four legt über theme.json die Regel
   `:where(.wp-site-blocks *:focus){outline-width:2px;outline-style:solid}` auf
   *jedes* :focus — ohne Farbangabe, also in der Textfarbe (Tinte, #1C1C1A).
   Weil sie an :focus hängt und nicht an :focus-visible, erscheint der schwarze
   Rahmen auch beim Antippen auf dem Handy und beim Mausklick, wo er nichts
   nützt. Die Regel steht in :where() und hat damit die Spezifität null, lässt
   sich hier also überschreiben, ohne an TT4 selbst zu rühren.

   Für Maus und Touch wird der Rahmen entfernt, für die Tastatur bleibt er —
   dort trägt er, und ohne ihn wäre nicht erkennbar, wo man gerade steht. */
*:focus:not(:focus-visible) {
	outline: none;
}

*:focus-visible {
	outline: 2px solid var(--wp--preset--color--amber-deep);
	outline-offset: 2px;
}

/* -------------------------------------------------------------------------
   Mobil-Overlay: passt auf einen Bildschirm

   Die Punkte sind kompakt genug, dass Haupt- und Untermenüs zusammen auf ein
   übliches Handydisplay passen. Falls es doch eng wird - kleines Gerät, quer
   gehaltenes Telefon, vergrößerte Schrift im Betriebssystem -, soll die Liste
   senkrecht scrollen statt aus dem Bild zu laufen. Waagerecht darf sie nie
   scrollen, deshalb `overflow-x: hidden`.

   `100dvh` statt `100vh`: Auf dem Handy wachsen und schrumpfen die Browser-
   leisten beim Scrollen. `vh` rechnet mit der größten Höhe, das Menü wäre
   dadurch unten abgeschnitten; `dvh` folgt der tatsächlich sichtbaren Höhe.
   ------------------------------------------------------------------------- */
.fv-nav .wp-block-navigation__responsive-container.is-menu-open {
	max-height: 100dvh;
	overflow-x: hidden;
	overflow-y: auto;
	overscroll-behavior: contain;
}

/* Der innere Bereich darf nicht selbst eine zweite Bildlaufleiste aufmachen. */
.fv-nav .is-menu-open .wp-block-navigation__responsive-container-content {
	overflow: visible;
}


/* ---------------------------------------------------------------------------
   Hero mit Portrait
   ---------------------------------------------------------------------------
   Der Bold-Prototyp sieht rechts neben der Überschrift einen Fotoplatz vor:
   280 px breit, Seitenverhältnis 4:5, 3 px Rahmen in der starken Trennlinie
   ("warm, nahbar, im Alltag statt Studio").

   Die Spaltenbreite steckt im Blockmarkup (flex-basis:280px), damit Frank sie
   im Editor sieht und verschieben kann. Hier steht nur, was der Editor nicht
   abbildet: Abstand, Ausrichtung, Rahmen.
   -------------------------------------------------------------------------- */

.fv-hero-grid {
	gap: var(--wp--preset--spacing--50);   /* 2.5rem = 40 px, wie im Entwurf */
	align-items: start;                    /* Foto oben bündig, nicht gedehnt */
}

.fv-portrait {
	margin: 0;
}

.fv-portrait img {
	display: block;
	width: 100%;
	height: auto;
	/* Die Datei ist bereits auf 4:5 beschnitten. Die Angabe hält den Platz
	   frei, solange das Bild lädt - sonst springt der Hero nach. */
	aspect-ratio: 4 / 5;
	object-fit: cover;
	border: 3px solid var(--wp--preset--color--rule);
}

/* Einspaltig stapeln die Blockspalten von selbst (Core ab 781 px). Die feste
   Entwurfsbreite von 280px passt zur zweispaltigen Desktop-Ansicht, lässt auf
   schmalen Bildschirmen aber eine Lücke neben dem Bild stehen. Dort füllt das
   Portrait stattdessen die Textspalte - bei 4:5 bleibt es dabei angemessen
   hoch (bei 340px Spaltenbreite z. B. 425px). */
@media (max-width: 781px) {
	.fv-hero-grid .fv-portrait {
		max-width: 420px;
		margin: 0 auto;
	}
}

/* "Transformationshelfer" muss wie im Prototyp in einer Zeile stehen - der
   Schwung darunter ist als Hintergrundbild auf die Wortbreite gestreckt und
   verzieht sich, sobald das Wort umbricht.

   Ein erster Versuch hat die Schriftgröße nach der FENSTERBREITE berechnet
   (ein Fenster-Bruchpunkt mit einer steileren vw-Formel). Das ist die falsche
   Grundlage: wie breit die Textspalte tatsächlich ist, hängt von Innenabstand,
   Abstand zum Foto und Rundungen zusammen - Annahmen darüber sind fehleranfällig,
   und genau das ist hier auch passiert, das Wort brach weiterhin um.

   Sauberer: die Schriftgröße direkt an der wirklichen Spaltenbreite bemessen,
   nicht am Fenster geschätzt. Dafür macht `container-type: inline-size` die
   Textspalte selbst zum Bezugsrahmen - `cqw` darin ist Prozent von IHRER
   eigenen gerenderten Breite, ganz gleich wie viel Platz Foto, Abstand oder
   Innenabstand tatsächlich wegnehmen.

   Der Prozentsatz ist mit der echten Schriftdatei gemessen (Archivo Black,
   assets/fonts/ArchivoBlack-400-latin.woff2): die größte Schrift, bei der
   "Transformationshelfer" mit 12px Luft noch in eine Zeile passt, liegt über
   Spaltenbreiten von 250 bis 900px konstant bei 7.8-8.1% der Spaltenbreite -
   praktisch eine gerade Linie. 7.6cqw liegt mit Sicherheitsabstand darunter,
   die Kappung bei 2.5rem bleibt wie zuvor - am breiten Desktop ändert sich
   nichts. */
.fv-hero-grid > .wp-block-column:first-child {
	container-type: inline-size;
}

.fv-hero-grid h1 {
	font-size: clamp(1.75rem, 7.6cqw, 2.5rem);
}

/* ---------------------------------------------------------------------------
   Vertikale Wortmarke unten rechts
   ---------------------------------------------------------------------------
   Prototyp: "Vertikales Logo, wie auf deinen Folien unten rechts" - fest am
   Bildschirmrand (position:fixed), auf jeder Seite gleich, unabhängig vom
   Header im Markup (siehe functions.php, frank_vohle_corner_logo()).

   Das ist das echte Logo-SVG, nicht Text im Logo-Look - liegend geladen wie
   im Header, hier nur gedreht. Ein <img> allein zu drehen würde die eigene
   Box nicht mitdrehen; das Element bliebe liegend im Fluss stehen, nur sein
   Inhalt kippt. Deshalb hat der Rahmen (.fv-corner-logo) schon die GEDREHTE
   Zielgröße - 16px breit, 195px hoch -, während das <img> darin in voller
   Länge liegt (auto x 16px) und über absolute Zentrierung + rotate(-90deg)
   in den Rahmen gedreht wird.

   -90 statt 90 Grad: Die Marke soll sich von unten nach oben lesen lassen,
   wie im Entwurf (".corner-logo{writing-mode:vertical-rl;
   transform:rotate(180deg)}" dort - andere Technik, gleiche Leserichtung).

   Unter 600px blendet sie sich aus: Auf dem Handy stünde sie im Weg, und dort
   zeigt der Header selbst schon Name und Logo direkt sichtbar. */
/* Weiße Fläche dahinter: die Marke liegt über wechselndem Untergrund - Foto,
   Fließtext, hellen wie dunklen Bildstellen. Ohne eigenen Grund war sie mal
   lesbar, mal nicht. Das Polster (10px) macht daraus eine kleine Plakette
   statt eines eng anliegenden Aufklebers - ohne Schatten, flach auf der
   Seite liegend. */
.fv-corner-logo {
	position: fixed;
	bottom: 22px;
	right: 14px;
	z-index: 40;
	width: 36px;
	height: 215px;
	background: var(--wp--preset--color--base);
	overflow: hidden;
}

.fv-corner-logo img {
	position: absolute;
	top: 50%;
	left: 50%;
	width: 195px;
	height: 16px;
	transform: translate(-50%, -50%) rotate(-90deg);
}

@media (max-width: 600px) {
	.fv-corner-logo {
		display: none;
	}
}

/* ---------------------------------------------------------------------------
   Hero-Banner: randlos wie die Navigation
   ---------------------------------------------------------------------------
   Frank möchte das Foto probeweise als Aufmacher: randlos über die volle
   Breite, direkt am unteren Rand des Headers andockend, darunter knapp und
   schlank eine Bildunterschrift statt der bisherigen Zweispalten-Vorstellung.

   Warum nicht das Editor-eigene "randlos" (align:full) nutzen: theme.json
   setzt useRootPaddingAwareAlignments, das lässt randlose Blöcke nur um das
   Wurzel-Padding (28px) ausbrechen, nicht bis zum Bildschirmrand - passend für
   Bilder INNERHALB des Fließtexts, aber die Kopfzeile selbst füllt die ganze
   Breite. Für "randlos wie die Navigation" der klassische, unabhängige Trick:
   100vw plus negativem Rand zieht das Bild bis an den echten Rand, unabhängig
   davon, wie tief es im Fließtext verschachtelt ist. */
/* !important nötig: Core setzt für jeden Block ohne align="full" auf
   ".is-layout-constrained > :where(...)" eine Höchstbreite und
   "margin: auto !important" - das schlägt eine gewöhnliche Regel unabhängig
   von ihrer Spezifität. */
.fv-hero-banner {
	display: block;
	max-width: 100vw !important;
	width: 100vw !important;
	margin-left: calc(50% - 50vw) !important;
	margin-right: calc(50% - 50vw) !important;
	margin-top: 0;
	/* Seitenverhältnis der Datei (2400x1143) - die Höhe ergibt sich daraus,
	   solange die Deckelung unten nicht greift. */
	aspect-ratio: 2400 / 1143;
	/* Deckelung: auf schmalen, hohen Fenstern würde die Datei bei voller
	   Breite sehr hoch werden. max-height kappt dort die Höhe, die Breite
	   bleibt volle 100vw - object-fit:cover am <img> gleicht das aus, indem
	   es oben/unten beschneidet statt das Bild zu stauchen. */
	max-height: 66vh;
	overflow: hidden;
}

.fv-hero-banner img {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
}

/* Direkt am Header-Strich andocken: <main> und der übliche Blockabstand
   zum ersten Kind schieben sonst eine Lücke dazwischen. */
.wp-block-post-content > .fv-hero-banner:first-child {
	margin-top: calc(-1 * var(--wp--style--block-gap, 1.5rem));
}

/* Bildunterschrift eng am Foto, schlank statt fett - "Frank möchte das
   Foto als Blickfang, die Schrift soll sich unterordnen". */
.fv-hero-caption {
	margin-top: 0.75rem;
	text-align: center;
}

.fv-hero-caption p {
	margin: 0;
}

.fv-hero-caption p:first-child {
	font-weight: 500;
	letter-spacing: 0.01em;
}

.fv-hero-caption p + p {
	margin-top: 0.25rem;
}
