:root {
	color-scheme: light dark;

	--font-serif: ui-serif, Georgia, "Iowan Old Style", "Palatino Linotype", Palatino, "Book Antiqua", serif;
	--font-sans: ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;

	--paper:         #f1efe9;
	--card:          #fdfcfa;
	--ink:           #1c1c1e;
	--ink-soft:      #45454b;
	--muted:         #78787f;
	--rule:          #e3dfd6;
	--accent:        #156082;
	--accent-strong: #114d69;
	--pill-fg:       #ffffff;
	/* The tooltip needs its own colours. Binding it to --ink/--card made it
	   flip with the theme: a glaring near-white panel in dark mode. */
	--tip-bg:        #1c1c1e;
	--tip-fg:        #fdfcfa;
	--tip-edge:      transparent;

	/* The inline figures were authored against --acc; alias it so the
	   accent stays in one place. Custom properties resolve at use time,
	   so the dark-mode override of --accent flows through automatically. */
	--acc: var(--accent);

	/* Two rails, on purpose. The sections use the narrower one: its floor is
	   the word "PUBLICATIONS" at 112px, so 7.5rem keeps a little slack over a
	   system font stack. The masthead keeps the original 8rem, because that
	   column holds the portrait rather than a small label, and the photo and
	   its gap to the text both read better at the wider measure. The cost is
	   that the name sits ~11px right of the section text below it.
	   --date-col floors on "2020-2025" at 100px. */
	--rail: 7.5rem;
	--rail-gap: 1.7rem;
	--rail-mast: 8rem;
	--rail-mast-gap: 1.9rem;
	--date-col: 6.5rem;

	/* figure palette - the inline SVGs read these */
	--fig-bg:        #f4f3ef;
	--fig-line:      #b9b5ab;
	--fig-ghost:     #cfcbc1;

	--measure: 72rem;
	--fig-w: 240px;
}

/* Dark tokens apply when the system asks for dark and the reader has not
   forced light, or when the reader has explicitly chosen dark. */
@media (prefers-color-scheme: dark) {
	:root:not([data-theme="light"]) {
		--paper:         #121215;
		--card:          #1a1a1f;
		--ink:           #e9e7e2;
		--ink-soft:      #bcbab4;
		--muted:         #8b8b93;
		--rule:          #2e2e36;
		--accent:        #77acc5;
		--accent-strong: #92bed3;
		--pill-fg:       #10221f;   /* dark text on the light chip - white failed contrast */
		--tip-bg:        #2c2c35;
		--tip-fg:        #e9e7e2;
		--tip-edge:      #43434e;

		--fig-bg:        #202027;
		--fig-line:      #4a4a54;
		--fig-ghost:     #3a3a44;
	}
}

:root[data-theme="dark"] {
		--paper:         #121215;
		--card:          #1a1a1f;
		--ink:           #e9e7e2;
		--ink-soft:      #bcbab4;
		--muted:         #8b8b93;
		--rule:          #2e2e36;
		--accent:        #77acc5;
		--accent-strong: #92bed3;
		--pill-fg:       #10221f;   /* dark text on the light chip - white failed contrast */
		--tip-bg:        #2c2c35;
		--tip-fg:        #e9e7e2;
		--tip-edge:      #43434e;

		--fig-bg:        #202027;
		--fig-line:      #4a4a54;
		--fig-ghost:     #3a3a44;
}

/* ---------- base ---------- */

*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }

body {
	margin: 0;
	padding: clamp(0.75rem, 3vw, 3rem) clamp(0.75rem, 3vw, 2rem);
	background-color: var(--paper);
	color: var(--ink);
	font-family: var(--font-sans);
	font-size: 1rem;
	line-height: 1.6;
	-webkit-font-smoothing: antialiased;
}

.page {
	max-width: var(--measure);
	margin-inline: auto;
	padding: clamp(1.5rem, 5vw, 4rem) clamp(1.25rem, 5vw, 4rem);
	background-color: var(--card);
	border: 1px solid var(--rule);
	border-radius: 3px;
}

a {
	color: var(--accent);
	text-decoration: none;
}
/* Underline only on hover/focus. Colour alone is a weak affordance, so the
   underline still appears for anyone who reaches a link by keyboard. */
