/* navid.tech — components.css
   Mobile-first. Breakpoints: 620 / 768 / 1024px. Needs tokens.css + base.css.
   Markup contract for every class: docs/DESIGN.md. */

/* Header */
.site-header {
  position: sticky; top: 0; z-index: var(--z-header);
  background-color: color-mix(in srgb, var(--bg) 88%, transparent);
  border-bottom: var(--hairline);
  backdrop-filter: saturate(160%) blur(10px);
  -webkit-backdrop-filter: saturate(160%) blur(10px);
}
@supports not (backdrop-filter: blur(4px)) { .site-header { background-color: var(--bg); } }
.site-header__inner {
  display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-md);
  min-height: var(--header-height);
}
.brand {
  display: inline-flex; align-items: center; gap: var(--space-xs); margin-inline-end: auto;
  text-decoration: none; color: var(--text); font-family: var(--font-display);
  font-size: var(--text-md); font-weight: var(--weight-semibold);
  letter-spacing: var(--tracking-snug);
}
.brand:visited { color: var(--text); }
.brand:hover .brand__name { color: var(--accent); }
.brand__logo {
  display: grid; place-items: center; width: 2rem; height: 2rem;
  color: var(--text-strong);           /* the ribbon inherits this, so it flips with the theme */
}
.brand__logo svg { width: 100%; height: 100%; display: block; }
/* the old letter-tile rule, neutralised: a cached copy of this file must not
   paint an accent tile behind the artwork */
.brand__mark { background: none; width: 2rem; height: 2rem; color: var(--text-strong); }
.brand__mark svg { width: 100%; height: 100%; display: block; }
.brand__name { transition: var(--transition-color); }
.brand__suffix { color: var(--text-muted); font-weight: var(--weight-regular); }

/* Nav: CSS-only mobile menu
   <input class="nav-toggle" type="checkbox" id="nav-toggle">
   <label class="nav-toggle-label" for="nav-toggle">
   <span class="nav-toggle-label__bars" aria-hidden="true"></span>Menu</label>
   <nav class="nav" id="site-nav" aria-label="Main"> ... </nav>
   The checkbox must be a previous sibling of .nav. No JavaScript. */
