/* ============================================================================
   NUIT NOIRE INTERNATIONAL — profile-page.css
   Die Profilseite (CPT nni_selection, SPEC7 Abschnitt 3; zuvor SPEC6 Abschnitt 4).

   Letzte Stufe der Kaskade: wird NACH tokens, base, components, private,
   profile und mobile geladen und darf deshalb ältere Regeln der Portrait-
   Einzelseite zurücknehmen, ohne dass irgendwo !important nötig wird.

   Farben, Zeiten, Schriften und Abstände kommen ausnahmslos aus tokens.css.
   Lokale Rechengrössen tragen das Präfix --nnipp- (profile page), damit sie
   nie mit den unveränderlichen Design-Tokens kollidieren. Einzige Ausnahme
   im --nni-Namensraum ist --nni-head-h: die Höhe der Kopfzeile, die von der
   klebenden Unternavigation und von jedem Sektionsanker gebraucht wird.

   Abschnitte:
     0  Masse — Kopfzeilenhöhe, Anker, lokale Variablen
     1  Grundgerüst — das alte Portrait-Raster zurücknehmen
     2  Kopfgalerie          .nni-phero
     3  Unternavigation      .nni-pnav
     4  Sektionen            .nni-psec
     4a Portrait, Read more  .nni-more            (SPEC11)
     5  Interview            .nni-interview
     6  Bausteine            .nni-chips / .nni-chip
     7  Angaben              .nni-vitals
     8  My Menu              .nni-menu
     9  Anfrage              .nni-enq
    10  Honorar              .nni-rates
    11  Galerie              .nni-pgal
    12  Lichtansicht         .nni-light
    13  Telefon und Tablet
    14  Weniger Bewegung
    15  Drucken

   EINE REGEL, DIE NICHT GEBROCHEN WIRD: Inhalt ist ohne JavaScript sichtbar.
   Verbergen darf nur, was unter .nni-js steht (siehe base.css, Abschnitt 7).
   In dieser Datei verbirgt deshalb nichts ausser der Lichtansicht — und die
   ist ein Fenster über der Seite, kein Inhalt.
   ========================================================================= */


/* ---------------------------------------------------------------------------
   0 · Masse

   --nni-head-h ist die Höhe der klebenden Kopfzeile. private.css legt sie als
   --nnip-head auf .nni-body; hier wird sie einmal übernommen und danach nur
   noch über --nni-head-h gelesen. Auf schmalen Geräten kommt der Notch-Rand
   dazu, weil mobile.css der Kopfzeile dort zusätzlich env(safe-area-inset-top)
   als Innenabstand gibt.
   ------------------------------------------------------------------------ */

:root {
	--nni-head-h: max(clamp(58px, 7.4vh, 82px), 68px);
}

.nni-body {
	/* Nachgemessen: die Kopfzeile ist nie nur so hoch wie ihre Mindesthöhe —
	   Innenabstand und Inhalt tragen auf (gemessen 63,9px bei 1280 Breite,
	   73px auf dem Telefon). Der Boden von 68px bzw. 76px fängt das ab, der
	   Notch-Rand kommt oben drauf. Lieber leicht zu hoch als zu niedrig:
	   eine Überschätzung schluckt die Überlappung unten, eine Unterschätzung
	   schöbe die Unternavigation unter die Kopfzeile. */
	--nni-head-h: calc(max(var(--nnip-head, clamp(58px, 7.4vh, 82px)), 68px) + env(safe-area-inset-top, 0px));

	/* Unternavigation: sichtbare Höhe (Ziel 46px + Haarlinie) und die
	   Überlappung, mit der sie unter die Kopfzeile geschoben wird. Die
	   Überlappung fängt jede Ungenauigkeit der Kopfzeilenhöhe ab — es
	   entsteht nie ein Spalt, durch den Inhalt durchläuft. */
	--nnipp-nav-h: 47px;
	--nnipp-overlap: 18px;

	/* Sprungziel: Kopfzeile + Unternavigation + Luft. */
	--nnipp-anchor: calc(var(--nni-head-h) + var(--nnipp-nav-h) + clamp(20px, 3vw, 44px));

	/* Kopfgalerie — Schreibtisch. Telefon und Tablet setzen eigene Werte. */
	--nnipp-hero-h: min(72vh, 760px);

	/* Linien */
	--nnipp-line: var(--nni-hair) solid var(--nni-line-soft);
	--nnipp-line-strong: var(--nni-hair) solid var(--nni-line);

	/* Zeilenlängen — an einer Stelle gepflegt, an vielen Stellen gelesen. */
	--nnipp-measure: var(--nni-max-text);   /* Fliesstext        62ch */
	--nnipp-measure-a: 46ch;                /* Interview-Antwort 46ch */
	--nnipp-measure-grid: 86ch;             /* Angaben, zweispaltig    */

	/* Luft zwischen zwei Sektionen. Die Vorgabe nennt dieses Mass als
	   Mindestabstand; er entsteht aus zwei Innenabständen, deshalb steht in
	   .nni-psec die Hälfte davon als Boden. */
	--nnipp-air: clamp(3.5rem, 9vw, 6rem);

	/* Böden für die Schriftgrade auf schmalen Geräten. 12px für
	   Beschriftungen, 16px für alles, was gelesen und nicht überflogen wird.
	   Über max() bleibt die Skala nach oben hin unangetastet.

	   Beide Böden greifen inzwischen nicht mehr: tokens.css ist an den
	   unteren Enden angehoben worden, --nni-fs-xs endet bei 12,48px und
	   --nni-fs-md liegt bei 360px schon auf 16,86px. Sie bleiben trotzdem
	   stehen — sie kosten nichts und halten auch dann, wenn jemand die Skala
	   später wieder nach unten dreht. Genau das war der Grund für ihre
	   Einführung. */
	--nnipp-fs-label: max(12px, var(--nni-fs-xs));
	--nnipp-fs-read: max(16px, var(--nni-fs-md));

	/* SPEC11: die Beschriftung im Kachelraster der Angaben (Abschnitt 7) darf
	   leiser sein als eine gewöhnliche Beschriftung — sie steht winzig über
	   dem Wert, nicht daneben. Derselbe Boden von 12px gilt trotzdem. */
	--nnipp-fs-whisper: max(12px, var(--nni-fs-micro));
}

/* Schmale Geräte tragen mehr Kopfzeile: mobile.css legt dort zusätzlichen
   Innenabstand an. Gemessen 73px (Telefon) bis 82px (Tablet hoch). */
@media (max-width: 63.999em) {
	.nni-body {
		--nni-head-h: calc(max(var(--nnip-head, clamp(58px, 7.4vh, 82px)), 76px) + env(safe-area-inset-top, 0px));
	}
}

/* Der Browser scrollt Anker sonst zweimal: einmal um scroll-padding des
   Dokuments, einmal um scroll-margin der Sektion. Auf der Profilseite trägt
   allein die Sektion das Mass. */
html:has(.nni-pnav) {
	scroll-padding-top: 0;
}


/* ---------------------------------------------------------------------------
   1 · Grundgerüst

   private.css macht `.single-nni_selection .nni-main > article` ab 64em zu
   einem zweispaltigen Raster (Bild links, Text rechts). Die neue Profilseite
   läuft durchgehend über die volle Breite. Die Rücknahme greift nur, wenn das
   neue Markup wirklich vorhanden ist.
   ------------------------------------------------------------------------ */

.single-nni_selection .nni-main > *:has(.nni-phero, .nni-pnav, .nni-psec) {
	display: block;
	grid-template-columns: none;
	gap: 0;
	padding-block-start: clamp(16px, 2.6vw, 34px);
	padding-block-end: 0;
}

/* Rückfall ohne :has — die Bausteine nehmen im Raster die volle Breite. */
.nni-phero,
.nni-pnav,
.nni-psec,
.nni-pgal {
	grid-column: 1 / -1;
	min-width: 0;
}

/* Die Bildregeln der alten Portraitseite dürfen die neuen Strecken nicht
   auf 3/4 zwingen. */
.nni-body .nni-phero .nni-figure,
.nni-body .nni-pgal .nni-figure {
	aspect-ratio: auto;
	overflow: visible;
}


/* ---------------------------------------------------------------------------
   2 · Kopfgalerie

   Der Rahmen kappt, nicht der Body: .nni-phero trägt overflow:hidden, die
   laufende Reihe darf beliebig breit sein. Der Rahmen zieht sich um den
   Innenabstand der Bahn nach aussen — bis an die Kante der Bahn, niemals
   darüber hinaus. Deshalb entsteht kein waagerechter Seitenüberlauf.

   Voraussetzung: .nni-phero ist unmittelbares Kind des Bahn-Elements
   (das <article> in .nni-main), das den Innenabstand var(--nni-gutter) trägt.
   ------------------------------------------------------------------------ */

.nni-phero {
	/* Rückfall: bis an die Kante der Bahn. Ein Skript darf --nnipp-bleed auf
	   den tatsächlichen Abstand der Bahn zum Fensterrand setzen und die
	   Strecke damit über die volle Breite laufen lassen — ohne 100vw, das
	   wegen der Bildlaufleiste waagerecht überliefe. */
	--nnipp-bleed: var(--nni-gutter);

	position: relative;
	width: calc(100% + var(--nnipp-bleed) * 2);
	max-width: calc(100% + var(--nnipp-bleed) * 2);
	margin-inline: calc(var(--nnipp-bleed) * -1);
	overflow: hidden;
	overscroll-behavior-x: contain;
	/* Waagerechtes Ziehen liest das Skript selbst, senkrecht scrollt die Seite. */
	touch-action: pan-y;
	-webkit-user-select: none;
	user-select: none;
	cursor: grab;
	background-color: var(--nni-black);
}

.nni-phero:active {
	cursor: grabbing;
}

/* Feine Verlaufsblenden an beiden Rändern. */
.nni-phero::before,
.nni-phero::after {
	content: "";
	position: absolute;
	inset-block: 0;
	z-index: 2;
	width: clamp(28px, 6vw, 104px);
	pointer-events: none;
}

.nni-phero::before {
	inset-inline-start: 0;
	background-image: linear-gradient(90deg, var(--nni-black), transparent);
}

.nni-phero::after {
	inset-inline-end: 0;
	background-image: linear-gradient(270deg, var(--nni-black), transparent);
}

.nni-phero__row {
	display: flex;
	flex-wrap: nowrap;
	align-items: stretch;
	gap: clamp(10px, 1.1vw, 18px);
	width: max-content;
	margin: 0;
	padding: 0;
	list-style: none;
	transform: translate3d(0, 0, 0);
	will-change: transform;
	backface-visibility: hidden;
}

/* Ein einzelnes Bild läuft nicht, es steht in der Mitte. */
.nni-phero__row:has(> *:only-child) {
	width: 100%;
	justify-content: center;
}

/* Die Bilder dürfen in <li> stecken — dann trägt die Hülle keine Masse. */
.nni-phero__row > * {
	margin: 0;
	min-width: 0;
}

.nni-phero__item {
	flex: 0 0 auto;
	position: relative;
	margin: 0;
	padding: 0;
	height: var(--nnipp-hero-h);
	aspect-ratio: 3 / 4;
	overflow: hidden;
	background-color: var(--nni-ink);
}

.nni-phero__img {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
	/* Gesichter sitzen selten in der Bildmitte. */
	object-position: 50% 34%;
	-webkit-user-drag: none;
	user-select: none;
}