a:hover, a:focus-visible {
	color: var(--accent-strong);
	text-decoration: underline;
	text-underline-offset: 2px;
	text-decoration-thickness: 1px;
}
/* Chips carry a border already - an underline on top reads as a mistake. */
.profiles a:hover, .profiles a:focus-visible,
.pub-links a:hover, .pub-links a:focus-visible,
a.email:hover, a.email:focus-visible { text-decoration: none; }

:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; border-radius: 2px; }

/* ---------- masthead ---------- */

.masthead {
	display: grid;
	grid-template-columns: var(--rail-mast) 1fr;
	gap: 0 var(--rail-mast-gap);
	align-items: start;
	padding-bottom: 2.25rem;
	border-bottom: 1px solid var(--rule);
}

.portrait {
	width: 100%;
	/* height:auto is required, otherwise the img height attribute wins
	   over aspect-ratio and the portrait stretches. */
	height: auto;
	/* Tall crop so the photo fills the rail rather than floating in it.
	   The cut-out has no background, so it sits directly on the page and
	   follows the theme for free. Its head centroid is at 35.7% of the
	   frame; cover crops 194px of width, which puts the head mid-slice
	   at 26% - not 46%, which was right for the old uncut JPEG. */
	aspect-ratio: 0.46;
	object-fit: cover;
	object-position: 26% 50%;
	filter: saturate(0.94);
	display: block;
}

.rail-mark { display: flex; flex-direction: column; gap: 0.85rem; }

/* The business-card logo, inlined so its two fills can read the theme:
   the tile takes --accent and the pill takes --card, which makes the
   lockup invert by itself in dark mode instead of glaring white.
   It carries no size of its own - each place it appears sets that. */
.logo {
	display: block;
	width: 100%;
	height: auto;
}

/* Sign-off in the colophon. The masthead is deliberately all type and one
   photograph, so the mark closes the page instead of crowding the portrait.
   It carries its own aria-label, so the name it replaces is not lost to
   screen readers. */
.sign-mark { display: block; width: 60px; flex: none; }

/* The Impressum has no masthead, so the mark carries the identity there
   and doubles as the way back to the front page. */
.legal-mark {
	display: block;
	width: 108px;
	margin: 0 0 1.1rem;
	border: 0;
}
.legal-mark .logo { width: 100%; margin: 0; }
.legal-mark:hover .logo, .legal-mark:focus-visible .logo { opacity: 0.85; }

.name {
	font-family: var(--font-serif);
	font-weight: 600;
	font-size: clamp(2.4rem, 6vw, 4.1rem);
	line-height: 1.06;
	letter-spacing: -0.025em;
	margin: 0;
}

.role { margin: 0.7rem 0 0; font-size: 1.12rem; color: var(--ink-soft); }
.role .org { white-space: nowrap; }

/* No max-width here on purpose: the interests line and the profile row
   share the identity column, so they wrap on the same measure and their
   ragged right edges line up instead of fighting each other. */
.interests {
	margin: 1.2rem 0 0;
	max-width: 68ch;
	font-family: var(--font-serif);
	font-size: 1.22rem;
	line-height: 1.45;
	color: var(--ink);
}

.profiles {
	list-style: none;
	margin: 1.5rem 0 0;
	padding: 0;
	display: flex;
	flex-wrap: wrap;
	gap: 0.5rem;
	font-size: 0.84rem;
}
/* Same chip as the publication links - one link idiom for the whole page. */
.profiles a, .email {
	display: inline-block;
	padding: 3px 10px;
	border-radius: 2px;
	text-decoration: none;
}
.profiles a {
	color: var(--accent);
	border: 1px solid color-mix(in srgb, var(--accent) 28%, transparent);
}
.profiles a:hover, .profiles a:focus-visible {
	color: var(--accent-strong);
	border-color: var(--accent);
	background: color-mix(in srgb, var(--accent) 8%, transparent);
}
.email { color: var(--ink-soft); border: 1px solid var(--rule); }
a.email:hover, a.email:focus-visible { color: var(--accent-strong); border-color: var(--accent); }

/* ---------- sections ---------- */

.section {
	display: grid;
	grid-template-columns: var(--rail) 1fr;
	gap: 0 var(--rail-gap);
	margin-top: 3rem;
	padding-bottom: 2.75rem;
	border-bottom: 1px solid var(--rule);
	counter-reset: pub;
}
/* The colophon supplies the final rule, so the last section skips its own. */
.section:last-of-type { padding-bottom: 0; border-bottom: 0; }