.nav-toggle { position: absolute; width: 1px; height: 1px; opacity: 0; pointer-events: none; }
.nav-toggle-label {
  display: inline-flex; align-items: center; gap: var(--space-xs);
  padding: var(--space-2xs) var(--space-sm); border: var(--hairline);
  border-radius: var(--radius-sm); background-color: var(--bg-surface);
  color: var(--text-secondary); font-size: var(--text-sm); font-weight: var(--weight-medium);
  cursor: pointer; user-select: none; transition: var(--transition-color);
}
.nav-toggle-label:hover { color: var(--accent); border-color: var(--border-accent); }
.nav-toggle:focus-visible + .nav-toggle-label {
  outline: 2px solid var(--focus-ring); outline-offset: 2px;
}
.nav-toggle-label__bars {
  position: relative; display: block; width: 1rem; height: 2px; background-color: currentColor;
  border-radius: var(--radius-pill);
  transition: background-color var(--dur-fast) var(--ease-out);
}
.nav-toggle-label__bars::before, .nav-toggle-label__bars::after {
  content: ""; position: absolute; left: 0; width: 100%; height: 2px;
  background-color: currentColor; border-radius: var(--radius-pill);
  transition: var(--transition-transform);
}
.nav-toggle-label__bars::before { top: -5px; }
.nav-toggle-label__bars::after { top: 5px; }
.nav-toggle:checked + .nav-toggle-label .nav-toggle-label__bars {
  background-color: transparent;
}
.nav-toggle:checked + .nav-toggle-label .nav-toggle-label__bars::before {
  transform: translateY(5px) rotate(45deg);
}
.nav-toggle:checked + .nav-toggle-label .nav-toggle-label__bars::after {
  transform: translateY(-5px) rotate(-45deg);
}
.nav {
  flex-basis: 100%; display: grid; grid-template-rows: 0fr;
  transition: grid-template-rows var(--dur-slow) var(--ease-out);
}
.nav > * {
  overflow: hidden; min-height: 0;
  /* Keep collapsed links out of the tab order, not just out of sight. */
  visibility: hidden; transition: visibility 0s linear var(--dur-slow);
}
.nav-toggle:checked ~ .nav > * { visibility: visible; transition-delay: 0s; }
.nav-toggle:checked ~ .nav { grid-template-rows: 1fr; }
@supports not (grid-template-rows: 0fr) {
  .nav { display: none; }
  .nav-toggle:checked ~ .nav { display: block; }
}
.nav__list {
  display: flex; flex-direction: column; gap: var(--space-3xs); margin: 0;
  padding: var(--space-xs) 0 var(--space-md); list-style: none;
}
.nav__link {
  display: block; padding: var(--space-xs) var(--space-sm); border-radius: var(--radius-sm);
  text-decoration: none; color: var(--text-secondary); font-size: var(--text-sm);
  font-weight: var(--weight-medium);
}
.nav__link:visited { color: var(--text-secondary); }
.nav__link:hover { color: var(--accent); background-color: var(--bg-subtle); }
.nav__link[aria-current="page"] {
  color: var(--accent); font-weight: var(--weight-semibold);
  background-color: var(--bg-accent-soft);
}
@media (min-width: 768px) {
  :root { --header-height: 4.25rem; }
  .nav-toggle-label { display: none; }
  .nav { flex-basis: auto; display: block; grid-template-rows: none; }
  .nav > * { overflow: visible; visibility: visible; }
  .nav__list { flex-direction: row; align-items: center; gap: var(--space-2xs); padding: 0; }
  .nav__link { position: relative; padding: var(--space-2xs) var(--space-sm); }
  .nav__link[aria-current="page"] { background-color: transparent; }
  .nav__link[aria-current="page"]::after {
    content: ""; position: absolute; left: var(--space-sm); right: var(--space-sm);
    bottom: -2px; height: 2px; background-color: var(--accent);
    border-radius: var(--radius-pill);
  }
}

/* Theme switch: ship it with [hidden]; a tiny inline script may reveal it.
   With JS off the OS preference still governs, so nothing is lost. */
.theme-toggle {
  display: inline-grid; place-items: center; width: 2.1rem; height: 2.1rem;
  border: var(--hairline); border-radius: var(--radius-sm);
  background-color: var(--bg-surface); color: var(--text-secondary); cursor: pointer;
  transition: var(--transition-color);
}
.theme-toggle:hover { color: var(--accent); border-color: var(--border-accent); }
.theme-toggle svg { width: 1rem; height: 1rem; }

/* Hero */
.hero {
  padding-block: clamp(2rem, 1rem + 6vw, 5rem) var(--space-section-tight);
  border-bottom: var(--hairline);
  background-image: radial-gradient(60rem 26rem at 88% -12%, color-mix(in srgb, var(--accent) 12%, transparent), transparent 70%);
}
.hero__inner { display: grid; gap: var(--space-xl); align-items: center; }
.hero__eyebrow {
  font-size: var(--text-xs); font-weight: var(--weight-semibold);
  letter-spacing: var(--tracking-wide); text-transform: uppercase; color: var(--accent);
}
.hero__title {
  margin-block-start: var(--space-sm); font-size: var(--text-4xl); line-height: 1.05;
}
.hero__subtitle {
  margin-block-start: var(--space-sm); max-width: var(--measure-narrow);
  font-size: var(--text-lg); line-height: var(--leading-snug); color: var(--text-secondary);
}
.hero__lede {
  margin-block-start: var(--space-md); max-width: var(--measure);
  color: var(--text-secondary);
}
.hero__actions {
  display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-sm);
  margin-block-start: var(--space-lg);
}
/* 4:5, not 1:1: it crops almost nothing off the source photo, and a
   portrait-shaped frame balances a tall text column. */