/* Aufziehende Blende — reine CSS-Bewegung, damit kein Bild unsichtbar bleibt,
   falls ein Skript ausfällt. animation-fill-mode: both hält den Endzustand. */
@keyframes nnipp-aperture {
	from {
		opacity: 0;
		transform: scale(1.055);
	}
	to {
		opacity: 1;
		transform: none;
	}
}

.nni-phero__img {
	animation: nnipp-aperture var(--nni-t-slow) var(--nni-ease) both;
}

/* Gezählt wird das Kind der Reihe — so greift die Staffelung auch dann,
   wenn jedes Bild in einem <li> sitzt. */
.nni-phero__row > *:nth-child(1) .nni-phero__img { animation-delay: calc(1 * var(--nni-stagger)); }
.nni-phero__row > *:nth-child(2) .nni-phero__img { animation-delay: calc(2 * var(--nni-stagger)); }
.nni-phero__row > *:nth-child(3) .nni-phero__img { animation-delay: calc(3 * var(--nni-stagger)); }
.nni-phero__row > *:nth-child(4) .nni-phero__img { animation-delay: calc(4 * var(--nni-stagger)); }
.nni-phero__row > *:nth-child(5) .nni-phero__img { animation-delay: calc(5 * var(--nni-stagger)); }
.nni-phero__row > *:nth-child(6) .nni-phero__img { animation-delay: calc(6 * var(--nni-stagger)); }

/* Das Skript darf die Reihe während des Ziehens anhalten. */
.nni-phero.is-held .nni-phero__row,
.nni-phero.is-paused .nni-phero__row {
	cursor: grabbing;
}


/* ---------------------------------------------------------------------------
   3 · Unternavigation

   Klebt unter der Kopfzeile. Sie sitzt bewusst um --nnipp-overlap zu hoch und
   gleicht das mit gleich grossem Innenabstand aus: der überstehende Streifen
   verschwindet unter der Kopfzeile (z-index 80), ein Spalt kann nicht
   entstehen.
   ------------------------------------------------------------------------ */

.nni-pnav {
	position: sticky;
	top: calc(var(--nni-head-h) - var(--nnipp-overlap));
	z-index: 40;
	width: calc(100% + var(--nni-gutter) * 2);
	max-width: calc(100% + var(--nni-gutter) * 2);
	margin-inline: calc(var(--nni-gutter) * -1);
	padding-block-start: var(--nnipp-overlap);
	background-color: var(--nni-black);
	border-bottom: var(--nnipp-line);
}

/* Glas nur am Schreibtisch.

   Auf dem Telefon schien der Text der Seite hinter der Leiste durch: 82 %
   Deckkraft plus Weichzeichner lesen sich auf diesem sehr ruhigen Design nicht
   als Glas, sondern als Fehler. mobile.css hat die Leiste dort bereits deckend
   gesetzt — diese Datei lädt aber später und hat diese Korrektur mit derselben
   Spezifität wieder zurückgenommen. Deshalb steht das Glas jetzt selbst hinter
   einer Bedingung. Oberhalb von 48em bleibt es, dort ist genug Raum darum herum.

   Die Grenze lautet 48.001em und nicht 48em: die Gegenregel in mobile.css
   reicht bis EINSCHLIESSLICH 48em ("max-width: 48em"), weil dort das Tablet im
   Hochformat mit genau 768px bewusst zum Mobilfall gezählt wird. Mit 48em auf
   beiden Seiten träfen bei exakt 768px beide Bedingungen zu; beide Selektoren
   heissen .nni-pnav und wiegen gleich schwer, und diese Datei lädt später —
   das Tablet im Hochformat bekäme also doch wieder Glas mit Weichzeichner.
   Die übrigen Paare dieser Datei (47.999em/48em, 63.999em/64em) liegen beide
   hier und trennen deshalb an der unteren Grenze. */