/* A rail label rather than a headline, and sticky so it stays beside the
   section while a long list scrolls past. */
.section > h2 {
	grid-column: 1;
	grid-row: 1;
	margin: 0;
	padding: 0.7rem 0 0;
	border: 0;
	border-top: 2px solid var(--ink);
	font-family: var(--font-sans);
	font-size: 0.72rem;
	font-weight: 600;
	line-height: 1.4;
	letter-spacing: 0.12em;
	text-transform: uppercase;
	color: var(--ink);
	position: sticky;
	top: 1.75rem;
}
.section > *:not(h2) { grid-column: 2; }

/* Entries drop their own year rail so the page has a single spine. */
.entry {
	display: block;
	margin-bottom: 1.5rem;
	padding-bottom: 1.5rem;
	border-bottom: 1px solid var(--rule);
}
.entry:last-child { border-bottom: 0; padding-bottom: 0; margin-bottom: 0; }

.entry-year {
	margin: 0 0 0.3rem;
	padding: 0;
	color: var(--muted);
	font-size: 0.76rem;
	font-weight: 600;
	letter-spacing: 0.09em;
	text-transform: uppercase;
	font-variant-numeric: tabular-nums;
}
/* No max-width: this is a heading, and the page's other headings - the
   publication titles and the section rules - run the full column. A 62ch
   cap made a News headline wrap at 731px inside an 838px column, which
   read as an accidental break rather than a measure. */
.entry-title { margin: 0; font-size: 1.06rem; font-weight: 600; line-height: 1.4; color: var(--ink); }
/* News headlines are sentences, not labels - let the link carry the colour
   without the whole line going teal. */
.entry-title a { color: var(--accent); }

/* The three dated sections share one vertical axis: the year sits in a narrow
   left column, baseline-aligned with the first line of the entry. Top
   alignment would leave the smaller date floating high on every row. */
.section-dated .entry {
	display: grid;
	grid-template-columns: var(--date-col) 1fr;
	column-gap: 1.15rem;
	align-items: baseline;
}
/* Right-aligned: the date labels the line beside it, so a constant short
   gap to the title reads better than a constant left edge. It also stacks
   the end years of the ranges, which is the number that matters in a
   reverse-chronological list. */
.section-dated .entry-year { margin: 0; white-space: nowrap; text-align: right; }

/* News and Awards are one-line records, so the hairline between items carries
   no load - drop it and tighten the rhythm. Experience keeps its rules,
   because its entries are multi-line blocks that would otherwise run together. */
.section-tight .entry {
	margin-bottom: 0.62rem;
	padding-bottom: 0;
	border-bottom: 0;
}
.section-tight .entry:last-child { margin-bottom: 0; }

@media (max-width: 34rem) {
	/* Too narrow for two columns - a 6.5rem year column would leave about
	   120px for the text. Stack, but keep the compact rhythm. */
	.section-dated .entry { display: block; }
	.section-dated .entry-year { margin-bottom: 0.15rem; }
	.section-tight .entry { margin-bottom: 1rem; }
}
.entry-body p, .entry > p:not(.entry-year) { margin: 0.2rem 0 0; }
.entry-meta { color: var(--ink-soft); font-size: 0.95rem; max-width: 68ch; }
.entry-note { color: var(--muted); font-size: 0.9rem; max-width: 68ch; }

/* ---------- list sections (no dates) ---------- */

/* Teaching and Service are lists, not dated entries, so they deliberately
   skip the year label and the hairline rhythm the other sections use. */
.plain-list { list-style: none; margin: 0; padding: 0; }
.plain-list li {
	display: flex;
	flex-wrap: wrap;
	align-items: baseline;
	gap: 0 0.65rem;
	margin-bottom: 0.65rem;
}
.plain-list li:last-child { margin-bottom: 0; }
.plain-title { font-size: 1.06rem; font-weight: 600; line-height: 1.4; color: var(--ink); }
.plain-note { font-size: 0.88rem; color: var(--muted); }
.plain-where { margin: 1.15rem 0 0; font-size: 0.95rem; color: var(--ink-soft); max-width: 68ch; }

/* Outreach sits below the "where" line, because it does not happen at either
   university and should not look as though it does. */
.plain-list-aside { margin-top: 1.5rem; padding-top: 1.15rem; border-top: 1px solid var(--rule); }
.plain-list-aside li:last-child { margin-bottom: 0; }