.hero__portrait {
  justify-self: start; width: min(15rem, 62%); aspect-ratio: 4 / 5; object-fit: cover;
  border-radius: var(--radius-xl); border: var(--hairline);
  box-shadow: var(--shadow-md);
}
@media (min-width: 768px) {
  .hero__inner { grid-template-columns: minmax(0, 1fr) auto; gap: var(--space-3xl); }
  .hero__portrait { width: clamp(11rem, 19vw, 15rem); }
}

/* Section heading */
.section-head { margin-block-end: var(--space-xl); }
/* A second group inside one <section> (Journal articles → Conference papers)
   otherwise starts hard against the list above it. */
:is(.pub-list, .timeline, .grid, .prose, .table-wrap, .stack) + .section-head {
  margin-block-start: var(--space-3xl);
}
.section-head__title { font-size: var(--text-2xl); }
/* The page title has to outrank the section titles under it; without this an
   h1 and an h2 in a .section-head render at exactly the same size. */
h1.section-head__title { font-size: var(--text-3xl); }
.section-head__note {
  margin-block-start: var(--space-xs); max-width: var(--measure); color: var(--text-muted);
}
.section-head > .lede { margin-block-start: var(--space-xs); max-width: var(--measure); }
.section-head--split {
  display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between;
  gap: var(--space-sm);
}

/* Grids */
.grid { display: grid; gap: var(--space-lg); grid-template-columns: 1fr; }
.grid--auto { grid-template-columns: repeat(auto-fit, minmax(min(17rem, 100%), 1fr)); }
/* Opt out of equal heights where a stretched, half-empty cell would
   read as a mistake. */
.grid--start { align-items: start; }
/* For cells holding a paragraph or two: drops to one column as soon as two
   would squeeze the measure below about 45 characters. */
