/* =====================================================================
   Miguel Zumalacárregui — site stylesheet
   Dark theme, system sans-serif, single column with card components.
   ===================================================================== */

:root {
	/* Surfaces */
	--bg:            #0a0c11;
	--bg-raised:     #12151d;
	--bg-card:       #151926;
	--border:        #2a3040;
	--border-strong: #3b4358;

	/* Text */
	--text:      #e8eaf0;
	--text-soft: #c2c8d6;
	--text-mute: #9198a8;

	/* Accents: violet primary, cyan secondary */
	--accent:        #b7a2ff;
	--accent-strong: #d0c2ff;
	--accent-dim:    #8b74e8;
	--cyan:          #6fd8ee;

	--radius: 10px;
	--measure: 1000px;

	--font: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue",
	        Arial, "Noto Sans", sans-serif;
}

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

html {
	-webkit-text-size-adjust: 100%;
	scroll-behavior: smooth;
}

body {
	margin: 0;
	overflow-x: hidden;
	background: var(--bg);
	color: var(--text);
	font-family: var(--font);
	font-size: 17.5px;
	line-height: 1.65;
	text-align: left;          /* never justify */
	overflow-wrap: break-word;
	font-synthesis-weight: none;
}

/* Anything wider than the column shrinks rather than overflowing */
img, iframe, video, svg { max-width: 100%; }
img, video { height: auto; }

.wrap {
	max-width: var(--measure);
	margin: 0 auto;
	padding: 0 1.25rem;
}

/* ---- Links ---------------------------------------------------------- */

a {
	color: var(--accent);
	text-decoration: underline;
	text-decoration-thickness: 1px;
	text-underline-offset: 0.18em;
	text-decoration-color: rgba(183, 162, 255, 0.45);
	transition: color 0.12s ease, text-decoration-color 0.12s ease;
}