.lead-in { margin: 0; font-size: 0.95rem; color: var(--ink-soft); }

/* Neutral outline, not the filled teal pill - these are venues reviewed for,
   not venues published in, and the two must not read the same. */
.venues {
	list-style: none;
	margin: 0.85rem 0 0;
	padding: 0;
	display: flex;
	flex-wrap: wrap;
	gap: 0.5rem;
}
.venues li {
	font-size: 0.84rem;
	color: var(--ink-soft);
	border: 1px solid var(--rule);
	border-radius: 2px;
	padding: 3px 10px;
}

/* ---------- publications ---------- */

.pub {
	display: grid;
	grid-template-columns: minmax(180px, var(--fig-w)) 1fr;
	grid-template-rows: auto 1fr;
	column-gap: 1.9rem;
	row-gap: 0.6rem;
	align-items: start;
	counter-increment: pub;
	margin-bottom: 2rem;
	padding-bottom: 2rem;
	border-bottom: 1px solid var(--rule);
}
.pub::before {
	content: counter(pub, decimal-leading-zero);
	grid-column: 1;
	grid-row: 1;
	font: 600 0.82rem/1 var(--font-sans);
	letter-spacing: 0.1em;
	color: var(--muted);
}
.pub-body { grid-column: 2; grid-row: 1 / span 2; }
.pub:last-of-type { margin-bottom: 0; padding-bottom: 0; border-bottom: 0; }

.fig {
	grid-column: 1;
	grid-row: 2;
	width: 100%;
	max-width: var(--fig-w);
	height: auto;
	aspect-ratio: 240 / 150;
	display: block;
	background: var(--fig-bg);
	border-radius: 3px;
}

.pub-top { margin: 0; display: flex; align-items: center; gap: 0.7rem; flex-wrap: wrap; }

.pill {
	background: var(--accent);
	color: var(--pill-fg);
	font: 600 0.66rem/1 var(--font-sans);
	letter-spacing: 0.1em;
	text-transform: uppercase;
	padding: 5px 9px;
	border-radius: 2px;
}
.pub-year {
	color: var(--muted);
	font-size: 0.8rem;
	font-weight: 600;
	letter-spacing: 0.05em;
	font-variant-numeric: tabular-nums;
}

.pub-title {
	font-family: var(--font-serif);
	font-weight: 600;
	font-size: 1.3rem;
	line-height: 1.28;
	letter-spacing: -0.01em;
	margin: 0.55rem 0 0;
}
.pub-authors { margin: 0.55rem 0 0; font-size: 0.94rem; color: var(--ink-soft); max-width: 68ch; }
.pub-authors strong { color: var(--ink); font-weight: 600; }

.pub-venue { margin: 0.35rem 0 0; font-size: 0.86rem; color: var(--muted); }

.pub-links { margin: 0.85rem 0 0; display: flex; flex-wrap: wrap; gap: 0.5rem; }
.pub-links a {
	text-decoration: none;
	font-size: 0.86rem;
	color: var(--accent);
	border: 1px solid color-mix(in srgb, var(--accent) 30%, transparent);
	border-radius: 2px;
	padding: 3px 10px;
}
.pub-links a:hover, .pub-links a:focus-visible {
	border-color: var(--accent);
	background: color-mix(in srgb, var(--accent) 8%, transparent);
}

/* The Summary control sits in the link row but is not a link, so it is
   deliberately quieter than the chips beside it: ink rather than accent,
   and a chevron that turns when it opens. */
.pub-more {
	font: inherit;
	font-size: 0.86rem;
	color: var(--ink-soft);
	background: none;
	border: 1px solid var(--rule);
	border-radius: 2px;
	padding: 3px 10px;
	cursor: pointer;
	display: inline-flex;
	align-items: center;
	gap: 0.42em;
}
.pub-more[hidden] { display: none; }   /* author display beats the UA rule */
.pub-more:hover, .pub-more:focus-visible {
	border-color: var(--ink-soft);
	background: color-mix(in srgb, var(--ink) 5%, transparent);
}
/* a chevron drawn from two borders, so it needs no glyph and no icon file */
.pub-more::after {
	content: "";
	width: 0.4em;
	height: 0.4em;
	border-right: 1.5px solid currentColor;
	border-bottom: 1.5px solid currentColor;
	transform: translateY(-0.14em) rotate(45deg);
	transition: transform 0.15s ease;
}
.pub-more[aria-expanded="true"]::after {
	transform: translateY(0.06em) rotate(-135deg);
}