.grid--wide { grid-template-columns: repeat(auto-fit, minmax(min(26rem, 100%), 1fr)); }
@media (min-width: 620px) {
  .grid--2, .grid--3 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (min-width: 1024px) { .grid--3 { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
.layout-rail { display: grid; gap: var(--space-xl); }
@media (min-width: 1024px) {
  .layout-rail { grid-template-columns: minmax(0, 1fr) 16rem; gap: var(--space-3xl); }
  .layout-rail__aside {
    position: sticky; align-self: start; top: calc(var(--header-height) + var(--space-lg));
  }
}

/* Card */
.card {
  display: flex; flex-direction: column; gap: var(--space-sm); padding: var(--space-lg);
  background-color: var(--bg-surface); border: var(--hairline);
  border-radius: var(--radius-lg); box-shadow: var(--shadow-xs);
  transition: var(--transition-shadow), var(--transition-transform), border-color var(--dur-base) var(--ease-out);
}
.card--link { position: relative; }
.card--link:hover, .card--link:focus-within {
  border-color: var(--border-accent); box-shadow: var(--shadow-md); transform: translateY(-2px);
}
.card__eyebrow {
  font-size: var(--text-2xs); font-weight: var(--weight-semibold);
  letter-spacing: var(--tracking-wide); text-transform: uppercase; color: var(--text-muted);
}
.card__title { font-size: var(--text-lg); }

/* Whole-card click target without JS: the title link stretches over the card. */
.card__title a { text-decoration: none; color: inherit; }
.card__title a::after {
  content: ""; position: absolute; inset: 0; border-radius: var(--radius-lg);
}
.card--link:hover .card__title { color: var(--accent); }
/* Ring the whole card, not the few words of the title that carry the link. */
.card__title a:focus-visible { outline: none; }
.card__title a:focus-visible::after {
  outline: 2px solid var(--focus-ring); outline-offset: 2px;
}
.card__body { color: var(--text-secondary); font-size: var(--text-sm); }
.card__footer {
  display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-xs);
  margin-block-start: auto; padding-block-start: var(--space-md);
  border-block-start: var(--hairline); font-size: var(--text-sm);
  color: var(--text-muted);
}
/* "Built with" line: the label sits above its list instead of butting into it. */
.tech { font-size: var(--text-sm); color: var(--text-secondary); }
.tech .u-eyebrow {
  display: block; margin-block-end: var(--space-3xs); color: var(--text-muted);
}
.card__cta { font-weight: var(--weight-medium); color: var(--accent); }
.card--flat { background-color: transparent; box-shadow: none; }
.card--accent { border-inline-start: 3px solid var(--accent); }
.stat { display: flex; flex-direction: column; gap: var(--space-3xs); }
.stat__value {
  font-family: var(--font-display); font-size: var(--text-2xl);
  font-weight: var(--weight-semibold); line-height: 1; color: var(--text);
  font-variant-numeric: tabular-nums;
}
.stat__label { font-size: var(--text-sm); color: var(--text-muted); }

/* Publications */
.pub-list { list-style: none; margin: 0; padding: 0; }
.pub-item {
  display: grid; gap: var(--space-2xs); padding-block: var(--space-xl);
  border-block-end: var(--hairline);
}
.pub-item:first-child { padding-block-start: 0; }
.pub-item:last-child { border-block-end: 0; }
.pub-item__title {
  font-family: var(--font-display); font-size: var(--text-lg);
  font-weight: var(--weight-semibold); line-height: var(--leading-snug); color: var(--text);
  text-wrap: balance;
}
.pub-item__title a { color: inherit; text-decoration: none; }
.pub-item__title a:hover { color: var(--accent); text-decoration: underline; }
.pub-item__authors { font-size: var(--text-sm); color: var(--text-secondary); }
.pub-item__authors .is-self { font-weight: var(--weight-semibold); color: var(--text); }
.pub-item__venue { font-size: var(--text-sm); color: var(--text-muted); font-style: italic; }
/* Type chip and status left, outbound links right: one row, two jobs,
   wrapping cleanly when there is no room. */
.pub-item__meta {
  display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-xs);
  margin-block-start: var(--space-xs); font-size: var(--text-sm);
}
.pub-item__meta .u-muted { font-size: var(--text-xs); }
.pub-item__links {
  display: flex; flex-wrap: wrap; gap: var(--space-sm); margin-inline-start: auto;
  font-size: var(--text-xs); font-weight: var(--weight-medium);
}
.pub-item__year {
  font-family: var(--font-mono); font-size: var(--text-sm); color: var(--text-muted);
  font-variant-numeric: tabular-nums; letter-spacing: var(--tracking-normal);
}
.pub-item > .stack { margin-block-start: var(--space-xs); }
@media (min-width: 768px) {
  /* The year becomes a rail: one column, one hairline, every entry aligned to
     the same edge, so the list can be skimmed by date alone. */
  .pub-item { grid-template-columns: 5rem minmax(0, 1fr); column-gap: var(--space-xl); }
  .pub-item__year {
    grid-row: 1 / span 5; padding-block-start: 0.2em;
    padding-inline-end: var(--space-xl);
    margin-inline-end: calc(var(--space-xl) * -1);
    border-inline-end: var(--hairline);
  }
}

/* Cite: a real toggle, not a stray triangle. */
.pub-item details > summary {
  display: inline-flex; align-items: center; gap: var(--space-2xs);
  width: -moz-fit-content; width: fit-content;
  padding: var(--space-3xs) var(--space-sm);
  border: var(--hairline); border-radius: var(--radius-pill);
  color: var(--accent); cursor: pointer; list-style: none;
  transition: var(--transition-color);
}
.pub-item details > summary::-webkit-details-marker { display: none; }
.pub-item details > summary::before {
  content: "+"; font-family: var(--font-mono); font-size: 1.1em; line-height: 1;
  color: var(--accent-quiet);
}
.pub-item details[open] > summary::before { content: "\2212"; }
.pub-item details > summary:hover {
  border-color: var(--border-accent); background-color: var(--bg-accent-soft);
  color: var(--accent-contrast);
}
.pub-item details[open] > summary { margin-block-end: var(--space-sm); }
.pub-item details pre { margin-block: 0; }
.pub-year-head {
  margin-block: var(--space-2xl) var(--space-sm); font-family: var(--font-sans);
  font-size: var(--text-xs); font-weight: var(--weight-semibold);
  letter-spacing: var(--tracking-wide); text-transform: uppercase; color: var(--text-muted);
}

/* Timeline (experience, education, service) */
.timeline { list-style: none; margin: 0; padding: 0; }
.timeline__item {
  position: relative; padding-inline-start: var(--space-lg); padding-block-end: var(--space-xl);
  border-inline-start: 2px solid var(--border);
}
.timeline__item:last-child { padding-block-end: 0; border-color: transparent; }
.timeline__item::before {
  content: ""; position: absolute; inset-inline-start: -6px; top: 0.45em; width: 10px;
  height: 10px; border-radius: var(--radius-pill); background-color: var(--bg);
  border: 2px solid var(--accent-quiet);
}
.timeline__role {
  font-size: var(--text-md); font-weight: var(--weight-semibold);
  margin-block-start: var(--space-3xs);
}
.timeline__org { color: var(--text-secondary); font-size: var(--text-sm); }
.timeline__dates {
  font-family: var(--font-mono); font-size: var(--text-xs); color: var(--text-muted);
  font-variant-numeric: tabular-nums;
}
/* Role, organisation, then detail. Without this every paragraph and
   bullet inside an entry runs together into one block of grey. */
.timeline__item > :is(p, ul, ol) + :is(p, ul, ol) { margin-block-start: var(--space-sm); }
.timeline__item ul {
  padding-inline-start: var(--space-md); list-style: disc; font-size: var(--text-sm);
}
.timeline__item li::marker { color: var(--accent-quiet); }
.timeline__item li + li { margin-block-start: var(--space-2xs); }
.timeline__item .tech { margin-block-start: var(--space-sm); }

/* Tags and pills */
.tag-list {
  display: flex; flex-wrap: wrap; gap: var(--space-2xs); list-style: none; margin: 0;
  padding: 0;
}
.tag, .pill {
  display: inline-flex; align-items: center; gap: var(--space-3xs); padding: 0.18em 0.62em;
  border-radius: var(--radius-pill); font-size: var(--text-xs);
  font-weight: var(--weight-medium); line-height: 1.5; white-space: nowrap;
}
.tag { background-color: var(--bg-accent-soft); color: var(--accent-contrast); }
a.tag { text-decoration: none; }
a.tag:hover {
  background-color: color-mix(in srgb, var(--accent) 22%, var(--bg-accent-soft));
  color: var(--accent-contrast);
}
.pill {
  background-color: var(--bg-subtle); color: var(--text-secondary);
  border: var(--hairline);
}
.pill--warm {
  background-color: var(--bg-warm-soft); color: var(--highlight); border-color: transparent;
}
.pill--outline { background-color: transparent; }
.tag--lg, .pill--lg { font-size: var(--text-sm); padding: 0.28em 0.8em; }

/* Buttons */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--space-xs);
  min-height: 2.75rem; /* 44px touch target */
  padding: var(--space-xs) var(--space-lg); border: var(--border-width) solid transparent;
  border-radius: var(--radius-sm); font-size: var(--text-sm);
  font-weight: var(--weight-semibold); line-height: 1.2; text-align: center;
  text-decoration: none; cursor: pointer;
  transition: var(--transition-color), var(--transition-shadow), var(--transition-transform);
}
.btn:active { transform: translateY(1px); }
.btn svg { width: 1em; height: 1em; }
.btn--primary, .btn--primary:visited {
  background-color: var(--accent); color: var(--text-on-accent); box-shadow: var(--shadow-xs);
}
.btn--primary:hover {
  background-color: var(--accent-hover); color: var(--text-on-accent);
  box-shadow: var(--shadow-sm);
}
.btn--secondary, .btn--secondary:visited {
  background-color: var(--bg-surface); color: var(--text); border-color: var(--border-strong);
}
.btn--secondary:hover { border-color: var(--accent); color: var(--accent); }
/* No box of its own, so a filled button's padding leaves it floating. */
.btn--ghost, .btn--ghost:visited {
  color: var(--accent); background-color: transparent; padding-inline: var(--space-md);
}
.btn--ghost:hover { background-color: var(--bg-accent-soft); color: var(--accent-contrast); }
.btn--sm {
  min-height: 2.25rem; padding: var(--space-3xs) var(--space-sm); font-size: var(--text-xs);
}
.btn--block { width: 100%; }
.btn[aria-disabled="true"] { opacity: 0.55; pointer-events: none; }