a:visited { color: #c3aee9; }

a:hover,
a:focus-visible {
	color: var(--cyan);
	text-decoration-color: currentColor;
}

/* Visible keyboard focus everywhere */
:focus-visible {
	outline: 2px solid var(--cyan);
	outline-offset: 3px;
	border-radius: 3px;
}

/* Skip link for keyboard and screen-reader users */
.skip-link {
	position: absolute;
	left: -9999px;
	top: 0;
	background: var(--accent);
	color: #12101c;
	padding: 0.6em 1em;
	z-index: 100;
	font-weight: 600;
	text-decoration: none;
}

.skip-link:focus {
	left: 0;
}

/* ---- Header & navigation -------------------------------------------- */

.site-header {
	border-bottom: 1px solid var(--border);
	background: linear-gradient(180deg, #0d1017, var(--bg));
	position: sticky;
	top: 0;
	z-index: 40;
	backdrop-filter: blur(6px);
}

.site-header .wrap {
	display: flex;
	flex-wrap: wrap;
	/* Centred rather than baseline-aligned: the brand carries an image beside
	   its text, and an inline-flex box takes its baseline from its first item,
	   so the mark's bottom edge -- not the name -- was being lined up with the
	   nav links. Same fix as the GLOW site. */
	align-items: center;
	gap: 0.4rem 1.5rem;
	padding-top: 0.7rem;
	padding-bottom: 0.7rem;
}

.brand {
	display: inline-flex;
	align-items: center;
	gap: 0.5rem;
	font-weight: 650;
	font-size: 1.05rem;
	letter-spacing: -0.01em;
	color: var(--text);
	text-decoration: none;
	white-space: nowrap;
}

/* Sized and nudged so the mark reads as a glyph on the same line as the
   wordmark: the M meets the cap height and the z hangs as a descender, the
   way the g in "Miguel" does. Both values are in em so they track the
   wordmark's font-size. At 1.6rem the mark overshot the caps top and bottom
   and floated free of the type. */
.brand-mark {
	width: 1.45em;
	height: 1.45em;
	transform: translateY(0.09em);
	display: block;
	flex: 0 0 auto;
}

.brand:visited { color: var(--text); }
.brand:hover    { color: var(--cyan); }

.site-nav {
	display: flex;
	flex-wrap: wrap;
	gap: 0.15rem 0.35rem;
	margin-left: auto;
}

.site-nav a {
	display: inline-block;
	padding: 0.28em 0.62em;
	border-radius: 6px;
	font-size: 0.93rem;
	color: var(--text-soft);
	text-decoration: none;
	white-space: nowrap;
}

.site-nav a:hover {
	color: var(--text);
	background: var(--bg-card);
}

/* Active page: color plus an underline bar, so it is not color-only */
.site-nav a[aria-current="page"] {
	color: var(--accent-strong);
	background: var(--bg-card);
	box-shadow: inset 0 -2px 0 var(--accent);
}

/* ---- Typography ------------------------------------------------------ */

h1, h2, h3, h4, h5 {
	margin-left: 0;                /* no heading indentation */
	line-height: 1.2;
	letter-spacing: -0.015em;
	font-weight: 640;
	overflow-wrap: break-word;
}

h1 { font-size: 2.15rem; margin: 0 0 0.6rem; }
h2 { font-size: 1.55rem; margin: 2.6rem 0 0.9rem; }
h3 { font-size: 1.2rem;  margin: 2rem 0 0.6rem; }
h4 { font-size: 1.02rem; margin: 1.6rem 0 0.4rem; color: var(--text-soft); }

h2 + h3, h3 + h4 { margin-top: 1rem; }

p { margin: 0 0 1.05em; }

ul, ol { margin: 0 0 1.05em; padding-left: 1.3em; }
li { margin-bottom: 0.35em; }

strong { font-weight: 640; }

hr {
	border: none;
	border-top: 1px solid var(--border);
	margin: 2.5rem 0;
}

small, .small { font-size: 0.86rem; color: var(--text-mute); }

code, kbd, samp {
	font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;
	font-size: 0.9em;
	background: var(--bg-card);
	border: 1px solid var(--border);
	border-radius: 4px;
	padding: 0.08em 0.35em;
}

pre {
	background: var(--bg-card);
	border: 1px solid var(--border);
	border-radius: var(--radius);
	padding: 0.9rem 1rem;
	overflow-x: auto;
}

pre code { background: none; border: none; padding: 0; }

/* Page intro paragraph under an h1 */
.lede {
	font-size: 1.12rem;
	color: var(--text-soft);
	max-width: 68ch;
}

/* A sentence naming what is further down the page, for pages short enough that
   a sticky section bar would cost more room than it saves. */
.page-toc {
	color: var(--text-mute);
	max-width: 68ch;
	margin: 1.2rem 0 1.8rem;
}

.page-head {
	padding: 2.4rem 0 0.4rem;
	border-bottom: 1px solid var(--border);
	margin-bottom: 1.6rem;
}

.eyebrow {
	text-transform: uppercase;
	letter-spacing: 0.11em;
	font-size: 0.76rem;
	font-weight: 650;
	color: var(--accent);
	margin: 0 0 0.5rem;
}

main { padding-bottom: 3rem; }

/* ---- Buttons --------------------------------------------------------- */

.btn-row {
	display: flex;
	flex-wrap: wrap;
	gap: 0.6rem;
	margin: 1.4rem 0;
}

.btn {
	display: inline-block;
	padding: 0.5em 1.05em;
	border-radius: 8px;
	border: 1px solid var(--border-strong);
	background: var(--bg-card);
	color: var(--text);
	font-size: 0.95rem;
	font-weight: 550;
	text-decoration: none;
}

.btn:visited { color: var(--text); }

.btn:hover, .btn:focus-visible {
	border-color: var(--accent);
	color: var(--accent-strong);
	background: #1b1f30;
}

.btn-primary {
	background: var(--accent);
	border-color: var(--accent);
	color: #14101f;
}

.btn-primary:visited { color: #14101f; }

.btn-primary:hover, .btn-primary:focus-visible {
	background: var(--accent-strong);
	border-color: var(--accent-strong);
	color: #14101f;
}

/* ---- Cards ----------------------------------------------------------- */

.card {
	background: var(--bg-card);
	border: 1px solid var(--border);
	border-radius: var(--radius);
	padding: 1.15rem 1.25rem;
}

.card > :last-child { margin-bottom: 0; }

.card h3, .card h4 { margin-top: 0; }

.card-title {
	margin: 0 0 0.35rem;
	font-size: 1.1rem;
	font-weight: 640;
}

.card-title a { text-decoration: none; }
.card-title a:hover { text-decoration: underline; }

.card-meta {
	font-size: 0.83rem;
	color: var(--text-mute);
	margin: 0 0 0.6rem;
}

.card-link {
	border-color: var(--border);
	display: block;
	text-decoration: none;
	color: inherit;
}

.card-link:visited { color: inherit; }

.card-link:hover, .card-link:focus-visible {
	border-color: var(--accent-dim);
	background: #1a1e2d;
}

/* Grids of cards */
.grid {
	display: grid;
	gap: 1rem;
	margin: 1.3rem 0 1.8rem;
}

/* min() guards the track floor: without it, auto-fit forces a 340px column even
   when the container is narrower, and the page scrolls sideways on small phones. */
.grid-2 { grid-template-columns: repeat(auto-fit, minmax(min(340px, 100%), 1fr)); }

/* A card that spans the whole grid, so an odd count still balances */
.card-wide { grid-column: 1 / -1; }

.card-split { display: grid; grid-template-columns: 1fr minmax(240px, 340px); gap: 1.4rem 1.8rem; align-items: center; }
.card-split > .card-col > :last-child { margin-bottom: 0; }
.card-split > .card-side { margin: 0; }
.card-split > .card-side img { width: 100%; height: auto; }

@media (max-width: 720px) {
	.card-split { display: block; }
	.card-split > .card-side { margin: 1.2rem 0 0; }
}
.grid-3 { grid-template-columns: repeat(auto-fit, minmax(min(275px, 100%), 1fr)); }

/* Compact label/value rows: keeps the software cards from turning into a
   stack of headed sections for one line of text each. */
.code-facts {
	display: grid;
	grid-template-columns: max-content 1fr;
	gap: 0.3rem 1rem;
	margin: 1.2rem 0 0;
	font-size: 0.92rem;
}

.code-facts dt {
	color: var(--text-mute);
	font-size: 0.78rem;
	text-transform: uppercase;
	letter-spacing: 0.09em;
	font-weight: 650;
	padding-top: 0.25em;
}

.code-facts dd { margin: 0; }

@media (max-width: 620px) {
	.code-facts { grid-template-columns: 1fr; gap: 0.1rem; }
	.code-facts dt { padding-top: 0.7em; }
	.code-facts dd { margin-bottom: 0.2rem; }
}

/* ---- Tags ------------------------------------------------------------ */

.tags {
	display: flex;
	flex-wrap: wrap;
	gap: 0.35rem;
	list-style: none;
	padding: 0;
	margin: 0.6rem 0 0;
}

.tag {
	font-size: 0.75rem;
	letter-spacing: 0.03em;
	padding: 0.14em 0.55em;
	border: 1px solid var(--border-strong);
	border-radius: 999px;
	color: var(--text-mute);
	margin: 0;
}

.tag-accent {
	border-color: var(--accent-dim);
	color: var(--accent);
}

/* ---- Hero (home page) ------------------------------------------------ */

.hero {
	display: grid;
	grid-template-columns: 1fr minmax(200px, 300px);
	gap: 2rem;
	align-items: start;
	/* Light at the foot: the section below brings its own 2.8rem top margin,
	   and the two do not collapse across the grid. */
	padding: 2.8rem 0 1rem;
}

/* The hero's last block is usually the button row, whose bottom margin would
   otherwise stack on top of both of those. */
.hero > div > :last-child { margin-bottom: 0; }

.hero h1 { font-size: 2.5rem; }

.hero-title {
	font-size: 1.18rem;
	font-weight: 550;
	color: var(--accent);
	margin: 0 0 1rem;
	/* One line on a wide screen; at the widths where it has to wrap, split it
	   evenly rather than leaving a single word stranded on the second line.
	   Ignored by browsers without it, which just get the default wrap. */
	text-wrap: balance;
}

.hero-portrait {
	width: 100%;
	max-width: 260px;
	aspect-ratio: 1 / 1;
	object-fit: cover;
	object-position: center 32%;
	border-radius: var(--radius);
	border: 1px solid var(--border);
	display: block;
}

.hero-portrait-caption {
	font-size: 0.8rem;
	color: var(--text-mute);
	margin-top: 0.5rem;
}

/* Photo credit laid over the foot of an image, the way the AEI credits the
   same portrait: revealed on hover, so it is there when looked for and out of
   the way otherwise. It stays in the document either way, so assistive
   technology reads it, and it is shown outright where there is no hover to
   reveal it with. The wrapper is sized to the image so the strip cannot
   outrun it. */
.portrait {
	position: relative;
	display: inline-block;
	margin: 0;
	line-height: 0;
}

.photo-credit {
	position: absolute;
	left: 0;
	right: 0;
	bottom: 0;
	padding: 3px 7px;
	font-size: 10px;
	line-height: 1.5;
	color: #fff;
	background: rgba(0, 0, 0, 0.5);
	border-radius: 0 0 var(--radius) var(--radius);
	opacity: 0;
	transition: opacity 0.15s ease;
}

.portrait:hover .photo-credit,
.portrait:focus-within .photo-credit {
	opacity: 1;
}

/* Touch screens have no hover to reveal it with */
@media (hover: none) {
	.photo-credit { opacity: 1; }
}

@media (prefers-reduced-motion: reduce) {
	.photo-credit { transition: none; }
}

/* ---- Roles strip ----------------------------------------------------- */

.roles {
	list-style: none;
	padding: 0;
	margin: 0;
	display: grid;
	gap: 0.75rem;
	grid-template-columns: repeat(auto-fit, minmax(min(215px, 100%), 1fr));
}

.roles li {
	margin: 0;
	padding: 0.75rem 0.9rem;
	border-left: 3px solid var(--accent-dim);
	background: var(--bg-raised);
	border-radius: 0 8px 8px 0;
	font-size: 0.95rem;
	line-height: 1.45;
}

.roles strong { display: block; }

.roles span { color: var(--text-mute); font-size: 0.87rem; }

/* ---- Figures --------------------------------------------------------- */

figure { margin: 1.6rem 0; max-width: 100%; }

figure img, figure video { display: block; width: 100%; border-radius: 8px; }

figcaption {
	margin-top: 0.5rem;
	font-size: 0.86rem;
	line-height: 1.5;
	color: var(--text-mute);
}

figure.float-right,
figure.float-left {
	margin-top: 0.3rem;
	margin-bottom: 1rem;
}

.float-right { float: right; margin-left: 1.6rem; }
.float-left  { float: left;  margin-right: 1.6rem; }

.center { display: block; margin-left: auto; margin-right: auto; }

/* Clear floats at the end of a section so they never bleed into the next */
.section::after,
.clearfix::after { content: ""; display: block; clear: both; }

/* ---- Einstein-predictions rosette (venn-glyph.html) ------------------ */

/* Four circles = the predictions; the dashed frame = general relativity
   itself. Everything starts dim; a `lit-<set>` class on the <svg> (baked in
   for heading glyphs, toggled by venn.js on the hero) brightens a set.
   `venn-focus` marks that a selection is active, which pushes the rest
   further back so the lit sets read as the figure, not merely brighter. */

.venn-set circle {
	fill: currentColor;
	fill-opacity: 0.14;
	stroke: currentColor;
	stroke-opacity: 0.5;
	stroke-width: 1.5;
	transition: fill-opacity 0.25s, stroke-opacity 0.25s;
}

.venn-set text {
	fill: var(--text-soft);
	font-size: 13px;
	transition: fill 0.25s;
}

.venn-set-cosmology  { color: #d9a63f; }
.venn-set-blackholes { color: #5583d9; }
.venn-set-lensing    { color: var(--accent-dim); }
.venn-set-waves      { color: #3f9d6e; }

.venn-frame {
	fill: none;
	stroke: var(--text-mute);
	stroke-opacity: 0.55;
	stroke-width: 1.5;
	stroke-dasharray: 5 5;
	transition: stroke 0.25s, stroke-opacity 0.25s;
}

.venn-flabel {
	fill: var(--text-mute);
	font-size: 10px;
	letter-spacing: 0.14em;
	transition: fill 0.25s;
}

/* While a strand is selected, unlit sets recede... */
.venn-focus .venn-set circle { fill-opacity: 0.05; stroke-opacity: 0.25; }
.venn-focus .venn-set text   { fill: var(--text-mute); }

/* ...and the lit ones come forward. */
.venn-focus.lit-cosmology  .venn-set-cosmology  circle,
.venn-focus.lit-blackholes .venn-set-blackholes circle,
.venn-focus.lit-lensing    .venn-set-lensing    circle,
.venn-focus.lit-waves      .venn-set-waves      circle {
	fill-opacity: 0.4;
	stroke-opacity: 1;
}

.venn-focus.lit-cosmology  .venn-set-cosmology  text,
.venn-focus.lit-blackholes .venn-set-blackholes text,
.venn-focus.lit-lensing    .venn-set-lensing    text,
.venn-focus.lit-waves      .venn-set-waves      text {
	fill: var(--text);
}

.venn-focus.lit-frame .venn-frame  { stroke: var(--accent); stroke-opacity: 1; }
.venn-focus.lit-frame .venn-flabel { fill: var(--accent); }

@media (prefers-reduced-motion: reduce) {
	.venn-set circle, .venn-set text, .venn-frame, .venn-flabel {
		transition: none;
	}
}

/* Hero: diagram beside the strand legend, stacking when narrow */
.venn-hero {
	display: flex;
	align-items: center;
	gap: 1rem 2rem;
	flex-wrap: wrap;
	margin: 1.6rem 0;
}

.venn-hero-svg { flex: 1 1 280px; max-width: 380px; height: auto; }

.venn-legend {
	flex: 1 1 240px;
	list-style: none;
	margin: 0;
	padding: 0;
}

.venn-legend li + li { margin-top: 0.15rem; }

.venn-legend a {
	display: block;
	padding: 0.45rem 0.7rem;
	border-left: 2px solid var(--border);
	color: var(--text-soft);
	text-decoration: none;
}

.venn-legend a:hover,
.venn-legend a:focus-visible {
	color: var(--text);
	border-left-color: var(--accent);
	background: var(--bg-raised);
}

/* Section-heading locator: the same rosette, small, linking back to the
   hero diagram (#overview) as a "you are here" that can take you home */
h2 .venn-glyph-link {
	float: right;
	display: block;
	padding: 2px 4px;
	margin: 0 0 0 1rem;
	border-radius: 8px;
	line-height: 0;
}

h2 .venn-glyph-link:hover,
h2 .venn-glyph-link:focus-visible {
	background: var(--bg-raised);
	box-shadow: 0 0 0 1px var(--border-strong);
}

h2 .venn-glyph {
	width: 76px;
	height: 60px;
}

/* Acronyms stand in for the full names at locator size, centered on their
   circles and shown only for the lit sets */
.venn-set .venn-abbr {
	display: none;
	font-size: 34px;
	font-weight: 650;
	fill: var(--text);
}

.venn-focus.lit-cosmology  .venn-set-cosmology  .venn-abbr,
.venn-focus.lit-blackholes .venn-set-blackholes .venn-abbr,
.venn-focus.lit-lensing    .venn-set-lensing    .venn-abbr,
.venn-focus.lit-waves      .venn-set-waves      .venn-abbr {
	display: inline;
}

/* ---- Responsive embeds ----------------------------------------------- */

.video {
	position: relative;
	width: 100%;
	max-width: 760px;
	margin: 1.4rem 0;
	aspect-ratio: 16 / 9;
	background: var(--bg-card);
	border-radius: 8px;
	overflow: hidden;
}

.video iframe {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	border: 0;
}

.video.embed-4x3 { aspect-ratio: 4 / 3; }

.audio-embed {
	width: 100%;
	height: 200px;
	border: 0;
	margin-bottom: 1rem;
	border-radius: 8px;
}

/* ---- Publication lists ----------------------------------------------- */

.pubs {
	list-style: none;
	padding: 0;
	margin: 0.8rem 0 1.2rem;
	border-top: 1px solid var(--border);
}

.pubs li {
	margin: 0;
	padding: 0.7rem 0;
	border-bottom: 1px solid var(--border);
	font-size: 0.95rem;
	line-height: 1.5;
}

.pubs .authors { color: var(--text-mute); display: block; font-size: 0.88rem; }

.pubs .journal { color: var(--text-mute); }

/* Where an entry carries its authors and reference in one line rather than in
   a separate .authors span, break it below the title so the titles still scan
   down the left edge. */
.pubs-stacked .journal { display: block; font-size: 0.9rem; }

/* The one-line claim a result makes, on results.html. Not .feature: that is
   the coverage line, and the two sit one above the other. */
.pubs .claim {
	display: block;
	margin-top: 0.25rem;
	color: var(--text-soft);
}

/* Year heading in the archive of featured works: the .pubs list draws its own
   top border, so the heading needs room above it rather than a rule of its
   own. */
.results-year { margin: 2.4rem 0 0; }
.results-year:first-of-type { margin-top: 0; }

/* An archive entry that carries a figure. The thumbnail is placed in the right
   column rather than written there, because it comes first in the source: on a
   narrow screen it then falls below the text instead of pushing the title down
   the page. Titles keep a common left edge whether an entry has a figure or
   not, which is what makes the list scannable. */
.pubs li.has-thumb {
	display: grid;
	grid-template-columns: 1fr 200px;
	gap: 0 1.4rem;
	align-items: start;
}

.pubs li.has-thumb .pub-body { grid-column: 1; grid-row: 1; }
.pubs li.has-thumb .pub-thumb { grid-column: 2; grid-row: 1; }

.pub-body { display: block; min-width: 0; }

/* A thumbnail is as wide as its column, but never taller than a wide one:
   the figures are mostly 2:1 strips, so the cap is what such a strip measures
   in a 200px column. A square figure at the full column width would be twice
   the height of its neighbours and leave the citation stranded beside it. */
.pub-thumb img {
	display: block;
	width: auto;
	height: auto;
	max-width: 100%;
	max-height: 104px;
	margin-left: auto;
	border-radius: 6px;
	background: #000;
}

/* Credit for a figure someone outside the author list drew */
.pub-credit {
	display: block;
	margin-top: 0.25rem;
	font-size: 0.75rem;
	color: var(--text-mute);
	text-align: right;
}

@media (max-width: 620px) {
	.pubs li.has-thumb { grid-template-columns: 1fr; gap: 0.7rem 0; }
	.pub-credit { text-align: left; }
	.pubs li.has-thumb .pub-thumb { grid-column: 1; grid-row: 2; }
	/* Below the text rather than beside it, so the figure takes the column and
	   the height cap only has to keep a square one from filling the screen. */
	.pub-thumb img { max-height: 300px; margin-left: 0; }
}

/* Institutional or press coverage of a paper, distinct from its citation */
.pubs .feature {
	display: block;
	font-size: 0.85rem;
	color: var(--text-mute);
	margin-top: 0.1rem;
}

.badge {
	display: inline-block;
	font-size: 0.72rem;
	letter-spacing: 0.03em;
	padding: 0.1em 0.5em;
	border-radius: 4px;
	background: rgba(183, 162, 255, 0.14);
	color: var(--accent);
	border: 1px solid var(--accent-dim);
	white-space: nowrap;
}

/* ---- News ------------------------------------------------------------
   Dated one-liners on the home page. The date sits in its own column so the
   list scans as a timeline rather than as prose. */

.news {
	list-style: none;
	padding: 0;
	margin: 1.1rem 0 0;
	border-top: 1px solid var(--border);
}

.news li {
	display: flex;
	gap: 0.85rem;
	padding: 0.8rem 0;
	border-bottom: 1px solid var(--border);
}

/* Narrow enough to read as a margin note rather than a column of its own.
   Tabular figures keep the years stacked even at an abbreviated width. */
.news-date {
	flex: 0 0 4.2rem;
	color: var(--text-mute);
	font-size: 0.86rem;
	font-variant-numeric: tabular-nums;
	white-space: nowrap;
	padding-top: 0.18rem;
}

.news-body { margin: 0; }

.news-links {
	color: var(--text-mute);
	font-size: 0.92rem;
}

/* Only items inside the freshness window carry this, and the template stops
   emitting it once they age out — so the motion always means something. It
   cycles between the two accents rather than the old site's yellow and pink,
   which would read as a different website. Users who ask for reduced motion
   get a still flag: see the prefers-reduced-motion block at the end. */
.news-flag {
	display: inline-block;
	font-size: 0.68rem;
	letter-spacing: 0.07em;
	text-transform: uppercase;
	font-weight: 600;
	padding: 0.15em 0.55em;
	border-radius: 4px;
	margin-right: 0.55rem;
	vertical-align: 0.1em;
	color: var(--bg);
	background: var(--accent);
	animation: news-pulse 4.5s ease-in-out infinite;
}

@keyframes news-pulse {
	0%, 100% {
		background: var(--accent);
		box-shadow: 0 0 0 0 rgba(183, 162, 255, 0.5);
	}
	50% {
		background: var(--cyan);
		box-shadow: 0 0 0.6rem 0.12rem rgba(111, 216, 238, 0.4);
	}
}

@media (max-width: 620px) {
	.news li { flex-direction: column; gap: 0.25rem; }
	.news-date { flex: none; padding-top: 0; }
}

/* Talk / link lists with an arrow marker */
.arrow-list { list-style: none; padding: 0; }

.arrow-list li {
	position: relative;
	padding-left: 1.4em;
	font-size: 0.95rem;
}

.arrow-list li::before {
	content: "↪";
	position: absolute;
	left: 0;
	color: var(--accent-dim);
}

/* ---- Section framing ------------------------------------------------- */

.section { margin: 2.8rem 0; }

/* Secondary material sits in a quieter, denser block */
.secondary {
	background: var(--bg-raised);
	border: 1px solid var(--border);
	border-radius: var(--radius);
	padding: 1.4rem 1.5rem;
}

.secondary > h3:first-child { margin-top: 0; font-size: 1.3rem; }
.secondary h4 { font-size: 1.02rem; color: var(--text-soft); }
.secondary > :last-child { margin-bottom: 0; }

/* ---- People ---------------------------------------------------------- */

/* Career-stage bands in the group list. Built from the same uppercase-accent
   vocabulary as .eyebrow so it reads as a structural label, not a heading
   competing with the h2 above it. */
.stage-heading {
	display: flex;
	align-items: center;
	gap: 0.8rem;
	margin: 2.2rem 0 1rem;
	font-size: 0.78rem;
	text-transform: uppercase;
	letter-spacing: 0.12em;
	font-weight: 650;
	/* Neutral, not accent: the accent is what marks a link, and these bands sit
	   directly above lists of names that are links. Caps, letter-spacing and
	   the trailing rule already say "heading" without borrowing that colour. */
	color: var(--text-soft);
	line-height: 1.3;
}

.stage-heading::after {
	content: "";
	flex: 1 1 auto;
	height: 1px;
	background: var(--border);
}


/* First band sits directly under the section heading */
h2 + .stage-heading { margin-top: 1.2rem; }


.person {
	display: flex;
	gap: 0.9rem;
	align-items: flex-start;
}

.person img {
	width: 62px;
	height: 62px;
	border-radius: 50%;
	object-fit: cover;
	flex: 0 0 auto;
	border: 1px solid var(--border-strong);
}

.person-avatar-fallback {
	width: 62px;
	height: 62px;
	border-radius: 50%;
	flex: 0 0 auto;
	display: grid;
	place-items: center;
	background: var(--bg-raised);
	border: 1px solid var(--border-strong);
	color: var(--accent);
	font-weight: 620;
	font-size: 0.95rem;
	letter-spacing: 0.02em;
}

.person-body { min-width: 0; }

.person-name { font-weight: 620; margin: 0 0 0.1rem; }

.person-role { font-size: 0.84rem; color: var(--text-mute); margin: 0 0 0.35rem; }

.person-note { font-size: 0.9rem; margin: 0; color: var(--text-soft); }

.person-incoming { margin: 0 0 0.4rem; }

.people-list { list-style: none; padding: 0; }

.people-list li {
	padding: 0.5rem 0;
	border-bottom: 1px solid var(--border);
	font-size: 0.94rem;
}

.people-list .next::before { content: " → "; color: var(--accent-dim); }

/* Project and software logos float right so the card text wraps around them.
   Declared before the heading in source order, which is what float needs. */
.card-logo {
	float: right;
	display: block;
	max-height: 130px;
	max-width: 300px;
	width: auto;
	margin: 0.15rem 0 1rem 1.6rem;
}

/* Cards must contain the float, or it bleeds into the next card. */
.card::after { content: ""; display: block; clear: both; }

/* Funding acknowledgement: a block of its own under the card body, so it never
   competes with the project's own logo floating opposite it. */
/* Funding acknowledgement: stacked directly under the project's own logo, at
   the same width. The card logo is height-limited (130px), so its rendered
   width follows from its aspect ratio -- 265px for the GLOW lock-up. Matching
   on width rather than height is what makes the two read as one block, since
   the two images are not the same shape. */
.funding-logo {
	float: right;
	clear: right;
	display: block;
	width: 265px;
	max-width: 100%;
	height: auto;
	margin: 0 0 1.2rem 1.6rem;
}

/* Stacked rather than side by side: funder lockups are wide (roughly 4:1
   here), so a row of them would push past the width a floated block can take
   inside a card. Matched on height, which is what makes marks of different
   aspect ratios read as equals. */
.funding-logos {
	float: right;
	clear: right;
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	gap: 0.8rem;
	margin: 0 0 1.2rem 1.6rem;
	max-width: 100%;
}

.funding-logos img {
	display: block;
	height: 48px;
	width: auto;
	max-width: 100%;
}

@media (max-width: 620px) {
	.funding-logos {
		float: none;
		margin: 0 0 1rem;
	}

	.card-logo {
		float: none;
		max-height: 76px;
		max-width: 210px;
		margin: 0 0 1rem;
	}

	.funding-logo {
		float: none;
		width: 155px; /* 76px tall at the GLOW logo's aspect ratio */
		margin: 0 0 1rem;
	}
}

/* A row of photos with mismatched aspect ratios: match on height, not width,
   so a square and a panorama sit together without one dwarfing the other. */
.photo-strip {
	display: flex;
	flex-wrap: wrap;
	gap: 1rem 1.2rem;
	align-items: flex-start;
	margin: 2rem 0 0;
}

/* display:table shrinks each figure to its image, so the caption wraps at
   the photo's width instead of spilling into the gap beside it */
.photo-strip figure { margin: 0; display: table; }

.photo-strip figcaption {
	display: table-caption;
	caption-side: bottom;
	font-size: 0.78rem;
	margin-top: 0.35rem;
}

.photo-strip img {
	height: 190px;
	width: auto;
	max-width: 100%;
	border-radius: 8px;
}

@media (max-width: 620px) {
	.photo-strip img { height: auto; width: 100%; }
}

/* ---- Logo strips ----------------------------------------------------- */

.logo-row {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 1rem 1.8rem;
	margin: 1.4rem 0;
}

.logo-row img { display: block; }

.logo-row-quiet img { opacity: 0.8; }

/* The home page's "Supported by" strip. The marks run from square to 4.5:1,
   so wordmarks get one height and square marks a taller one, which balances
   them by area rather than by height. Not .logo-row-quiet: that class dims
   every mark by a further 20%, which the AEI wordmark cannot afford. */
/* Quiet coda, not a section on the level of Research program: the heading
   borrows the footer's small-caps treatment. */
.support-heading {
	font-size: 0.78rem;
	text-transform: uppercase;
	letter-spacing: 0.11em;
	color: var(--text-mute);
	margin: 0 0 0.2rem;
}

.logo-row-support {
	gap: 1.1rem 1.5rem;
	margin-top: 1.2rem;
}

.logo-row-support img {
	height: 35px;
	width: auto;
	opacity: 0.85;
	transition: opacity 0.2s;
}

.logo-row-support .logo-tall { height: 48px; }

.logo-row-support a:hover img,
.logo-row-support a:focus-visible img { opacity: 1; }

/* Undimmed, for a mark whose own colour is already dark against this page.
   The Max Planck Minerva is thin line art in the society's green, and the
   0.85 the row applies to hold the white marks back takes it below where it
   reads. */
.logo-row-support img.logo-colour { opacity: 1; }

/* The trajectory row below it: the marks keep their colour, so they are held
   back by size and a little transparency rather than by being drained. It is
   allowed to run to two lines. */
.support-heading-past { margin-top: 2rem; }

.logo-row-past { gap: 1rem 1.5rem; }

.logo-row-past img {
	height: 28px;
	opacity: 0.8;
}

.logo-row-past .logo-tall { height: 37px; }

.logo-row-past a:hover img,
.logo-row-past a:focus-visible img { opacity: 1; }

/* Both rows span the text column rather than ending wherever the last mark
   falls, which left a quarter of the width empty and made the strip look like
   an appendix to the video above it. space-between does the spanning, so the
   marks are sized to nearly fill the column on their own and the gaps take up
   what is left.

   Only once each row fits on one line: on a wrapped row space-between would
   strand the last mark against the left edge. The supporters row measures
   about 810px unstretched, so 880px is where the column stops being able to
   hold it. The number is tied to the marks: the AEI lockup gained 40px when it
   changed to the colour version, and the threshold moved with it. */
@media (min-width: 880px) {
	.logo-row-support { justify-content: space-between; }
}

@media (max-width: 620px) {
	.logo-row-support { gap: 0.9rem 1.4rem; }
	.logo-row-support img { height: 26px; }
	.logo-row-support .logo-tall { height: 36px; }
	.logo-row-past { gap: 0.8rem 1.2rem; }
	.logo-row-past img { height: 24px; }
	.logo-row-past .logo-tall { height: 32px; }
}

@media (prefers-reduced-motion: reduce) {
	.logo-row-support img { transition: none; }
}

/* ---- Footer ---------------------------------------------------------- */

.site-footer {
	border-top: 1px solid var(--border);
	background: var(--bg-raised);
	padding: 2.2rem 0 2.6rem;
	font-size: 0.9rem;
	color: var(--text-mute);
	margin-top: 3rem;
}

/* Four fixed columns rather than auto-fit: with four items, auto-fit leaves
   one of them orphaned on a row of its own through a wide band of widths. */
.footer-grid {
	display: grid;
	gap: 1.5rem;
	grid-template-columns: repeat(4, 1fr);
}

@media (max-width: 900px) {
	.footer-grid { grid-template-columns: repeat(2, 1fr); }
}

/* Below this the ORCID line no longer fits in half a screen. */
@media (max-width: 460px) {
	.footer-grid { grid-template-columns: 1fr; }
}

.site-footer h2 {
	font-size: 0.78rem;
	text-transform: uppercase;
	letter-spacing: 0.11em;
	color: var(--text-soft);
	margin: 0 0 0.6rem;
}

.site-footer ul { list-style: none; padding: 0; margin: 0; }
.site-footer li { margin-bottom: 0.3rem; }

.footer-note {
	margin-top: 2rem;
	padding-top: 1.2rem;
	border-top: 1px solid var(--border);
	font-size: 0.83rem;
}

/* ---- Mobile ---------------------------------------------------------- */

@media (max-width: 760px) {
	body { font-size: 17px; }

	.hero {
		grid-template-columns: 1fr;
		padding-top: 1.8rem;
	}

	.hero h1 { font-size: 2rem; }

	.hero-portrait { max-width: 260px; }

	/* Portrait first would push the text down; keep text first, image after */
	.hero-media { order: 2; }

	h1 { font-size: 1.85rem; }
	h2 { font-size: 1.35rem; }

	/* Stack floated figures rather than crowding a narrow column */
	.float-left, .float-right {
		float: none;
		margin-left: 0;
		margin-right: 0;
		max-width: 100% !important;
		width: 100% !important;
	}

	.secondary { padding: 1.1rem; }

	.site-header { position: static; }

	.site-header .wrap { padding-bottom: 0.4rem; }

	.site-nav { margin-left: 0; width: 100%; }
}

/* ---- In-page section navigation -------------------------------------- */

/* Fallbacks: subnav.js measures both and overrides them. */
:root { --header-h: 54px; --subnav-h: 44px; }

.subnav {
	position: sticky;
	top: var(--header-h);
	z-index: 30;
	margin: 1.75rem 0;
	padding: 0.4rem 0;
	background: rgba(10, 12, 17, 0.94);
	-webkit-backdrop-filter: blur(6px);
	backdrop-filter: blur(6px);
	border-top: 1px solid var(--border);
	border-bottom: 1px solid var(--border);
}

.subnav ul {
	display: flex;
	flex-wrap: wrap;
	gap: 0.3rem;
	margin: 0;
	padding: 0;
	list-style: none;
}

.subnav a {
	display: block;
	padding: 0.25rem 0.7rem;
	border: 1px solid transparent;
	border-radius: 999px;
	font-size: 0.87rem;
	line-height: 1.5;
	color: var(--text-soft);
	text-decoration: none;
	white-space: nowrap;
}

.subnav a:hover {
	background: var(--bg-card);
	color: var(--text);
}

.subnav a[aria-current="true"] {
	background: var(--bg-card);
	border-color: var(--accent-dim);
	color: var(--accent-strong);
}

/* Where a page's sections are not all at the same level, a rule keeps the
   subsections of one heading reading as a group. */
.subnav li.subnav-rule {
	margin-left: 0.55rem;
	padding-left: 0.65rem;
	border-left: 1px solid var(--border-strong);
}

/* Anchor jumps must clear both sticky bars. */
.subnav ~ * [id],
.subnav ~ [id] {
	scroll-margin-top: calc(var(--header-h) + var(--subnav-h) + 0.75rem);
}

/* One scrollable line rather than three stacked rows on a phone. */
@media (max-width: 620px) {
	.subnav ul {
		flex-wrap: nowrap;
		overflow-x: auto;
		scrollbar-width: none;
	}

	.subnav ul::-webkit-scrollbar { display: none; }
}

@media print {
	.subnav { display: none; }
}

/* ---- Motion ---------------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
	html { scroll-behavior: auto; }

	*, *::before, *::after {
		animation-duration: 0.001ms !important;
		animation-iteration-count: 1 !important;
		transition-duration: 0.001ms !important;
	}
}

/* ---- Print ----------------------------------------------------------- */

@media print {
	body { background: #fff; color: #000; }
	.site-header, .site-footer, .btn-row { display: none; }
	a { color: #000; }
}