.pub-summary {
	margin: 0.85rem 0 0;
	padding-left: 0.95rem;
	border-left: 2px solid color-mix(in srgb, var(--accent) 35%, transparent);
	font-family: var(--font-serif);
	font-size: 1rem;
	line-height: 1.62;
	color: var(--ink-soft);
	/* no max-width: the summary shares the column with the title and the
	   author line, and a narrower measure only makes it look ragged. */
}

.section-more { margin-top: 2rem; font-size: 0.9rem; }

/* ---------- footer ---------- */

.colophon {
	margin-top: 3.25rem;
	padding-top: 1.4rem;
	align-items: center;
	border-top: 1px solid var(--rule);
	font-size: 0.85rem;
	color: var(--muted);
	display: flex;
	flex-wrap: wrap;
	gap: 0.5rem 1rem;
	justify-content: space-between;
}

/* ---------- legal pages ---------- */

.legal-head { padding-bottom: 2.25rem; border-bottom: 2px solid var(--ink-soft); }
.legal h1 {
	font-family: var(--font-serif);
	font-weight: 600;
	font-size: clamp(1.9rem, 4vw, 2.6rem);
	letter-spacing: -0.015em;
	margin: 0;
}
/* Same rail label as the main page, but not uppercased: "gemäß" would be
   transformed to "GEMÄSS" and this is quoted statutory wording. */
.legal .section > h2 {
	text-transform: none;
	letter-spacing: 0.04em;
	font-size: 0.82rem;
}
.legal h3 { font-size: 1rem; font-weight: 600; margin: 1.6rem 0 0.35rem; }
.legal h3:first-of-type { margin-top: 0; }
.legal p { margin: 0 0 0.9rem; max-width: 68ch; color: var(--ink-soft); }
.legal .source { font-size: 0.85rem; color: var(--muted); margin-top: 1.6rem; }

/* The rail costs 158px. Below ~1024px that is width the publication row
   needs more, so the spine folds before the layout can get cramped. */
@media (max-width: 64rem) {
	.section { grid-template-columns: 1fr; gap: 0; }
	.section > h2 { position: static; margin-bottom: 1.25rem; }
	.section > *:not(h2) { grid-column: 1; }
	/* Once the rail folds, the tall portrait crop would sit alone above
	   everything as a narrow strip. Turn the masthead into an identity block
	   instead: a head-and-shoulders thumbnail beside the name and role, with
	   the lede and the link chips running full width underneath.
	   display:contents lifts the text block's children into this grid so they
	   can be placed individually; minmax(0,…) stops the text column flooring
	   at its longest word and pushing the page sideways. */
	.masthead {
		grid-template-columns: 128px minmax(0, 1fr);
		column-gap: 1.3rem;
		row-gap: 0.2rem;
		align-items: start;
	}
	.lead { display: contents; }
	.rail-mark {
		grid-column: 1;
		grid-row: 1 / span 2;
		width: 128px;
		height: 156px;
		overflow: hidden;
	}
	/* object-fit: cover can only crop one axis, so the zoom into the head is
	   done by hand: the portrait is drawn at 298px and pulled left and up
	   until the head sits in the window. Head centroid is 35.7% across. */
	.portrait {
		width: 298px;
		height: auto;
		aspect-ratio: auto;
		object-fit: fill;
		margin: -6px 0 0 -42px;
	}
	.name { grid-column: 2; grid-row: 1; }
	.role { grid-column: 2; grid-row: 2; margin-top: 0.5rem; }
	.interests, .profiles { grid-column: 1 / -1; }
	.interests { margin-top: 1.5rem; }
}

@media (max-width: 46rem) {
	.pub { grid-template-columns: 1fr; grid-template-rows: none; gap: 0.6rem 0; }
	.pub::before, .fig, .pub-body { grid-column: 1; grid-row: auto; }
	.fig { max-width: 320px; }
	.pub-title { font-size: 1.15rem; }
}