/* Tables */
.table-wrap {
  overflow-x: auto;
  border: var(--hairline); border-radius: var(--radius-md);
}
table {
  width: 100%; border-collapse: collapse; font-size: var(--text-sm);
  background-color: var(--bg-surface);
}
caption {
  padding-block-end: var(--space-xs); color: var(--text-muted); font-size: var(--text-sm);
  text-align: start;
}
th, td {
  padding: var(--space-sm) var(--space-md); text-align: start; vertical-align: top;
  border-block-end: var(--hairline);
}
thead th {
  position: sticky; top: 0; background-color: var(--bg-subtle); color: var(--text);
  font-size: var(--text-xs); font-weight: var(--weight-semibold);
  letter-spacing: var(--tracking-wide); text-transform: uppercase; white-space: nowrap;
}
tbody tr:last-child :is(th, td) { border-block-end: 0; }
tbody tr:hover { background-color: color-mix(in srgb, var(--accent) 5%, transparent); }
td.num, th.num {
  text-align: end; font-variant-numeric: tabular-nums; font-family: var(--font-mono);
}

/* Blockquote and callout */
blockquote {
  margin-block: var(--space-xl); padding: var(--space-xs) 0 var(--space-xs) var(--space-lg);
  border-inline-start: 3px solid var(--accent-quiet); color: var(--text-secondary);
  font-family: var(--font-display); font-size: var(--text-md); font-style: italic;
  line-height: var(--leading-body);
}
blockquote p + p { margin-block-start: var(--space-sm); }
blockquote cite {
  display: block; margin-block-start: var(--space-sm); font-family: var(--font-sans);
  font-size: var(--text-sm); font-style: normal; color: var(--text-muted);
}
.callout {
  padding: var(--space-md) var(--space-lg); background-color: var(--bg-subtle);
  border-inline-start: 3px solid var(--accent); border-radius: var(--radius-sm);
  font-size: var(--text-sm); color: var(--text-secondary);
}
.callout__title {
  margin-block-end: var(--space-3xs); font-family: var(--font-sans); font-size: var(--text-xs);
  font-weight: var(--weight-semibold); letter-spacing: var(--tracking-wide);
  text-transform: uppercase; color: var(--text);
}
.callout--warm {
  border-inline-start-color: var(--highlight); background-color: var(--bg-warm-soft);
}