@supports (backdrop-filter: blur(2px)) and (color: color-mix(in srgb, #000 50%, transparent)) {
	@media (min-width: 48.001em) {
		.nni-pnav {
			background-color: color-mix(in srgb, var(--nni-black) 82%, transparent);
			-webkit-backdrop-filter: blur(16px);
			backdrop-filter: blur(16px);
		}
	}
}

.nni-pnav__list {
	display: flex;
	align-items: stretch;
	gap: clamp(18px, 2.4vw, 44px);
	margin: 0;
	padding-inline: var(--nni-gutter);
	list-style: none;
	overflow-x: auto;
	overflow-y: hidden;
	overscroll-behavior-x: contain;
	-webkit-overflow-scrolling: touch;
	scrollbar-width: none;
	-ms-overflow-style: none;

	/* Einrasten, aber nur in der Nähe („proximity"). Ein früherer Versuch mit
	   `mandatory` fraß beim Laden den linken Innenabstand und schnitt den
	   ersten Buchstaben ab. Der Grund war die fehlende Deckung zweier Masse:
	   die Rastposition einer Marke ist ihr linker Rand minus scroll-padding.
	   Stimmt dieses Mass mit dem Innenabstand der Leiste überein, liegt die
	   Rastposition der ersten Marke bei genau 0 — nichts wird abgeschnitten.
	   Beide Masse werden deshalb ab hier gemeinsam gepflegt (auf dem Telefon
	   im Abschnitt 13, wo der Notch-Rand dazukommt). */
	scroll-snap-type: x proximity;
	scroll-padding-inline: var(--nni-gutter);
}

.nni-pnav__list::-webkit-scrollbar {
	width: 0;
	height: 0;
	display: none;
}

.nni-pnav__list > li {
	margin: 0;
	flex: 0 0 auto;
	scroll-snap-align: start;
	/* Kein `always`: wer schnell über die Leiste wischt, soll nicht an jeder
	   einzelnen Marke abgebremst werden. */
	scroll-snap-stop: normal;
}

.nni-pnav__link {
	position: relative;
	display: inline-flex;
	align-items: center;
	min-height: 46px;
	padding-block: 12px;
	white-space: nowrap;
	font-family: var(--nni-sans);
	font-weight: 300;
	font-size: var(--nni-fs-micro);
	line-height: 1.4;
	letter-spacing: var(--nni-ls-ui);
	/* Der Nachlauf der Sperrung würde die Haarlinie zu weit tragen. */
	margin-inline-end: calc(-1 * var(--nni-ls-ui));
	text-transform: uppercase;
	text-decoration: none;
	color: var(--nni-faint);
	transition: color var(--nni-t-fast) var(--nni-ease);
}

.nni-pnav__link::after {
	content: "";
	position: absolute;
	inset-inline: 0 var(--nni-ls-ui);
	inset-block-end: 9px;
	height: var(--nni-hair);
	background-color: currentColor;
	transform: scaleX(0);
	transform-origin: 0 50%;
	transition: transform var(--nni-t-med) var(--nni-ease);
}

@media (hover: hover) {
	.nni-pnav__link:hover {
		color: var(--nni-cream-soft);
	}
}

.nni-pnav__link:focus-visible {
	color: var(--nni-cream);
	outline-offset: 4px;
}

.nni-pnav__link.is-current,
.nni-pnav__link[aria-current] {
	color: var(--nni-cream);
}

.nni-pnav__link.is-current::after,
.nni-pnav__link[aria-current]::after {
	transform: scaleX(1);
}

/* Weiche Verlaufskante an beiden Rändern, die NUR erscheint, wenn dort
   wirklich noch etwas steht (SPEC11, Abschnitt 5 — siehe @todo in
   parts/profile-nav.php, das diese Technik bereits vorskizziert hat). Die
   frühere mask-image-Lösung war unbedingt: sie erschien immer, auch wenn die
   Leiste gar nicht mehr scrollte, und fehlte am Schreibtisch (ab 64em) ganz.

   Vier Hintergrundschichten, zwei Schichtenpaare:
     1+2 „Deckel" — vom Flächenton auf transparent, background-attachment:
         local. Sie laufen MIT dem Inhalt und sitzen exakt am Anfang bzw. Ende
         der scrollbaren Fläche. Solange nichts weiter gescrollt werden kann,
         deckt der Deckel die Blende darunter vollständig zu.
     3+4 „Blende" — ein schmaler, radialer Lichtschein, background-attachment:
         scroll. Sie bleibt visuell am Rand des Rahmens stehen und wird erst
         sichtbar, sobald der zugehörige Deckel wegscrollt, also sobald dort
         tatsächlich noch Einträge folgen.
   Reine Hintergrund-Technik, keine Fremdbibliothek, keine Voraussetzung durch
   JavaScript — bei jeder Fensterbreite aktiv, nicht nur unter 64em. Der
   Deckel ist bewusst blickdicht in --nni-black gehalten: am Schreibtisch legt
   sich das Glas (siehe oben) leicht heller darüber, was für den schmalen
   Rand am Anfang/Ende der Leiste nicht ins Gewicht fällt.

   Die Blende ist HELL, nicht dunkel: ein Schatten (die klassische Bauart
   dieser Technik, für helle Flächen gedacht) verschwindet auf einer bereits
   fast schwarzen Fläche (--nni-black = #050505) unsichtbar im Untergrund —
   nachgemessen im Pruefstand blieb die Kante bei rgba(0,0,0,.45) bei jedem
   Scrollstand identisch rgb(5,5,5), keine Kante zu sehen. Der helle Schein in
   --nni-cream (als rgb-Literal, siehe unten) hebt sich sichtbar ab, ohne
   selbst wie ein aktives Bedienelement zu wirken. rgba() statt color-mix():
   eine ungültige Funktion in EINER der vier kommagetrennten Ebenen würde die
   gesamte background-image-Deklaration verwerfen, nicht nur diese Ebene. */
.nni-pnav__list {
	--nnipp-fade-w: clamp(20px, 3vw, 40px);

	background-repeat: no-repeat;
	background-position: left center, right center, left center, right center;
	background-size:
		var(--nnipp-fade-w) 100%,
		var(--nnipp-fade-w) 100%,
		12px 100%,
		12px 100%;
	background-attachment: local, local, scroll, scroll;
	background-image:
		linear-gradient(90deg, var(--nni-black) 40%, transparent),
		linear-gradient(270deg, var(--nni-black) 40%, transparent),
		/* rgb(232, 224, 213) = --nni-cream. */
		radial-gradient(farthest-side at 0 50%, rgba(232, 224, 213, .16), transparent),
		radial-gradient(farthest-side at 100% 50%, rgba(232, 224, 213, .16), transparent);
}


/* ---------------------------------------------------------------------------
   4 · Sektionen
   ------------------------------------------------------------------------ */

.nni-psec {
	scroll-margin-top: var(--nnipp-anchor);
	/* Der Boden hält die geforderte Luft zwischen zwei Sektionen ein, auch
	   wenn die fliessende Grösse darunter fällt: zwei Innenabstände ergeben
	   zusammen mindestens --nnipp-air. */
	padding-block: max(calc(var(--nnipp-air) / 2), clamp(56px, 8vw, 132px));
	min-width: 0;
}

.nni-psec + .nni-psec {
	border-top: var(--nnipp-line);
}

.nni-pnav + .nni-psec,
.nni-phero + .nni-psec {
	padding-block-start: clamp(36px, 5vw, 78px);
}

.nni-psec__head {
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	gap: clamp(10px, 1.4vw, 16px);
	margin-bottom: clamp(26px, 3.6vw, 52px);
	min-width: 0;
}

.nni-psec__head .nni-eyebrow {
	color: var(--nni-faint);
}

/* Serifen-Zwischentitel. Die alte Regel der Portraitseite setzt .nni-display
   auf Plakatgrösse — innerhalb einer Sektion ist das zu laut. Die Überschrift
   der Seite (h1) bleibt davon unberührt. */
.nni-body .nni-psec__head :where(h2, h3, .nni-psec__title) {
	font-family: var(--nni-serif);
	font-weight: 300;
	font-size: var(--nni-fs-xl);
	line-height: var(--nni-lh-tight);
	letter-spacing: var(--nni-ls-display);
	color: var(--nni-cream);
	max-width: 26ch;
	text-wrap: balance;
}

.nni-psec__body {
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	gap: clamp(18px, 2.4vw, 32px);
	min-width: 0;
}

.nni-psec__body > * {
	max-width: 100%;
	min-width: 0;
}

/* Zeilenlänge im Fliesstext: 62 Zeichen. Gilt für Prosa — nicht für die
   Listen, aus denen Bausteine, Galerie und Sprungmarken gebaut sind. */
.nni-psec__body :where(p, li, dd, blockquote) {
	max-width: var(--nnipp-measure);
}

.nni-chips > li,
.nni-pgal > *,
.nni-phero__row > *,
.nni-pnav__list > li {
	max-width: none;
}

.nni-psec__body :where(p) {
	color: var(--nni-cream-soft);
}

/* Angaben, Zitate, „In her words" behalten ihre Bausteine aus components.css
   und private.css — hier wird nur die Breite geführt. */
.nni-psec__body .nni-facts,
.nni-psec__body .nni-words__body {
	width: 100%;
	max-width: var(--nnipp-measure);
}

.nni-psec__body .nni-quote {
	margin-block: clamp(8px, 1.4vw, 18px);
}


/* ---------------------------------------------------------------------------
   4a · Portrait — Anlauf und „Read more" (SPEC11, Abschnitt 4)

   Kein eigener nummerierter Hauptabschnitt, weil beides nur die Einleitung
   betrifft und an ihre bestehende Sektion (4) andockt.

   Der erste Absatz trägt mehr Gewicht als die folgenden — Serifenlos wie der
   übrige Fliesstext (ein Sprung zur Serife stünde zu dicht neben .nni-lede
   direkt darüber), nur grösser und heller gesetzt: der Anlauf nach der
   Essenz, nicht bloss eine weitere Zeile.

   Der Aufklapper ist natives <details>/<summary> — single-nni_selection.php
   teilt den Text nur, wenn er die rund 900 Zeichen aus der Vorgabe
   überschreitet. Ohne ein einziges Skript liest sich der ganze Text weiter,
   nur eben ohne den Zwischenschritt; profile.js darf das später verfeinern.
   ------------------------------------------------------------------------ */

.nni-psec--intro .nni-prose > p:first-child {
	font-size: var(--nni-fs-md);
	line-height: var(--nni-lh-body);
	color: var(--nni-cream);
}

.nni-more {
	margin-top: clamp(4px, 1vw, 10px);
}

.nni-more__toggle {
	display: inline-flex;
	align-items: center;
	min-height: 44px;
	gap: 8px;
	padding-block: .3em;
	font-family: var(--nni-sans);
	font-weight: 300;
	font-size: var(--nni-fs-xs);
	letter-spacing: var(--nni-ls-ui);
	text-indent: var(--nni-ls-ui);
	text-transform: uppercase;
	color: var(--nni-muted);
	cursor: pointer;
	list-style: none;
	transition: color var(--nni-t-fast) var(--nni-ease);
}

.nni-more__toggle::-webkit-details-marker {
	display: none;
}

.nni-more__toggle::marker {
	content: "";
}

.nni-more__toggle::after {
	content: "";
	flex: 0 0 auto;
	width: 7px;
	height: 7px;
	border-right: var(--nni-hair) solid currentColor;
	border-bottom: var(--nni-hair) solid currentColor;
	transform: rotate(45deg);
	transition: transform var(--nni-t-med) var(--nni-ease);
}

.nni-more[open] .nni-more__toggle::after {
	transform: rotate(-135deg);
}

@media (hover: hover) {
	.nni-more__toggle:hover {
		color: var(--nni-cream);
	}
}

.nni-more__toggle:focus-visible {
	color: var(--nni-cream);
	outline: var(--nni-hair) solid var(--nni-cream);
	outline-offset: 4px;
}

.nni-more__label--less {
	display: none;
}

.nni-more[open] .nni-more__label--more {
	display: none;
}

.nni-more[open] .nni-more__label--less {
	display: inline;
}

.nni-more__body {
	margin-top: clamp(14px, 1.8vw, 22px);
}

.nni-more__body > * + * {
	margin-top: clamp(16px, 1.6vw, 26px);
}


/* ---------------------------------------------------------------------------
   5 · Interview

   Erwartet <dl class="nni-interview"> mit .nni-interview__q (dt) und
   .nni-interview__a (dd); Zwischen-Elemente pro Paar sind erlaubt.
   Am Schreibtisch zweispaltig, auf dem Telefon untereinander.
   ------------------------------------------------------------------------ */

.nni-interview {
	display: grid;
	grid-template-columns: minmax(0, 1fr);
	width: 100%;
	margin: 0;
	border-top: var(--nnipp-line);
}

.nni-interview__q {
	margin: 0;
	padding-block: clamp(24px, 3vw, 36px) 0;
	/* Untereinander gesetzt läuft die Frage auf Textbreite; erst in der
	   zweispaltigen Ansicht wird sie schmal. */
	max-width: var(--nnipp-measure);
	font-family: var(--nni-sans);
	font-weight: 300;
	font-size: var(--nni-fs-xs);
	line-height: 1.8;
	letter-spacing: var(--nni-ls-ui);
	margin-inline-end: calc(-1 * var(--nni-ls-ui));
	text-transform: uppercase;
	color: var(--nni-muted);
	text-wrap: pretty;
}

.nni-interview__a {
	margin: 0;
	padding-block: clamp(10px, 1.2vw, 14px) clamp(24px, 3vw, 36px);
	max-width: var(--nnipp-measure-a);
	border-bottom: var(--nnipp-line);
	font-family: var(--nni-serif);
	font-weight: 300;
	font-size: clamp(1.24rem, 1.06rem + .8vw, 1.72rem);
	line-height: var(--nni-lh-snug);
	letter-spacing: -.006em;
	color: var(--nni-cream);
	text-wrap: pretty;
}

.nni-interview__a p {
	margin: 0;
	max-width: none;
	font: inherit;
	color: inherit;
}

.nni-interview__a p + p {
	margin-top: .55em;
}

/* Zweispaltig, sobald Platz da ist: Frage links schmal, Antwort rechts breit.
   Der Spaltenabstand ist bewusst 0 und steckt als Innenabstand in der Frage —
   sonst risse die Haarlinie zwischen den beiden Zellen auf. Die Antwort füllt
   die ganze Spalte, ihr Text bleibt über den Innenabstand auf Lesebreite. */
@media (min-width: 48em) {
	.nni-interview {
		grid-template-columns: minmax(0, 15rem) minmax(0, 1fr);
		column-gap: 0;
		/* Bewusst nicht baseline: nur gedehnte Zellen enden auf gleicher
		   Höhe, und nur dann läuft die Haarlinie durch die Reihe. */
		align-items: stretch;
	}

	.nni-interview__q {
		max-width: 100%;
		/* Die halbe Zeilenhöhe der Antwort als optischer Ausgleich — sonst
		   sitzt die kleine Frage sichtbar über der ersten Antwortzeile. */
		padding-block: calc(clamp(26px, 3vw, 44px) + .5em) clamp(26px, 3vw, 44px);
		padding-inline-end: clamp(28px, 3.5vw, 88px);
		border-bottom: var(--nnipp-line);
	}

	.nni-interview__a {
		max-width: none;
		padding-block: clamp(26px, 3vw, 44px);
		padding-inline-end: max(0px, calc(100% - var(--nnipp-measure-a)));
	}
}

@media (min-width: 64em) {
	.nni-interview {
		grid-template-columns: minmax(0, 22rem) minmax(0, 1fr);
	}
}

/* Sind Frage und Antwort paarweise eingepackt, übernimmt die Hülle die
   Spalten des Rasters — die Zweispaltigkeit bleibt damit erhalten. */
@media (min-width: 48em) {
	.nni-interview > *:not(.nni-interview__q):not(.nni-interview__a) {
		display: grid;
		grid-column: 1 / -1;
		grid-template-columns: subgrid;
		align-items: stretch;
	}
}


/* ---------------------------------------------------------------------------
   6 · Bausteine — Repertoire und Vorlieben
   Nur Haarlinie und Sperrung. Kein Farbfeld, keine Pille.
   ------------------------------------------------------------------------ */

.nni-chips {
	display: flex;
	flex-wrap: wrap;
	gap: 9px;
	width: 100%;
	margin: 0;
	padding: 0;
	list-style: none;
}

.nni-chips > li {
	margin: 0;
	display: flex;
}

.nni-chip {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-height: 36px;
	padding: 8px 15px 7px;
	background: none;
	border: var(--nnipp-line-strong);
	border-radius: 0;
	font-family: var(--nni-sans);
	font-weight: 300;
	font-size: var(--nni-fs-micro);
	line-height: 1.4;
	letter-spacing: var(--nni-ls-ui);
	/* Sperrung schiebt den Satz optisch nach links — zurückschieben. */
	text-indent: var(--nni-ls-ui);
	text-transform: uppercase;
	text-decoration: none;
	color: var(--nni-cream-soft);
	white-space: nowrap;
	transition:
		border-color var(--nni-t-med) var(--nni-ease),
		color var(--nni-t-fast) var(--nni-ease);
}

@media (hover: hover) {
	a.nni-chip:hover,
	button.nni-chip:hover {
		border-color: var(--nni-muted);
		color: var(--nni-cream);
	}
}

a.nni-chip:focus-visible,
button.nni-chip:focus-visible {
	color: var(--nni-cream);
	outline-offset: 3px;
}

/* Der Vorlieben-Text steht über den Bausteinen und bleibt Fliesstext. */
.nni-psec__body > .nni-chips {
	margin-top: clamp(4px, 1vw, 12px);
}


/* ---------------------------------------------------------------------------
   7 · Angaben — „At a glance"

   SPEC11, Abschnitt 4: die Zeilen hier sind kurz und zahlreich — ein Alter,
   eine Schuhgrösse, ein „No" bei „Smoking". Die frühere Zuordnungsliste (eine
   Zeile pro Angabe, Beschriftung links, Wert rechts) liess das wie ein
   ausgefülltes Formular aussehen. Jetzt ein enges Kachelraster: die
   Beschriftung steht sehr klein ÜBER dem Wert, mehrere Kacheln nebeneinander.

   Ein Token „--nni-rule" gibt es nicht — Nachschlagen statt Raten, siehe
   tokens.css. Gemeint war immer die Farbe von <hr class="nni-rule">, also
   var(--nni-line) — hier weiterhin über --nnipp-line-strong geführt.

   Lange Antworten (z. B. der Teint, wörtlich in der Vorgabe: „Kissed by the
   sun with a soft tan in summer, warm nude in winter") sollen die Kachel
   nicht sprengen, sondern über die volle Breite laufen dürfen. Die Ausnahme
   gilt nach WERTLÄNGE, nicht nach Feldname: nur complexion und passion sind
   im Katalog (inc/profiles.php, nni_profile_vital_fields_fallback()) für
   ganze Sätze gedacht, jedes andere Feld — auch ein eigenes (x_…) — bricht in
   seiner Kachel einfach um, ohne das Raster zu sprengen. Kein Fehler, nur
   kein Sonderfall; „dense" holt die kurzen Kacheln danach wieder heran.
   ------------------------------------------------------------------------ */

/*
 * Die Breite einer Kachel richtet sich nach der LÄNGE ihres Wertes, nicht
 * nach dem Namen des Feldes.
 *
 * Vorher stand hier ein starres Raster aus vier gleich breiten Säulen, und
 * eine Ausnahmeliste (complexion, passion) hob einzelne Felder auf die volle
 * Zeile. Das ging an den echten Daten vorbei: „Available in" mit 104 Zeichen
 * brach in sechs Zeilen zu rund siebzehn Zeichen in einer 177px-Säule um,
 * während „Complexion" mit 25 Zeichen die ganze Zeile von 837px bekam und
 * 660px davon leer liess. Ein Abschnitt, der „At a glance" heisst, wurde so
 * zur Lesearbeit.
 *
 * Ein Flex-Umbruch macht das ohne jede Namensliste: die Grundbreite jeder
 * Kachel ist ihr eigener Inhalt (flex-basis: auto), lange Werte belegen
 * darum von selbst mehr Platz, kurze weniger, und flex-grow verteilt den
 * Rest, so dass keine Lücke stehen bleibt. Die Untergrenze verhindert die
 * Ein-Wort-Säule, die Obergrenze den Zeilenläufer über die ganze Bahn.
 * Die Kacheln einer Zeile strecken sich auf gleiche Höhe — die Haarlinien
 * darunter bleiben also eine durchgehende Linie.
 */
.nni-vitals {
	display: flex;
	flex-wrap: wrap;
	column-gap: clamp(18px, 3vw, 40px);
	row-gap: 0;
	width: 100%;
	max-width: var(--nnipp-measure-grid);
	margin: 0;
	border-top: var(--nnipp-line-strong);
}

/*
 * Auf dem Telefon ist nur Platz für zwei Kacheln. Dort wächst darum keine
 * Kachel über ihren Inhalt hinaus (flex-grow: 0): eine kurze Angabe bleibt
 * eine halbe Zeile, auch wenn die nächste Angabe zu lang ist, um daneben zu
 * passen. Ohne das stünde „Eyes — Green" über die ganze Breite, bloss weil
 * darunter ein langer Satz folgt.
 */
.nni-vitals__row {
	display: flex;
	flex-direction: column;
	gap: 5px;
	flex: 0 1 auto;
	min-width: calc(50% - (clamp(18px, 3vw, 40px) / 2));
	max-width: 100%;
	padding-block: clamp(13px, 1.7vw, 18px);
	border-bottom: var(--nnipp-line-strong);
}

.nni-psec__body .nni-vitals__label {
	margin: 0;
	max-width: none;
	min-width: 0;
	font-family: var(--nni-sans);
	font-weight: 300;
	font-size: var(--nnipp-fs-whisper);
	line-height: 1.4;
	letter-spacing: var(--nni-ls-fine);
	/* Der Nachlauf der Sperrung stünde sonst als Lücke hinter dem Wort. */
	margin-inline-end: calc(-1 * var(--nni-ls-fine));
	text-transform: uppercase;
	color: var(--nni-faint);
	overflow-wrap: break-word;
}

.nni-psec__body .nni-vitals__value {
	margin: 0;
	max-width: none;
	min-width: 0;
	font-family: var(--nni-serif);
	font-weight: 300;
	font-size: var(--nnipp-fs-read);
	line-height: var(--nni-lh-snug);
	letter-spacing: -.004em;
	color: var(--nni-cream);
	overflow-wrap: break-word;
	text-wrap: pretty;
}

/*
 * Wie viele Kacheln nebeneinander stehen, entscheidet der Umbruch selbst.
 * Gesteuert wird nur die Untergrenze: je breiter das Fenster, desto mehr darf
 * eine kurze Kachel wachsen, ohne dass eine lange in eine Säule gequetscht
 * wird. Am Telefon ist die Grenze bewusst niedrig — dort stehen zwei kurze
 * Angaben nebeneinander, eine lange nimmt die ganze Zeile.
 */
@media (min-width: 34em) {

	.nni-vitals__row {
		/* Ab hier stehen drei und mehr Kacheln nebeneinander; jetzt darf der
		   Rest einer Zeile verteilt werden, statt am rechten Rand zu bleiben. */
		flex-grow: 1;
		min-width: min(100%, 10rem);
	}
}

@media (min-width: 48em) {

	.nni-vitals {
		column-gap: clamp(24px, 3vw, 44px);
	}

	.nni-vitals__row {
		min-width: min(100%, 11rem);
		padding-block: clamp(15px, 1.8vw, 20px);
	}
}


/* ---------------------------------------------------------------------------
   8 · My Menu

   Bewusst anders gesetzt als die Angaben darüber: dort ein Kachelraster, hier
   Karten. Stünde beides in derselben Form, läse sich die Seitenmitte wie eine
   einzige lange Tabelle.

   SPEC11, Abschnitt 4: die Karte braucht keinen vollen Rahmen mehr — eine
   Linie links reicht als Halt. Die Kategorie darüber wird leiser (kleinerer
   Grad, derselbe blasse Ton), der Satz darunter lauter: er trägt jetzt den
   Grad einer kleinen Zwischenüberschrift statt dem einer Angabe, damit „My
   Menu" wie eine Reihe kurzer Aussagen liest und nicht wie eine zweite
   Angaben-Liste in Kartenform.

   Kein Radius, kein Schatten. Drei Spalten ab 64em, zwei ab 40em, darunter
   eine.
   ------------------------------------------------------------------------ */

.nni-menu {
	display: grid;
	grid-template-columns: minmax(0, 1fr);
	gap: clamp(9px, 1.2vw, 16px);
	width: 100%;
	margin: 0;
	padding: 0;
	list-style: none;
	align-items: stretch;
}

/* Ohne diese Zeile trägt base.css der Hülle 0.35em Aussenabstand an und das
   Raster bekommt Sprossen; die Lesebreite aus Abschnitt 4 machte die Karte
   ausserdem schmaler als ihre Spalte. */
.nni-psec__body .nni-menu > li {
	display: flex;
	margin: 0;
	max-width: none;
	min-width: 0;
}

.nni-menu__card {
	display: flex;
	flex-direction: column;
	gap: 7px;
	width: 100%;
	min-width: 0;
	padding-block: clamp(15px, 1.9vw, 20px) clamp(17px, 2.1vw, 23px);
	padding-inline: clamp(20px, 2.4vw, 27px) clamp(15px, 1.9vw, 22px);
	border: 0;
	border-inline-start: var(--nnipp-line-strong);
}

.nni-psec__body .nni-menu__cat {
	margin: 0;
	max-width: none;
	font-family: var(--nni-sans);
	font-weight: 300;
	font-size: var(--nnipp-fs-whisper);
	line-height: 1.4;
	letter-spacing: var(--nni-ls-fine);
	margin-inline-end: calc(-1 * var(--nni-ls-fine));
	text-transform: uppercase;
	color: var(--nni-faint);
	overflow-wrap: break-word;
}

.nni-psec__body .nni-menu__line {
	margin: 0;
	max-width: none;
	font-family: var(--nni-serif);
	font-weight: 300;
	font-size: var(--nni-fs-lg);
	line-height: var(--nni-lh-snug);
	letter-spacing: -.006em;
	color: var(--nni-cream);
	overflow-wrap: break-word;
	text-wrap: pretty;
}

@media (min-width: 40em) {

	.nni-menu {
		grid-template-columns: repeat(2, minmax(0, 1fr));
	}
}

@media (min-width: 64em) {

	.nni-menu {
		grid-template-columns: repeat(3, minmax(0, 1fr));
	}
}


/* ---------------------------------------------------------------------------
   9 · Anfrage

   Kein zweites Formular, nur zwei Sätze und ein Knopf zur Concierge-Seite.
   Der Knopf trägt redaktionellen Text, deshalb darf er umbrechen: .nni-btn
   steht auf `white-space: nowrap`, und eine längere Beschriftung liefe damit
   auf 360px Breite über den Rand.

   SPEC11, Abschnitt 4: der Schluss der Seite darf mehr Fläche bekommen und
   ruhiger stehen als die Sektionen darüber. Zwei im Haus bereits erprobte
   Mittel dafür: der Flächenwechsel auf --nni-surface, den die Vorgabe
   ausdrücklich für Sektionsgrenzen erlaubt — hier das einzige Mal auf der
   Seite, damit er als Geste wirkt statt sich abzunutzen —, und dieselbe
   zentrierte, grosszügig gepolsterte Form, die der „Schlussruf" .nni-cta
   (components.css) schon dort trägt, wo diese Sektion selbst fehlt. Beide
   Formen dienen demselben Zweck und sollen sich deshalb auch gleich anfühlen.
   ------------------------------------------------------------------------ */

/*
 * Verdoppelter Selektor (.nni-psec.nni-psec--enquiry statt nur
 * .nni-psec--enquiry) aus zwei Gründen, beide gegen dieselbe Regel in
 * Abschnitt 13 (.nni-psec, Telefon, max-width: 47.999em):
 *
 *   1. Der Flächenwechsel braucht denselben Überstand bis an den Fensterrand
 *      wie .nni-pnav (Abschnitt 3) — ohne width/margin-inline endet die
 *      Fläche an der Kante der Bahn, mit schwarzem Rand ringsum: eine Karte,
 *      keine Flächengrenze. padding-inline holt den Text auf seinen
 *      gewohnten Abstand zurück, den er sonst vom <article> geerbt hätte.
 *   2. .nni-psec--enquiry und die allgemeine Telefonregel .nni-psec wiegen
 *      beide 0-1-0 und stehen in derselben Datei — eine @media-Anfrage erhöht
 *      die Spezifität nicht, es entscheidet die Quellreihenfolge, und die
 *      allgemeine Regel steht später. Nachgemessen: padding-block fiel auf
 *      44px, byte-gleich mit jeder anderen Sektion, statt der beabsichtigten
 *      --nni-sp-9/--nni-sp-10. .nni-psec.nni-psec--enquiry wiegt 0-2-0 und
 *      gewinnt unabhängig von der Quellreihenfolge — am wenigsten invasiv,
 *      ohne die allgemeine Regel in Abschnitt 13 einzuschränken.
 */
.nni-psec.nni-psec--enquiry {
	width: calc(100% + var(--nni-gutter) * 2);
	max-width: calc(100% + var(--nni-gutter) * 2);
	margin-inline: calc(var(--nni-gutter) * -1);
	padding-inline: var(--nni-gutter);
	background-color: var(--nni-surface);
	padding-block: var(--nni-sp-9) var(--nni-sp-10);
}

.nni-psec--enquiry .nni-psec__head {
	align-items: center;
	text-align: center;
	width: 100%;
}

.nni-enq {
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	gap: clamp(18px, 2.4vw, 30px);
	width: 100%;
	min-width: 0;
}

.nni-psec--enquiry .nni-enq {
	align-items: center;
	text-align: center;
}

.nni-psec__body .nni-enq__text {
	max-width: var(--nnipp-measure);
	font-size: max(16px, var(--nni-fs-base));
	line-height: var(--nni-lh-body);
	color: var(--nni-cream-soft);
}

.nni-psec--enquiry .nni-psec__body .nni-enq__text {
	margin-inline: auto;
}

.nni-enq__act {
	max-width: 100%;
	min-width: 0;
}

.nni-enq__cta {
	max-width: 100%;
	white-space: normal;
	text-wrap: balance;
}


/* ---------------------------------------------------------------------------
   10 · Honorar
   Ohne Rahmen. Links das Zeitfenster, rechts der Wert, dazwischen eine sehr
   feine punktierte Führungslinie. Die Linie ist das ::after des Zeitfensters,
   das selbst als Flex-Behälter läuft — so wächst sie über den freien Raum.
   ------------------------------------------------------------------------ */

.nni-rates {
	display: flex;
	flex-direction: column;
	width: 100%;
	max-width: var(--nnipp-measure);
	margin: 0;
}

.nni-rates__row {
	display: flex;
	flex-wrap: wrap;
	align-items: baseline;
	column-gap: clamp(12px, 1.6vw, 22px);
	row-gap: 2px;
	padding-block: clamp(13px, 1.7vw, 20px);
	min-width: 0;
}

.nni-rates__slot {
	flex: 1 1 auto;
	display: flex;
	align-items: baseline;
	gap: clamp(10px, 1.4vw, 18px);
	min-width: 0;
	font-family: var(--nni-sans);
	font-weight: 300;
	font-size: var(--nni-fs-micro);
	line-height: 1.6;
	letter-spacing: var(--nni-ls-fine);
	text-transform: uppercase;
	color: var(--nni-muted);
}

.nni-rates__slot::after {
	content: "";
	flex: 1 1 auto;
	min-width: 24px;
	height: var(--nni-hair);
	transform: translateY(-.28em);
	background-image: repeating-linear-gradient(
		90deg,
		var(--nni-line) 0 1px,
		transparent 1px 5px
	);
}

.nni-rates__value {
	flex: 0 0 auto;
	font-family: var(--nni-serif);
	font-weight: 300;
	font-size: var(--nni-fs-lg);
	line-height: var(--nni-lh-tight);
	letter-spacing: var(--nni-ls-display);
	color: var(--nni-cream);
	font-variant-numeric: lining-nums tabular-nums;
	white-space: nowrap;
}

.nni-rates__note {
	/* min-width erzwingt die eigene Zeile: mit max-width allein passte die
	   Notiz rechnerisch noch neben den Wert und rutschte in dessen Zeile.
	   Die Lesebreite kommt jetzt über den Innenabstand. */
	flex: 1 0 100%;
	min-width: 100%;
	max-width: none;
	padding-top: 4px;
	padding-inline-end: max(0px, calc(100% - 52ch));
	font-family: var(--nni-sans);
	font-weight: 300;
	font-size: var(--nni-fs-xs);
	line-height: 1.7;
	letter-spacing: var(--nni-ls-body);
	text-transform: none;
	color: var(--nni-faint);
}


/* ---------------------------------------------------------------------------
   11 · Galerie — „Photographs"

   SPEC11, Abschnitt 4: der zweite Höhepunkt der Seite nach der Kopfgalerie,
   kein gleichförmiges Raster. Jedes dritte Bild — in single-nni_selection.php
   mit .nni-pgal__item--feature ausgezeichnet, sofern danach noch mindestens
   zwei weitere Bilder folgen — spannt hier die volle Bahn (grid-column:
   1 / -1, bei jeder Spaltenzahl); die beiden dazwischen bleiben normal und
   stehen nebeneinander: gross, klein, klein, im Wechsel.

   Normale Bilder halten das Seitenverhältnis 3/4 des Hauses. Die Auszeichnung
   bekommt ein eigenes, flacheres Verhältnis von 16/9: bei voller Spannweite
   (rund 90% der Bahn, unabhängig von der Spaltenzahl) ergäbe 3/4 ein Bild von
   fast zwei Bildschirmhöhen — nachgemessen 1152 × 1536px bei 1280px
   Fensterbreite, also praktisch nie ganz zu sehen, kein Höhepunkt mehr,
   sondern eine Wand. 16/9 hält dieselbe Breite bei rund 650px, weiterhin klar
   das grösste Bild der Sektion (doppelt so breit wie ein normales), ohne den
   Bildschirm zu sprengen. object-position auf .nni-pgal__img sitzt bei 50%
   38% — derselbe obere Bildausschnitt, der bei den übrigen Bildern Gesichter
   im Rahmen hält, mildert das flachere Format auch hier ab. Unter 34em (eine
   Spalte) bleibt die Auszeichnung bei 3/4 wie jedes andere Bild — dort gibt
   es keine Doppelspalte, die sie auszeichnen könnte. Kein Schlagschatten,
   kein Anheben — beim Zeigerkontakt wird das Bild nur um zwei Prozent heller.

   Zwei Spalten von 34em bis 64em, drei ab dem Schreibtisch (64em). Die
   Auszeichnung selbst wird davon nicht schmaler — sie spannt immer die volle
   Bahn —, nur die NORMALEN Bilder werden ab 64em enger und damit niedriger:
   acht Bilder (Val Noire) massen bei zwei Spalten durchgehend rund 6960px,
   allein die drei vollen Bildschirmhöhen der Auszeichnung machten mehr als
   die Hälfte davon aus. Mit 16/9 und drei Spalten ab dem Schreibtisch sind es
   rund 2850px — deutlich unter dem Ziel von 3000px, bei weiterhin klar
   erkennbarem gross/klein-Wechsel. Nachgemessen im Prüfstand, siehe Rückmeldung.
   ------------------------------------------------------------------------ */

.nni-pgal {
	display: grid;
	/* Telefon: eine Spalte. Ein Portrait auf 350px Breite trägt ein Gesicht,
	   zwei auf 170px tragen keines. */
	grid-template-columns: minmax(0, 1fr);
	gap: clamp(8px, 1.2vw, 20px);
	width: 100%;
	margin: 0;
	padding: 0;
	list-style: none;
	align-items: start;
}

/* Die Bilder dürfen in <li> stecken. Ohne diese Zeile trägt base.css der
   Hülle 0.35em Aussenabstand an und das Raster bekommt Sprossen. */
.nni-pgal > * {
	margin: 0;
	min-width: 0;
}

.nni-pgal__item {
	position: relative;
	display: block;
	margin: 0;
	padding: 0;
	width: 100%;
	aspect-ratio: 3 / 4;
	overflow: hidden;
	background-color: var(--nni-ink);
	border: 0;
	border-radius: 0;
	box-shadow: none;
	cursor: zoom-in;
	-webkit-appearance: none;
	appearance: none;
	text-align: left;
}

/* Zwei Spalten, die Auszeichnung spannt beide. Normale Reihenfolge im
   Rasterfluss (kein „dense") reicht: gross belegt eine ganze Zeile, die
   beiden folgenden Bilder rutschen von selbst in die nächste Zeile
   nebeneinander — die Lesereihenfolge im Markup bleibt die Bildreihenfolge. */
@media (min-width: 34em) {
	.nni-pgal {
		grid-template-columns: repeat(2, minmax(0, 1fr));
	}

	.nni-pgal__item--feature {
		grid-column: 1 / -1;
		/* Flacher als das 3/4 der übrigen Bilder — Begründung im
		   Abschnittskopf oben. */
		aspect-ratio: 16 / 9;
	}
}

/* Ab dem Schreibtisch eine dritte Spalte für die NORMALEN Bilder — die
   Auszeichnung bleibt bei grid-column: 1 / -1 und damit bei voller
   Bahnbreite, unabhängig von der Spaltenzahl. Steht in einer Bildgruppe
   zwischen zwei Auszeichnungen nur ein Paar (wie bei Val Noire), bleibt die
   dritte Spalte dort leer statt beengt gequetscht — ein ruhiger, rechts
   liegender Rand, keine unvollständige Zeile mitten im Raster. */
@media (min-width: 64em) {
	.nni-pgal {
		grid-template-columns: repeat(3, minmax(0, 1fr));
	}
}

.nni-pgal__img {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
	object-position: 50% 38%;
	transition: filter var(--nni-t-med) var(--nni-ease-soft);
}

@media (hover: hover) {
	.nni-pgal__item:hover .nni-pgal__img {
		filter: brightness(1.02);
	}
}

.nni-pgal__item:focus-visible {
	outline: var(--nni-hair) solid var(--nni-cream);
	outline-offset: 3px;
}

.nni-pgal__item:focus-visible .nni-pgal__img {
	filter: brightness(1.02);
}


/* ---------------------------------------------------------------------------
   12 · Lichtansicht
   Vollbild, tiefes Schwarz mit leichter Unschärfe dahinter. Blättern über
   zwei grosse unsichtbare Flächen; am Schreibtisch zusätzlich feine Pfeile.
   ------------------------------------------------------------------------ */

.nni-light {
	position: fixed;
	inset: 0;
	/* Unter dem Korn (9999), über allem anderen. */
	z-index: 9990;
	display: flex;
	align-items: center;
	justify-content: center;
	padding: clamp(16px, 4vw, 56px);
	background-color: var(--nni-black);
	opacity: 0;
	visibility: hidden;
	transition:
		opacity var(--nni-t-med) var(--nni-ease-soft),
		visibility 0s linear var(--nni-t-med);
}

.nni-light[hidden] {
	display: none;
}

.nni-light.is-open,
.nni-light[data-open="true"] {
	opacity: 1;
	visibility: visible;
	transition-delay: 0s;
}

@supports (backdrop-filter: blur(4px)) and (color: color-mix(in srgb, #000 50%, transparent)) {
	.nni-light {
		background-color: color-mix(in srgb, var(--nni-black) 90%, transparent);
		-webkit-backdrop-filter: blur(24px) saturate(.85);
		backdrop-filter: blur(24px) saturate(.85);
	}
}

.nni-light__img {
	position: relative;
	z-index: 1;
	width: auto;
	height: auto;
	max-width: 92vw;
	max-height: 86vh;
	object-fit: contain;
	background-color: var(--nni-ink);
	opacity: 0;
	transform: scale(.985);
	transition:
		opacity var(--nni-t-med) var(--nni-ease),
		transform var(--nni-t-slow) var(--nni-ease);
	pointer-events: none;
}

.nni-light.is-open .nni-light__img,
.nni-light[data-open="true"] .nni-light__img {
	opacity: 1;
	transform: none;
}

/* Schliessen — feines Kreuz aus zwei Haarlinien. */
.nni-light__close {
	position: absolute;
	z-index: 3;
	top: max(clamp(10px, 2vw, 26px), env(safe-area-inset-top, 0px));
	right: max(clamp(10px, 2vw, 26px), env(safe-area-inset-right, 0px));
	width: 48px;
	height: 48px;
	margin: 0;
	padding: 0;
	background: none;
	border: 0;
	color: var(--nni-muted);
	cursor: pointer;
	-webkit-appearance: none;
	appearance: none;
	transition: color var(--nni-t-fast) var(--nni-ease);
}

.nni-light__close::before,
.nni-light__close::after {
	content: "";
	position: absolute;
	top: 50%;
	left: 50%;
	width: 22px;
	height: var(--nni-hair);
	background-color: currentColor;
}

.nni-light__close::before { transform: translate(-50%, -50%) rotate(45deg); }
.nni-light__close::after  { transform: translate(-50%, -50%) rotate(-45deg); }

@media (hover: hover) {
	.nni-light__close:hover { color: var(--nni-cream); }
}

.nni-light__close:focus-visible {
	color: var(--nni-cream);
	outline-offset: -6px;
}

/* Blättern. Die Richtung kommt aus dem Modifikator; ohne Modifikator gilt
   die Reihenfolge im Dokument: die erste Fläche liegt links, jede weitere
   rechts. So bleibt die Bedienung auch dann richtig, wenn das Markup nur
   .nni-light__nav kennt. */
.nni-light__nav {
	position: absolute;
	z-index: 2;
	inset-block: 0;
	inset-inline-start: 0;
	width: min(34%, 260px);
	margin: 0;
	padding: 0;
	background: none;
	border: 0;
	color: var(--nni-faint);
	cursor: pointer;
	-webkit-appearance: none;
	appearance: none;
	--nnipp-arrow-x: clamp(14px, 2.4vw, 34px);
	--nnipp-arrow-rot: 45deg;
	transition: color var(--nni-t-fast) var(--nni-ease);
}

.nni-light__nav ~ .nni-light__nav,
.nni-light__nav--next,
.nni-light__nav[data-dir="next"],
.nni-light__nav[data-nni-next] {
	inset-inline-start: auto;
	inset-inline-end: 0;
	--nnipp-arrow-rot: -135deg;
}

.nni-light__nav--prev,
.nni-light__nav[data-dir="prev"],
.nni-light__nav[data-nni-prev] {
	inset-inline-start: 0;
	inset-inline-end: auto;
	--nnipp-arrow-rot: 45deg;
}

.nni-light__nav::before {
	content: "";
	position: absolute;
	top: 50%;
	inset-inline-start: var(--nnipp-arrow-x);
	width: 15px;
	height: 15px;
	border-left: var(--nni-hair) solid currentColor;
	border-bottom: var(--nni-hair) solid currentColor;
	transform: translateY(-50%) rotate(var(--nnipp-arrow-rot));
	opacity: .75;
	transition: opacity var(--nni-t-fast) var(--nni-ease);
}

.nni-light__nav ~ .nni-light__nav::before,
.nni-light__nav--next::before,
.nni-light__nav[data-dir="next"]::before,
.nni-light__nav[data-nni-next]::before {
	inset-inline-start: auto;
	inset-inline-end: var(--nnipp-arrow-x);
}

.nni-light__nav--prev::before,
.nni-light__nav[data-dir="prev"]::before,
.nni-light__nav[data-nni-prev]::before {
	inset-inline-start: var(--nnipp-arrow-x);
	inset-inline-end: auto;
}

@media (hover: hover) {
	.nni-light__nav:hover { color: var(--nni-cream-soft); }
	.nni-light__nav:hover::before { opacity: 1; }
}

.nni-light__nav:focus-visible {
	color: var(--nni-cream);
	outline-offset: -10px;
}

/* Auf Berührungsgeräten bleiben nur die unsichtbaren Flächen. */
@media (max-width: 63.999em) {
	.nni-light__nav::before {
		display: none;
	}
}


/* ---------------------------------------------------------------------------
   13 · Telefon und Tablet
   Mobil ist gleichrangig: gleiche Ruhe, kürzere Zeilen, grössere Ziele,
   kein waagerechter Seitenüberlauf.
   ------------------------------------------------------------------------ */

/* Die Spaltenzahl der Galerie (zwei ab 34em, Auszeichnung spannt beide)
   steht jetzt vollständig in Abschnitt 11 — ein Versatz einzelner Kacheln
   widerspräche dem gross/klein-Muster dort, das seine eigene Reihenfolge
   bereits über den Rasterfluss selbst herstellt. */

/* --- Tablet: 48em bis 64em --------------------------------------------- */
@media (min-width: 48em) and (max-width: 63.999em) {

	.nni-body {
		--nnipp-hero-h: min(64vh, 620px);
		--nnipp-measure: 52ch;
		--nnipp-measure-a: 44ch;
	}
}

/* --- Telefon: bis 48em -------------------------------------------------- */
@media (max-width: 47.999em) {

	.nni-body {
		/* svh statt vh: die Kopfgalerie springt beim Ein- und Ausblenden
		   der Browserleisten nicht. */
		--nnipp-hero-h: 62svh;
		--nnipp-measure: 38ch;
		--nnipp-measure-a: 38ch;
		--nnipp-overlap: 16px;
	}

	/* Ein Bild in Bildhöhe, ein Streifen des nächsten bleibt sichtbar.

	   Die Höhe kommt hier aus dem Seitenverhältnis und nicht mehr aus einem
	   festen Pixelmass: --nnipp-hero-h deckelt nur noch die Breite. Damit
	   springt die Kopfgalerie nicht mehr, wenn die Browserleisten kommen und
	   gehen, und ein Hochformat bleibt ein Hochformat. */
	.nni-phero__item {
		aspect-ratio: 3 / 4;
		width: min(84vw, calc(var(--nnipp-hero-h) * 3 / 4));
		height: auto;
	}

	.nni-phero__row {
		gap: 8px;
	}

	.nni-pnav__list {
		gap: 22px;
		padding-inline-start: max(var(--nni-gutter), env(safe-area-inset-left, 0px));
		padding-inline-end: max(var(--nni-gutter), env(safe-area-inset-right, 0px));
		/* Deckungsgleich mit dem Innenabstand, sonst rastet die erste Marke
		   hinter dem Rand ein und der erste Buchstabe verschwindet. */
		scroll-padding-inline-start: max(var(--nni-gutter), env(safe-area-inset-left, 0px));
		scroll-padding-inline-end: max(var(--nni-gutter), env(safe-area-inset-right, 0px));
	}

	/* Beschriftungen auf dem Telefon nie unter 12px. Die fünf Marken hier
	   stehen auf --nni-fs-micro, und das Ende dieser Skala liegt bei 360 und
	   390px auf 11,52px; gesperrt und in Versalien fehlt dort ein halber
	   Pixel zur Ruhe. Am Schreibtisch bleibt die Skala, wie sie ist —
	   deshalb steht das hier und nicht in der Grundregel.

	   Nicht in dieser Liste, und auch nicht nötig: Überzeile (.nni-eyebrow),
	   der Knopf der Anfrage (.nni-btn) und der Zurück-Verweis (.nni-link).
	   Alle drei stehen in components.css auf --nni-fs-xs, und diese Skala
	   endet bei 12,48px — nachgerechnet 12,48 / 12,48 / 12,50px bei 360 /
	   390 / 414. Der Boden käme dort also nie zum Zug. */
	.nni-pnav__link,
	.nni-chip,
	.nni-rates__slot,
	.nni-rates__note,
	.nni-interview__q {
		font-size: max(12px, var(--nni-fs-micro));
	}

	/* Nachgemessen: die kürzeste Marke („Voice") wurde 43px breit und blieb
	   damit um einen Pixel unter dem Mindestmass für eine antippbare Fläche.
	   Der Boden hebt sie an, ohne den Abstand zwischen den Marken zu ändern. */
	.nni-pnav__link {
		min-height: 46px;
		min-width: 44px;
		justify-content: center;
	}

	.nni-psec {
		padding-block: max(calc(var(--nnipp-air) / 2), clamp(44px, 11vw, 72px));
	}

	.nni-pnav + .nni-psec,
	.nni-phero + .nni-psec {
		padding-block-start: clamp(30px, 8vw, 48px);
	}

	.nni-psec__head {
		margin-bottom: clamp(20px, 5vw, 30px);
	}

	/* Der „Anlauf" des Portraits (Abschnitt 4a) trug auf dem Telefon nur den
	   Helligkeitssprung, keinen wahrnehmbaren Grössenunterschied: mobile.css
	   zwingt Fliesstext unter 30em auf einen festen Wert von 1rem, der die
	   fliessende Skala hier aussticht — nachgemessen 16,86 / 16,93 / 17,00px
	   gegen 16,00px bei 360 / 390 / 414px, ein Unterschied von unter einem
	   Pixel. Ein eigener Boden von 18px macht den Sprung wieder sichtbar
	   (+12,5%), deutlich unter dem Grad der Essenz-Zeile darüber. */
	.nni-psec--intro .nni-prose > p:first-child {
		font-size: max(18px, var(--nni-fs-md));
	}

	.nni-body .nni-psec__head :where(h2, h3, .nni-psec__title) {
		font-size: var(--nni-fs-lg);
		max-width: 20ch;
	}

	.nni-interview__a {
		font-size: clamp(1.2rem, 1.02rem + 1.1vw, 1.44rem);
	}

	/* Honorar bricht um, statt zu quetschen. */
	.nni-rates__row {
		flex-direction: column;
		align-items: flex-start;
		row-gap: 3px;
		padding-block: 14px;
	}

	.nni-rates__row + .nni-rates__row {
		border-top: var(--nnipp-line);
	}

	.nni-rates__slot {
		flex: 1 1 auto;
		width: 100%;
	}

	/* Umgebrochen führt die punktierte Linie ins Leere. */
	.nni-rates__slot::after {
		display: none;
	}

	.nni-rates__value {
		white-space: normal;
	}

	.nni-chip {
		min-height: 38px;
		padding-inline: 13px;
	}

	.nni-pgal {
		gap: 8px;
	}

	.nni-light {
		padding: 12px;
	}

	.nni-light__img {
		max-width: 92vw;
		max-height: 86svh;
	}

	.nni-light__close {
		width: 52px;
		height: 52px;
	}

	.nni-light__nav {
		width: 38%;
	}
}

/* Unter 34em (eine Spalte) bleibt .nni-pgal__item einfach bei 3/4 — dasselbe
   Seitenverhältnis wie überall sonst, kein eigener Fall mehr nötig. */

/* --- Sehr schmale Geräte: bis 22.5em ------------------------------------ */
@media (max-width: 22.5em) {

	.nni-phero__item {
		width: min(88vw, calc(var(--nnipp-hero-h) * 3 / 4));
	}

	.nni-pnav__list {
		gap: 18px;
	}
}

/* --- Querformat auf dem Telefon: die Kopfgalerie darf nicht die ganze
       Höhe fressen ------------------------------------------------------- */
@media (max-width: 63.999em) and (orientation: landscape) {

	.nni-body {
		--nnipp-hero-h: min(82svh, 340px);
	}

	.nni-light__img {
		max-height: 82svh;
	}
}

/* Die Galerie wechselt ab dem Schreibtisch (64em) auf drei Spalten für die
   normalen Bilder — die Regel dafür steht direkt in Abschnitt 11, bei der
   Spaltenzahl der Auszeichnung, statt hier verstreut zu stehen. */

/* --- Grosse Fenster ------------------------------------------------------
   Nachgemessen: bei 1920 Breite ist die Bahn auf 1464px begrenzt, während
   ein Bild mit 72vh auf 570px Breite wüchse — dann stünden nur noch zweieinhalb
   Hochformate nebeneinander. Die Deckelung hält drei bis vier im Blick.
   ------------------------------------------------------------------------ */
@media (min-width: 100em) {

	.nni-body {
		--nnipp-hero-h: min(64vh, 620px);
	}
}


/* ---------------------------------------------------------------------------
   14 · Weniger Bewegung
   Alles steht still. Die Kopfgalerie wird zum gewöhnlichen Wischfeld.
   ------------------------------------------------------------------------ */

@media (prefers-reduced-motion: reduce) {

	.nni-phero {
		overflow-x: auto;
		overflow-y: hidden;
		touch-action: auto;
		cursor: default;
		scroll-snap-type: x proximity;
		scrollbar-width: none;
		-ms-overflow-style: none;
	}

	.nni-phero::-webkit-scrollbar {
		width: 0;
		height: 0;
		display: none;
	}

	.nni-phero:active {
		cursor: default;
	}

	.nni-phero__row {
		transform: none !important;
		will-change: auto;
	}

	.nni-phero__item {
		scroll-snap-align: center;
	}

	.nni-phero__img {
		animation: none;
		opacity: 1;
		transform: none;
	}

	.nni-pnav__link,
	.nni-pnav__link::after,
	.nni-chip,
	.nni-pgal__img,
	.nni-light,
	.nni-light__img,
	.nni-light__close,
	.nni-light__nav,
	.nni-light__nav::before,
	.nni-more__toggle,
	.nni-more__toggle::after {
		transition: none;
	}

	.nni-pnav__link.is-current::after,
	.nni-pnav__link[aria-current]::after {
		transform: scaleX(1);
	}

	.nni-light__img {
		opacity: 1;
		transform: none;
	}

	.nni-light {
		transition: opacity 1ms linear;
	}
}


/* ---------------------------------------------------------------------------
   15 · Drucken
   Ein Profil auf Papier: schwarze Schrift auf Weiss, Bilder klein, keine
   Bedienelemente. Ergänzt den Druckabschnitt aus private.css.
   ------------------------------------------------------------------------ */

@media print {

	.nni-pnav,
	.nni-light {
		display: none !important;
	}

	.single-nni_selection .nni-main > *:has(.nni-phero, .nni-pnav, .nni-psec) {
		padding: 0;
	}

	.nni-phero {
		width: auto;
		max-width: none;
		margin-inline: 0;
		overflow: visible;
		background: none;
		break-inside: avoid;
	}

	.nni-phero::before,
	.nni-phero::after {
		display: none;
	}

	.nni-phero__row {
		width: auto;
		flex-wrap: wrap;
		gap: 4mm;
		transform: none !important;
	}

	.nni-phero__item {
		height: 52mm;
		width: 39mm;
		aspect-ratio: auto;
		background: none;
		border: 1px solid #ccc;
	}

	/* Nur die ersten vier Bilder — die Reihe ist im Markup verdoppelt. */
	.nni-phero__row > *:nth-child(n + 5) {
		display: none;
	}

	.nni-phero__img {
		animation: none;
		opacity: 1;
		transform: none;
	}

	.nni-psec {
		padding-block: 0 10mm;
		border-color: #ccc;
		break-inside: avoid;
	}

	/* SPEC11: die Anfrage-Sektion trägt am Bildschirm seit Abschnitt 9 einen
	   eigenen Flächenwechsel, mehr Innenabstand und einen Überstand bis an
	   den Fensterrand als ruhige Geste zum Schluss. Auf Papier ist all das
	   fehl am Platz — schwarze Schrift auf Weiss bleibt hier die Regel, und
	   Innenabstand wie Überstand kosten nur Blatt. Ohne diese Zeile stünde
	   .nni-psec--enquiry weiterhin unbedingt (ausserhalb jeder
	   @media-Anfrage) auf --nni-surface und über die Satzspiegelgrenze
	   hinaus, auch im Ausdruck. */
	.nni-psec--enquiry {
		width: auto;
		max-width: none;
		margin-inline: 0;
		padding-inline: 0;
		background: none;
		padding-block: 0 10mm;
	}

	.nni-psec + .nni-psec {
		border-top: 1px solid #ccc;
		padding-block-start: 8mm;
	}

	.nni-body .nni-psec__head :where(h2, h3, .nni-psec__title),
	.nni-interview__a,
	.nni-rates__value {
		color: #000;
		page-break-after: avoid;
	}

	.nni-psec__body :where(p, li),
	.nni-interview__q,
	.nni-rates__slot,
	.nni-rates__note,
	.nni-chip {
		color: #111;
	}

	.nni-interview,
	.nni-interview__q,
	.nni-interview__a {
		border-color: #ccc;
		break-inside: avoid;
	}

	.nni-vitals,
	.nni-vitals__row,
	.nni-menu__card {
		border-color: #ccc;
		break-inside: avoid;
	}

	.nni-psec__body .nni-vitals__value,
	.nni-psec__body .nni-menu__line {
		color: #000;
	}

	.nni-psec__body .nni-vitals__label,
	.nni-psec__body .nni-menu__cat,
	.nni-psec__body .nni-enq__text {
		color: #111;
	}

	/* Auf Papier führt kein Knopf irgendwohin. */
	.nni-enq__act {
		display: none;
	}

	/* SPEC11: der Aufklapper der Einleitung ist ein Bildschirm-Griff. Auf
	   Papier gibt es kein „Zuklappen" — der Rest des Portraits steht deshalb
	   immer, der Knopf verschwindet wie die übrigen Bedienelemente. */
	.nni-more__toggle {
		display: none;
	}

	.nni-more__body {
		display: block;
	}

	.nni-rates__slot::after {
		background-image: repeating-linear-gradient(90deg, #bbb 0 1px, transparent 1px 5px);
	}

	.nni-chip {
		border-color: #ccc;
	}

	.nni-pgal {
		grid-template-columns: repeat(4, minmax(0, 1fr));
		gap: 3mm;
	}

	.nni-pgal > * {
		margin-block-start: 0;
	}

	/* Die Auszeichnung spannt am Bildschirm zwei Spalten — @media
	   (min-width: 34em) trägt keine Einschränkung auf „screen" und greift
	   auch auf Papier (ein A4-Blatt misst rund 49,6em), also ohne diese Zeile
	   auch hier, über alle vier Druckspalten hinweg. Jede Kachel bleibt auf
	   Papier gleich gross; die frühere Auswahl über nth-child zielte auf ein
	   Raster, das es nicht mehr gibt, und ist ersatzlos entfallen. */
	.nni-pgal__item--feature {
		grid-column: auto;
	}

	.nni-pgal__item {
		aspect-ratio: 3 / 4;
		background: none;
		border: 1px solid #ccc;
		break-inside: avoid;
	}

	.nni-pgal > *:nth-child(n + 13) {
		display: none;
	}
}


/* ============================================================================
   NACHGEMESSEN — in Chrome über das DevTools-Protokoll gemessen, nicht
   geschätzt: neun Fenstergrössen, beide Markup-Varianten (Bilder frei oder
   in <li>, Interview als dl oder mit Paar-Hülle).

   Zeilenlängen — links das gesetzte Mass, rechts die tatsächlich gesetzten
   Zeichen der längsten Zeile (ch ist breiter als ein Durchschnittsbuchstabe):

     Fliesstext        Telefon      38ch  →  49–50 Zeichen
                       Tablet       52ch  →  70 Zeichen
                       Schreibtisch 62ch  →  84 Zeichen  (= --nni-max-text)
     Interview-Antwort Telefon      38ch  →  37 Zeichen
                       Tablet    Spalte  →  47–52 Zeichen
                       Schreibtisch 46ch  →  55 Zeichen
     Interview-Frage   Telefon   Textmass →  29 Zeichen (2 Zeilen)
                       ab 48em   15rem    →  19 Zeichen
                       ab 64em   22rem    →  29–33 Zeichen

   Kopfgalerie — Bildhöhe (--nnipp-hero-h), Breite = Höhe × 3/4:

     ACHTUNG, die drei schmalsten Zeilen sind überholt. Unter 48em trägt das
     Bild seit SPEC7 ein Seitenverhältnis von 3/4 statt einer festen Höhe:
     --nnipp-hero-h deckelt dort nur noch die Breite, die Höhe rechnet sich
     daraus. Im Prüfstand nachgemessen (siehe zweiter Messblock am Ende):
       360 × 780   317 breit · 422 hoch
       390 × 844   328 breit · 437 hoch
       414 × 896   348 breit · 464 hoch
     — jeweils schmaler als das Fenster, also weiterhin kein Seitenüberlauf.
     Welches der beiden Masse greift (84vw oder 62svh × 3/4), hängt davon ab,
     wie viel Höhe der Browser gerade für sich behält.

     360 × 780     484 hoch · 317 breit · 1,1 Bilder im Rahmen
     390 × 844     523 hoch · 328 breit · 1,2 Bilder   (62svh)
     430 × 932     578 hoch · 361 breit · 1,2 Bilder
     600 × 900     558 hoch · 419 breit · 1,4 Bilder
     768 × 1024    620 hoch · 465 breit · 1,6 Bilder   (min(64vh, 620px))
     834 × 1112    620 hoch · 465 breit · 1,8 Bilder
     1280 × 800    576 hoch · 432 breit · 2,9 Bilder   (min(72vh, 760px))
     1440 × 900    648 hoch · 486 breit · 2,9 Bilder
     1600 × 900    576 hoch · 432 breit · 3,3 Bilder   (ab 100em: min(64vh, 620px))
     1920 × 1080   620 hoch · 465 breit · 3,0 Bilder
     2560 × 1440   620 hoch · 465 breit · 3,0 Bilder
     Kein Fenster erzeugt waagerechten Seitenüberlauf (scrollWidth == clientWidth).

   Kopfzeile und Unternavigation — gemessene Kopfzeilenhöhe gegen den Wert,
   auf den --nni-head-h die klebende Leiste setzt. Die Differenz ist der
   Abstand zwischen Kopfzeilenkante und erster Textzeile der Leiste; sie darf
   nie negativ werden, sonst rutscht die Leiste unter die Kopfzeile:

     360–600 px    Kopfzeile 73,0  →  Leiste bei 76,0  →  +3,0
     768 px        Kopfzeile 75,8  →  Leiste bei 76,0  →  +0,2
     834 px        Kopfzeile 82,0  →  Leiste bei 82,0  →   0,0
     1280 px       Kopfzeile 63,9  →  Leiste bei 68,0  →  +4,1
     1440 px       Kopfzeile 66,6  →  Leiste bei 68,0  →  +1,4
     1920 px       Kopfzeile 79,9  →  Leiste bei 79,9  →   0,0
     Der Überstand von 16–18px unter der Kopfzeile schluckt die Überschätzung,
     ein Spalt entsteht dadurch nirgends.

     Sichtbare Höhe der Leiste 46px (Tap-Ziel 46px, Mindestmass 44px erfüllt).
     scroll-margin-top der Sektionen: 143px (Telefon) · 146–154px (Tablet) ·
     153–173px (Schreibtisch). scroll-padding-top des Dokuments steht auf 0,
     damit sich beide Masse nicht addieren.

   Galerie — SPEC11 hat das Raster dieser Sektion ersetzt (siehe Abschnitt 11:
   gross/klein-Wechsel statt Höhen-Variation über nth-child). Die Zeilen, die
   hier vorher standen, beschrieben das alte Raster und sind falsch geworden
   — entfernt statt stehen gelassen, damit hier nichts Überholtes als aktuell
   gemessen erscheint. Für diese Runde stand kein Prüfstand zur Verfügung;
   nachgemessen ist nur, was tinycss2 und `php -l` prüfen können: die Datei
   parst fehlerfrei, die Klammern sind ausgeglichen. Ein echter Browser-Blick
   auf 34em und 64em steht noch aus (siehe Rückmeldung am Ende des Auftrags).

   Honorar — Zeilenhöhe 67px (Schreibtisch) · 49–52px (Tablet) · 67px mit
   umgebrochener Zeile (Telefon). Der Wert steht auf 62ch rechtsbündig, die
   punktierte Führungslinie füllt 12–22px vor dem Wert aus. Auf dem Telefon
   bricht die Zeile um und die Führungslinie entfällt.

   Bausteine — 36px hoch (Telefon 38px), Radius 0, nur Haarlinie.

   Lichtansicht — Bild höchstens 92vw × 86vh:
     390 × 844    359 × 726        1440 × 900   1325 × 774
     834 × 1112   767 × 956        1920 × 1080  1766 × 929
     Schliesskreuz 48 × 48px (Telefon 52 × 52px), Notch-sicher gesetzt.
     Blätterflächen 34% der Breite (Telefon 38%), höchstens 260px; die Pfeile
     erscheinen erst ab 64em. Ohne Modifikator am Markup entscheidet die
     Reihenfolge im Dokument: erste Fläche links, jede weitere rechts — geprüft.

   Weniger Bewegung — geprüft: die Reihe steht (transform: none), die Blende
   läuft nicht, der Rahmen wird zum gewöhnlichen Wischfeld (overflow-x: auto,
   touch-action: auto).

   Drucken — geprüft: Unternavigation und Lichtansicht verschwinden, die
   Kopfgalerie zeigt vier Bilder zu 39 × 52mm, die Galerie vier Spalten im
   Format 3/4, Text #111 auf Weiss, Überschriften und Werte schwarz.
   ========================================================================= */


/* ============================================================================
   NACHGEMESSEN, ZWEITE RUNDE — die drei Sektionen aus SPEC7 (Angaben, My Menu,
   Anfrage) und die Korrekturen daneben.

   Gemessen wurde in einem Prüfstand: eine statische Seite mit demselben
   Markup, denselben Stylesheets in derselben Reihenfolge und OHNE JavaScript,
   über einen örtlichen Server im Browser aufgerufen und über das
   DevTools-Protokoll ausgelesen. Fünf Breiten: 360, 390, 414, 768, 1280.
   Was fehlt, ist die echte Installation mit echten Bildern — Bildhöhen und
   alles, was am Filestore hängt, ist hier also nicht geprüft.

   Waagerechter Seitenüberlauf: bei keiner der fünf Breiten
   (documentElement.scrollWidth == clientWidth, jeweils gleich der
   Fensterbreite). Über die Kante ragen nur die Kinder der beiden waagerecht
   scrollenden Rahmen — Kopfgalerie und Unternavigation —, und die kappt ihr
   Rahmen.

   Schriftgrade bei 360 / 390 / 414. Die erste Runde hat hier nur die Stellen
   aufgeführt, die einen Boden im Code tragen, und daraus eine Zusicherung für
   die ganze Seite gemacht — drei sichtbare Beschriftungen waren gar nicht
   erfasst. Sie stehen jetzt mit in der Liste, und die Grade sind gegen die
   angehobene Skala aus tokens.css nachgerechnet:

     Fliesstext .nni-prose p        16,00px  (mobile.css, fester Wert)
     Anfrage-Text                   16,00px  (Boden max(16px, …))
     Interview-Antwort              20,28 / 20,61 / 20,87px
     Angaben, Wert                  16,86 / 16,93 / 17,00px
     Menu, Satz                     dieselben Werte
     Angaben, Beschriftung          12,48 / 12,48 / 12,50px
     Menu, Kategorie                dieselben Werte
     Marke der Unternavigation      12,00px  (Boden greift; Skala 11,52px)
     Baustein, Honorar, Notiz,
     Interview-Frage                12,00px  (Boden greift; Skala 11,52px)
     Überzeile .nni-eyebrow         12,48 / 12,48 / 12,50px
     Knopf der Anfrage .nni-btn     dieselben Werte
     Zurück-Verweis .nni-link       dieselben Werte
     Namenszeile am Zitat           12,00px  (Boden in components.css)

     Damit ist der Boden von 16px für Fliesstext und 12px für Beschriftungen
     an jeder Stelle eingehalten — auch an den drei zuletzt genannten, die
     ihren Grad nicht aus einem Boden dieser Datei beziehen, sondern aus
     --nni-fs-xs. Diese Skala endet bei 12,48px; fiele sie je wieder darunter,
     gehören die drei Selektoren in die Bodenliste in Abschnitt 13.

   Antippbare Flächen innerhalb des Profils: keine mehr unter 44px.
     Marken der Unternavigation  43–115 × 46px — die kürzeste („Voice") war
     43px breit und bekam deshalb einen Boden von 44px.
     Knopf der Anfrage           166 × 47px
     Galeriekachel               373 × 466px
     Zurück-Verweis              161 × 46px
     Die Wortmarke im Kopf stand ausserhalb des Profils bei 37 × 12,5px und
     ist inzwischen 44 × 44px gross; die Regel dafür steht in mobile.css,
     Abschnitt 5, und wurde hier nicht angefasst.

   Klebende Leiste: bei 360, 390 und 414 gemessen als rgb(5, 5, 5) ohne
   backdrop-filter, also deckend. Oberhalb von 48em wieder Glas (0,82
   Deckkraft, blur(16px)); bei genau 768px bleibt sie deckend, weil mobile.css
   das Tablet im Hochformat zum Mobilfall zählt. Der Text der Seite scheint
   auf dem Telefon nicht mehr durch.

   Die Kopfzeile darüber trug denselben Fehler eine Ebene höher: sie war ohne
   JavaScript dauerhaft durchsichtig. Behoben in private.css, Abschnitt 2 —
   deckend ist dort jetzt der Grundzustand.

   Einrasten der Leiste: scrollLeft 0, erste Marke bei genau 20px, also am
   Innenabstand — nichts wird angeschnitten. scroll-snap-type steht auf
   „x proximity", scroll-snap-align der Marken auf „start".

   Kopfgalerie unter 48em (Seitenverhältnis 3/4 statt fester Höhe):
     360 × 780   317 × 422    390 × 844   328 × 437    414 × 896   348 × 464
     Jeweils schmaler als das Fenster.

   Angaben: SPEC11 hat die Zuordnungsliste durch ein Kachelraster ersetzt
   (Abschnitt 7: Beschriftung winzig über dem Wert, zwei Kacheln pro Zeile
   ab 360px, drei ab 34em, vier ab 48em). Die Zeilen, die hier vorher zur
   alten Liste standen, beschreiben dieses Raster nicht mehr und sind
   entfernt. Ungeprüft ist mit dieser Runde vor allem eines: ob die fünf
   langen Ausnahmefelder (complexion, tattoos, piercings, languages,
   available_in) auf 360px tatsächlich sauber über die volle Breite laufen,
   statt nur schmal in ihrer Kachel umzubrechen — dafür bräuchte es echte
   Profildaten mit einem tatsächlich langen Wert in einem dieser Felder.

   My Menu: dieselbe Lage. Die Karte trägt jetzt eine Linie links statt
   eines vollen Rahmens, die Kategorie ist kleiner, der Satz grösser
   (--nni-fs-lg statt --nnipp-fs-read) — die alten Kartenmasse oben stimmen
   nicht mehr und sind entfernt statt falsch stehen gelassen.

   Luft zwischen zwei Sektionen (Vorgabe mindestens clamp(3.5rem, 9vw, 6rem);
   gemessen als Innenabstand unten plus Innenabstand oben — VOR SPEC11, gilt
   weiterhin für alle Sektionen ausser „Enquire": die trägt seit SPEC11 mit
   Absicht mehr, siehe Abschnitt 9, und ist hier bewusst ausgenommen):
     360px   Vorgabe 56px · gemessen  88,0px
     390px   Vorgabe 56px · gemessen  88,0px
     414px   Vorgabe 56px · gemessen  91,1px
     1280px  Vorgabe 96px · gemessen 204,8px
     Der max()-Boden in .nni-psec hält das auch dann, wenn jemand die
     fliessenden Werte später nach unten dreht.

   Ohne JavaScript: der Prüfstand lädt kein einziges Skript. Alle .nni-reveal
   stehen dort auf opacity 1 und transform: none, jede Sektion ist lesbar.
   Die Regel aus base.css hält.
   ========================================================================= */


/* Ohne JavaScript läuft das Band nicht — dann muss es wenigstens wischbar sein. */
@media (scripting: none) {
	.nni-phero {
		overflow-x: auto;
		overflow-y: hidden;
		touch-action: auto;
		scroll-snap-type: x proximity;
	}

	.nni-phero__item {
		scroll-snap-align: center;
	}
}


/* ============================================================================
   SPEC11, AUFTRAG Q — NICHT NACHGEMESSEN

   Diese Runde hat vier Sektionen umgebaut: Portrait (Anlauf + Aufklapper,
   Abschnitt 4a), Angaben (Kachelraster, Abschnitt 7), My Menu (Linie statt
   Rahmen, Abschnitt 8), Anfrage (Fläche + Mitte, Abschnitt 9) und Galerie
   (gross/klein-Wechsel, Abschnitt 11). Ausserdem wurden preferences und
   repertoire in single-nni_selection.php auf parts/profile-terms.php
   umgestellt (Auftrag P), mit Rückfall auf die alten Bausteine.

   Geprüft wurde diesmal ohne Browser: `php -l` über die angefasste PHP-Datei,
   ein eigenständiger Test von nni_pf_html_blocks() mit fünf Fällen (kurzer
   Text, langer Text mit vielen Absätzen, verschachteltes Block-Editor-
   Markup, ein einzelner sehr langer Block, Umlaute) — alle wie erwartet,
   Rekonstruktion bytegleich —, und diese Datei über tinycss2 geparst: keine
   Fehler, Klammern ausgeglichen. Was fehlt, ist der Blick im Fenster: kein
   Prüfstand mit echten Profildaten stand zur Verfügung. Vor dem Ausrollen
   gehört mindestens einmal geprüft, bei 360, 768 und 1280:

     • Angaben — reissen die fünf Ausnahmefelder wirklich über die volle
       Breite, wenn ihr Wert lang ist, oder bricht die Kachel nur eng um?
     • My Menu — trägt --nni-fs-lg auf einer schmalen Karte noch gut, oder
       wirkt der Satz gequetscht?
     • Galerie — steht das gross/klein-Muster wirklich im Wechsel, oder
       verschiebt eine ungerade Bildzahl den Rhythmus sichtbar?
     • Portrait — löst ein echter, langer Redaktionstext den Aufklapper bei
       den richtigen rund 900 Zeichen aus, und bleibt der erste Absatz dabei
       immer vollständig sichtbar?
     • Anfrage — wirkt --nni-surface auf echtem Bildschirm wie eine Geste
       oder wie ein Bruch? Der Farbabstand zu --nni-black ist im Token sehr
       knapp gehalten, genau damit er das nicht wird — das gehört gesehen,
       nicht nur berechnet.
   ========================================================================= */