@media (max-width: 46rem) {
	/* Phone: smaller thumbnail, and the name has to clear the theme toggle
	   and still fit a 320px screen beside it, so it scales down further
	   than the global clamp. */
	.masthead { grid-template-columns: 104px minmax(0, 1fr); column-gap: 1.05rem; }
	.rail-mark { width: 104px; height: 126px; }
	.portrait { width: 242px; margin: -5px 0 0 -34px; }
	.name { padding-right: 2.6rem; font-size: clamp(1.8rem, 8.4vw, 2.6rem); }
	/* the organisation is held on one line at desktop widths; in a 160px
	   column that alone pushes the page sideways. */
	.role .org { white-space: normal; }
}

@media (max-width: 40rem) {
	.interests { font-size: 1.1rem; }
}

/* ---------- print ---------- */

@media print {
	:root {
		--paper: #fff; --card: #fff; --ink: #000; --ink-soft: #000;
		--muted: #444; --rule: #bbb; --accent: #000; --accent-strong: #000;
		--pill-fg: #fff;
	}
	body { padding: 0; font-size: 10.5pt; }
	.page { max-width: none; border: 0; padding: 0; }
	a { text-decoration: underline; }

	/* A printed CV does not need twelve figures - drop them and let the
	   text reflow to full width. */
	.fig { display: none; }
	.section { grid-template-columns: 1fr; }
	.section > h2 { position: static; grid-column: 1; margin-bottom: 0.8rem; }
	.section > *:not(h2) { grid-column: 1; }
	.pub::before { display: none; }
	.pub { grid-template-columns: 1fr; margin-bottom: 1.2rem; }
	.pill { border: 1px solid #000; color: #000 !important; background: none !important; }
	.pub-links a { border: 0; padding: 0; }
	.pub-links { gap: 0.9rem; }

	.profiles a[href]::after,
	.pub-links a[href^="http"]::after,
	.entry-meta a[href^="http"]::after {
		content: " (" attr(href) ")";
		font-size: 85%; color: #444; word-break: break-all;
	}
	.pub, .entry, .section > h2 { break-inside: avoid; }
	.section > h2 { break-after: avoid; }

	/* A printed CV stays a list of publications, not a reading list. */
	.pub-more, .pub-summary { display: none; }

	/* The print palette sets --accent to black, which would turn the logo
	   into a solid slab. Give it back its own colours, and drop the footer
	   sign-off entirely - a printed CV does not need a logo twice. */
	.logo { --accent: #156082; --card: #ffffff; }
	.sign-mark { display: none; }
}

/* ---------- theme toggle ---------- */

.page { position: relative; }

.theme-toggle {
	position: absolute;
	top: clamp(1.5rem, 5vw, 4rem);
	right: clamp(1.25rem, 5vw, 4rem);
	width: 2.1rem;
	height: 2.1rem;
	display: grid;
	place-items: center;
	padding: 0;
	cursor: pointer;
	color: var(--muted);
	background: transparent;
	border: 1px solid var(--rule);
	border-radius: 3px;
}
/* An author `display` beats the UA stylesheet's [hidden] rule, so the
   attribute has to be honoured explicitly or the button shows without JS. */
.theme-toggle[hidden] { display: none; }
.theme-toggle:hover { color: var(--accent-strong); border-color: var(--accent); }
.theme-toggle svg { width: 1.05rem; height: 1.05rem; display: block; }
.theme-toggle .icon-sun { display: none; }
:root[data-theme="dark"] .theme-toggle .icon-sun  { display: block; }
:root[data-theme="dark"] .theme-toggle .icon-moon { display: none; }

.sr-only {
	position: absolute; width: 1px; height: 1px;
	padding: 0; margin: -1px; overflow: hidden;
	clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* ---------- venue tooltip ---------- */

.pill { position: relative; }

.pill[data-full]::after {
	content: attr(data-full);
	position: absolute;
	left: 0;
	top: calc(100% + 7px);
	z-index: 5;
	width: max-content;
	max-width: 15rem;
	padding: 6px 9px;
	background: var(--tip-bg);
	color: var(--tip-fg);
	border: 1px solid var(--tip-edge);
	font: 400 0.75rem/1.35 var(--font-sans);
	letter-spacing: 0;
	text-transform: none;
	border-radius: 3px;
	opacity: 0;
	visibility: hidden;
	transition: opacity 120ms ease, visibility 0s linear 120ms;
	pointer-events: none;
}
.pill[data-full]:hover::after {
	opacity: 1;
	visibility: visible;
	transition-delay: 0s;
}

@media print { .theme-toggle { display: none; } .pill[data-full]::after { content: none; } }