/* Code */
code, kbd, samp {
  font-family: var(--font-mono); font-size: 0.875em; font-variant-ligatures: none;
}
:not(pre) > code {
  padding: 0.12em 0.36em; background-color: var(--bg-inset);
  border: var(--hairline); border-radius: var(--radius-xs);
  color: var(--text); word-break: break-word;
}
kbd {
  padding: 0.1em 0.4em; background-color: var(--bg-surface);
  border: var(--hairline-strong); border-block-end-width: 2px;
  border-radius: var(--radius-xs); font-size: 0.82em;
}
pre {
  overflow-x: auto; margin-block: var(--space-lg);
  padding: var(--space-md) var(--space-lg); background-color: var(--bg-subtle);
  border: var(--hairline); border-radius: var(--radius-md);
  color: var(--text); font-size: var(--text-sm); line-height: 1.55; tab-size: 2;
}
pre code { background: none; border: 0; padding: 0; font-size: 1em; }
.code-block { position: relative; }
.code-block__lang {
  position: absolute; top: var(--space-xs); inset-inline-end: var(--space-sm);
  font-family: var(--font-mono); font-size: var(--text-2xs); color: var(--text-muted);
  text-transform: lowercase;
}

/* Post meta, post list, breadcrumb */
.post-meta {
  display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-xs) var(--space-sm);
  font-size: var(--text-sm); color: var(--text-muted);
}
.post-meta > * + *::before {
  content: "\00b7"; margin-inline-end: var(--space-sm); color: var(--border-strong);
}
.post-meta time { font-variant-numeric: tabular-nums; }
.post-header { margin-block-end: var(--space-xl); }
.post-header__title { margin-block: var(--space-sm); font-size: var(--text-3xl); }
.post-list { list-style: none; margin: 0; padding: 0; }
.post-list__item {
  padding-block: var(--space-xl); border-block-end: var(--hairline);
}
.post-list__item:first-child { padding-block-start: 0; }
.post-list__item:last-child { border-block-end: 0; }
/* Date first, then the title: the same reading order as a post page header. */
.post-list__item .post-meta { margin-block-end: var(--space-2xs); }
.post-list__title { font-size: var(--text-xl); }
.post-list__title a { color: inherit; text-decoration: none; }
.post-list__title a:hover { color: var(--accent); text-decoration: underline; }
.post-list__excerpt {
  margin-block-start: var(--space-xs); max-width: var(--measure); color: var(--text-secondary);
  font-size: var(--text-md);
}
.post-list__excerpt + .tag-list { margin-block-start: var(--space-sm); }
.breadcrumb { font-size: var(--text-sm); color: var(--text-muted); }
.breadcrumb ol {
  display: flex; flex-wrap: wrap; gap: var(--space-2xs); list-style: none; margin: 0;
  padding: 0;
}
.breadcrumb li + li::before {
  content: "/"; margin-inline-end: var(--space-2xs); color: var(--border-strong);
}

/* Pagination */
.pagination {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between;
  gap: var(--space-sm); margin-block-start: var(--space-2xl);
  padding-block-start: var(--space-lg);
  border-block-start: var(--hairline); font-size: var(--text-sm);
}
.pagination__link {
  display: inline-flex; align-items: center; gap: var(--space-2xs); min-height: 2.5rem;
  padding: var(--space-3xs) var(--space-sm); border: var(--hairline);
  border-radius: var(--radius-sm); color: var(--text-secondary); text-decoration: none;
  font-weight: var(--weight-medium);
}
.pagination__link:hover { border-color: var(--border-accent); color: var(--accent); }
.pagination__link[aria-disabled="true"] { opacity: 0.45; pointer-events: none; }
.pagination__status { color: var(--text-muted); font-variant-numeric: tabular-nums; }
.pagination--prevnext { display: grid; gap: var(--space-sm); }
@media (min-width: 620px) { .pagination--prevnext { grid-template-columns: 1fr 1fr; } }
.pagination--prevnext .pagination__link {
  flex-direction: column; align-items: flex-start; padding: var(--space-sm) var(--space-md);
}
.pagination__label {
  font-size: var(--text-xs); color: var(--text-muted); text-transform: uppercase;
  letter-spacing: var(--tracking-wide);
}

/* Back to top
   Default: an in-flow link at the end of long pages (works with JS off).
   Optional: add .to-top--fixed and toggle .is-visible from a scroll handler. */
.to-top {
  display: inline-flex; align-items: center; gap: var(--space-2xs);
  padding: var(--space-3xs) var(--space-sm); font-size: var(--text-sm);
  color: var(--text-muted); text-decoration: none;
}
.to-top:hover { color: var(--accent); }
.to-top--fixed {
  position: fixed; inset-block-end: var(--space-lg); inset-inline-end: var(--space-lg);
  z-index: var(--z-sticky); width: 2.75rem; height: 2.75rem; justify-content: center;
  padding: 0; background-color: var(--bg-surface);
  border: var(--hairline); border-radius: var(--radius-pill);
  box-shadow: var(--shadow-md); opacity: 0; visibility: hidden; transform: translateY(0.5rem);
  transition: opacity var(--dur-base) var(--ease-out), transform var(--dur-base) var(--ease-out), visibility 0s linear var(--dur-base);
}
.to-top--fixed.is-visible {
  opacity: 1; visibility: visible; transform: none; transition-delay: 0s;
}

/* Footer */
.site-footer {
  /* No top margin: the last section already pays its own bottom padding, and
     the footer's rule plus its own top padding do the separating. */
  padding-block: var(--space-2xl) var(--space-xl);
  background-color: var(--bg-surface);
  border-block-start: var(--hairline); font-size: var(--text-sm);
  color: var(--text-muted);
}
.site-footer__grid { display: grid; gap: var(--space-xl); }
@media (min-width: 620px) { .site-footer__grid { grid-template-columns: 1.4fr 1fr 1fr; } }
.site-footer :is(h2, h3) {
  margin-block-end: var(--space-sm); font-family: var(--font-sans); font-size: var(--text-xs);
  font-weight: var(--weight-semibold); letter-spacing: var(--tracking-wide);
  text-transform: uppercase; color: var(--text-secondary);
}
.link-list { display: grid; gap: var(--space-2xs); list-style: none; margin: 0; padding: 0; }
/* Unclassed lists in page content (research "Related publications") run their
   items together otherwise. */
main :is(ul, ol).u-secondary > li + li { margin-block-start: var(--space-2xs); }
.link-list a, .link-list a:visited { color: var(--text-secondary); text-decoration: none; }
.link-list a:hover { color: var(--accent); text-decoration: underline; }
/* Quiet chrome in the footer; in page content it is navigation and has
   to look clickable. */
main .link-list { gap: var(--space-xs); }
main .link-list a, main .link-list a:visited { color: var(--link); }
main .link-list a:hover { color: var(--link-hover); }
.site-footer__bottom {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between;
  gap: var(--space-sm); margin-block-start: var(--space-xl);
  padding-block-start: var(--space-md);
  border-block-start: var(--hairline); font-size: var(--text-xs);
}

/* Misc */
.panel {
  padding: var(--space-lg); background-color: var(--bg-surface);
  border: var(--hairline); border-radius: var(--radius-lg);
}
/* A panel is a box in a page, not a page section: a plain heading in one
   takes the card scale. One with a class (.u-eyebrow) keeps its own size. */
.panel > :is(h2, h3):first-child:not([class]) { font-size: var(--text-lg); }
.divider {
  height: 1px; margin-block: var(--space-xl); background-color: var(--border); border: 0;
}
.cluster { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-sm); }
.cluster--between { justify-content: space-between; }
.email-link { font-family: var(--font-mono); font-size: 0.95em; word-break: break-all; }
@media (prefers-reduced-motion: reduce) { .nav { transition: none; } }

/* Research film (home page) ------------------------------------------- */
.film { position: relative; aspect-ratio: 16 / 9; max-width: 960px; border-radius: var(--radius-lg, 12px); overflow: hidden; background: var(--bg-surface, var(--bg, #fff)); box-shadow: 0 1px 2px rgb(0 0 0 / .06), 0 8px 24px rgb(0 0 0 / .08); border: 1px solid var(--border, #d9e0e4); }
.film__link, .film__frame { display: block; width: 100%; height: 100%; border: 0; }
.film__poster { display: block; width: 100%; height: 100%; object-fit: cover; }
.film__play { position: absolute; inset: 50% auto auto 50%; width: 76px; height: 76px; margin: -38px 0 0 -38px; border-radius: 50%; background: var(--accent, #0d6e71); box-shadow: 0 6px 20px rgb(0 0 0 / .25); transition: transform .15s ease, background-color .15s ease; }
.film__play::after { content: ""; position: absolute; inset: 50% auto auto 54%; transform: translate(-50%, -50%); border-style: solid; border-width: 13px 0 13px 22px; border-color: transparent transparent transparent #fff; }
.film__link:hover .film__play, .film__link:focus-visible .film__play { transform: scale(1.06); }
.film__link:focus-visible { outline: 3px solid var(--accent, #0d6e71); outline-offset: -3px; }
.film__note { margin-block-start: var(--space-sm, .75rem); color: var(--text-muted, #5b6b76); font-size: var(--text-sm, .9rem); }
@media (prefers-reduced-motion: reduce) { .film__play { transition: none; } .film__link:hover .film__play { transform: none; } }
