:root {
  --bg: #0a0c12;
  --text: #e9e5dc;      /* headings, names, strong links */
  --body: #a7aab3;      /* paragraphs */
  --muted: #8b8e98;     /* labels, captions */
  --rule: #23262f;
  --warm: #f2b27a;     /* paper titles */
  --warm-hover: #ffc996;
  --accent: #ffffff;    /* monochrome: highlights are simply brighter */

  --serif: "Newsreader", "Newsreader fallback", Georgia, serif;
  --sans: "Inter", "Inter fallback", system-ui, sans-serif;
  color-scheme: dark;
}

/* Stand-ins sized to match the web fonts, so text doesn't grow when Inter/Newsreader arrive. */
@font-face { font-family: "Inter fallback"; src: local("Arial"); size-adjust: 107.8%; ascent-override: 91.5%; descent-override: 22.8%; line-gap-override: 0%; }
@font-face { font-family: "Newsreader fallback"; src: local("Georgia"); size-adjust: 102%; ascent-override: 78%; descent-override: 21%; line-gap-override: 0%; }

* { box-sizing: border-box; }
html { scroll-behavior: smooth; }
body {
  margin: 0;
  background: var(--bg);
  color: var(--body);
  font: 400 16px/1.65 var(--sans);
  -webkit-font-smoothing: antialiased;
}
a { color: inherit; }
a:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; border-radius: 2px; }
::selection { background: rgba(255, 255, 255, .22); color: #fff; }

.skip {
  position: absolute; left: 16px; top: -60px; z-index: 100;
  padding: 8px 12px; border-radius: 4px; background: var(--accent); color: var(--bg);
  font-weight: 600; text-decoration: none;
}
.skip:focus { top: 16px; }

/* ---------- Night-lights background ----------
   A stack of city images sits behind the page. One is shown at a time and they
   cross-fade in turn (site.js); the stack is taller than the screen and drifts up
   more slowly than the content as you scroll. Two bright copies sit inside soft,
   irregular "glow" clouds that follow the cursor, one trailing the other, so
   nearby lights brighten. Everything moves with transforms and opacity only, so
   nothing repaints. A shade layer keeps the reading column dark. */
.sky {
  position: fixed; left: 0; top: 0; z-index: -1;
  width: 100%; height: 100vh; height: 100lvh;
  overflow: hidden; background: #000;
}
.sky-base { position: absolute; inset: 0; }
.stack { position: absolute; left: 0; top: 0; width: 100%; height: 140%; will-change: transform; }
.sky-base .stack { filter: none; }   /* the exports are already dark: show their own pixels */
.city { position: absolute; inset: 0; opacity: 0; transition: opacity 3s ease; }
.city:first-child, .city.is-current { opacity: 1; }
.stack.is-cycling .city:not(.is-current) { opacity: 0; }
/* Each city is shown smaller than the screen ("zoomed out"), with its edges fading into
   the night. --iw is its width: 80% of the screen, but on tall, narrow screens at least
   75% of the screen height so it doesn't shrink to a sliver. --scale (per city) shrinks
   exports that were zoomed further in, so every city looks about equally sharp. The
   city's focus point (--ax, --ay: fractions of the image, e.g. downtown) sits at --fx
   across the screen, on the vertical middle of the stack. */
.city img {
  --iw: calc(max(80%, 75lvh * 9 / 7) * var(--scale, 1));
  --fx: 50%;
  position: absolute; top: 50%;
  left: calc(var(--fx) - var(--iw) * var(--ax, .5));
  width: var(--iw); height: auto; aspect-ratio: 9 / 7;
  transform: translateY(calc(var(--ay, .5) * -100%));  /* focus point on the stack's middle line */
  -webkit-mask-image:
    linear-gradient(to right, transparent, #000 14%, #000 86%, transparent),
    linear-gradient(to bottom, transparent, #000 14%, #000 86%, transparent);
  -webkit-mask-composite: source-in;
  mask-image:
    linear-gradient(to right, transparent, #000 14%, #000 86%, transparent),
    linear-gradient(to bottom, transparent, #000 14%, #000 86%, transparent);
  mask-composite: intersect;
}
@media (min-width: 1024px) {
  .city img { --fx: 40%; }  /* a little left of centre, behind the sidebar */
  [dir="rtl"] .city img { --fx: 60%; }  /* the sidebar is on the right in right-to-left languages */
}

.sky-glow {
  --r: clamp(280px, 36vmax, 560px);
  position: absolute; left: 0; top: 0;
  width: calc(var(--r) * 2); height: calc(var(--r) * 2);
  overflow: hidden;
  -webkit-mask: url("assets/glow-a.png") center / 100% 100% no-repeat;
  mask: url("assets/glow-a.png") center / 100% 100% no-repeat;
  opacity: 0; transition: opacity 1.4s ease;
  will-change: transform;
}
.sky-glow.trail {
  --r: clamp(220px, 26vmax, 420px);
  -webkit-mask-image: url("assets/glow-b.png");
  mask-image: url("assets/glow-b.png");
}
.sky.is-lit .sky-glow { opacity: 1; }
.sky.is-lit .sky-glow.trail { opacity: .8; }
.sky-lit { position: absolute; left: 0; top: 0; will-change: transform; }
.sky-lit .stack { filter: brightness(1.7); }
.sky-shade { position: absolute; inset: 0; background: rgba(0, 0, 0, .65); }
.lights-static .sky-base .stack { filter: none; }
.archive .sky-shade { background: rgba(0, 0, 0, .78); }

/* ---------- Layout: sticky sidebar + one reading column ---------- */
.layout { max-width: 1280px; margin: 0 auto; padding: 48px 24px 0; }
.sidebar { margin-bottom: 64px; text-shadow: 0 1px 10px rgba(10, 12, 18, .9), 0 0 2px rgba(10, 12, 18, .6); }
.name { margin: 0; font: 500 clamp(40px, 5vw, 52px)/1.1 var(--serif); color: var(--text); letter-spacing: -.01em; }
.name a { text-decoration: none; }
.role { margin: 12px 0 0; font: 500 18px/1.4 var(--sans); color: var(--text); }
.tagline { max-width: 340px; margin: 16px 0 0; }

.sidenav { display: none; margin-top: 64px; }
.sidenav ul { list-style: none; margin: 0; padding: 0; }
.sidenav a {
  display: inline-flex; align-items: center; gap: 16px; padding: 10px 0;
  font: 600 12px/1 var(--sans); letter-spacing: .12em; text-transform: uppercase;
  color: var(--muted); text-decoration: none;
}
.sidenav a::before { content: ""; width: 32px; height: 1px; background: currentColor; transition: width .2s ease; }
.sidenav a:hover, .sidenav a.is-active { color: var(--text); }
.sidenav a:hover::before, .sidenav a.is-active::before { width: 64px; }

.icons { display: flex; gap: 20px; list-style: none; margin: 32px 0 0; padding: 0; }
.icons a { display: block; color: var(--muted); transition: color .2s; }
.icons a:hover { color: var(--text); }
.icons svg { display: block; width: 24px; height: 24px; }

/* Names the city currently in the background, and credits the data. */
.sky-caption { margin: 20px 0 0; font: 400 12px/1.5 var(--sans); color: var(--muted); }
.sky-city {
  display: inline-block; font-size: 13px; font-weight: 500; color: var(--text); text-decoration: none;
  border-bottom: 1px solid rgba(233, 229, 220, .3); transition: opacity .4s ease, border-color .2s;
}
.sky-city:hover { border-color: var(--text); }
.sky-city:focus-visible { outline-offset: 1px; }
.sr-only {
  position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
.sky-caption.is-changing .sky-city { opacity: 0; }
.sky-source { margin: 2px 0 0; font: 400 12px/1.5 var(--sans); color: var(--muted); }

@media (min-width: 768px) {
  .layout { padding: 80px 48px 0; }
}
@media (min-width: 1024px) {
  .layout { display: flex; justify-content: space-between; gap: 64px; padding: 0 96px; }
  .sidebar {
    position: sticky; top: 0; width: 44%; height: 100vh; margin: 0; padding: 96px 0;
    display: flex; flex-direction: column; justify-content: space-between;
  }
  .sidenav { display: block; }
  .layout > main { width: 52%; padding: 96px 0 0; }
  /* Let the lights glow behind the name; darken them behind the reading column. */
  .sky-shade {
    background: linear-gradient(to right,
      rgba(0, 0, 0, .3) 0%, rgba(0, 0, 0, .35) 38%,
      rgba(0, 0, 0, .7) 48%, rgba(0, 0, 0, .7) 100%);
  }
  [dir="rtl"] .sky-shade {
    background: linear-gradient(to left,
      rgba(0, 0, 0, .3) 0%, rgba(0, 0, 0, .35) 38%,
      rgba(0, 0, 0, .7) 48%, rgba(0, 0, 0, .7) 100%);
  }
}

/* Short desktop windows: tighten the sidebar so the icons and caption stay on screen,
   and on very short ones let it scroll with the page instead of sticking. */
@media (min-width: 1024px) and (max-height: 840px) {
  .sidebar { padding: 48px 0; }
  .sidenav { margin-top: 32px; }
}
@media (min-width: 1024px) and (max-height: 640px) {
  .sidebar { position: static; height: auto; align-self: flex-start; }
}
/* Tablets: keep lines to a comfortable reading length. */
@media (max-width: 1023px) {
  main section > :not(.section-heading) { max-width: 640px; }
}

/* Language picker and the note on machine-translated pages. */
.lang-picker { display: flex; align-items: center; gap: 8px; margin-top: 16px; color: var(--muted); }
.lang-picker svg { flex: none; width: 16px; height: 16px; }
.lang-select {
  max-width: 220px; padding: 5px 8px; border-radius: 6px; cursor: pointer;
  border: 1px solid rgba(233, 229, 220, .2); background: rgba(10, 12, 18, .6); color: var(--body);
  font: 500 13px var(--sans);
}
.lang-select:hover { border-color: rgba(233, 229, 220, .4); }
.lang-select:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.mt-note { margin: 8px 0 0; font: 400 12px/1.5 var(--sans); color: var(--muted); }
.mt-note a { color: var(--body); text-decoration: underline; text-decoration-color: rgba(167, 170, 179, .45); text-underline-offset: 3px; }
.page-top { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 8px 24px; margin-bottom: 12px; }
.page-top .back { margin: 0; }
.page-top .lang-picker { margin-top: 0; }

/* ---------- Reading column ---------- */
main section { margin-bottom: 96px; scroll-margin-top: 64px; }
main p { margin: 0 0 16px; }
main p a { color: var(--text); font-weight: 500; text-decoration: none; }
main p a:hover { color: var(--accent); text-decoration: underline; text-decoration-color: rgba(255, 255, 255, .4); text-underline-offset: 3px; }

/* Section headings stick to the top on small screens; on desktop the sidebar names the sections. */
.section-heading {
  position: sticky; top: 0; z-index: 5;
  margin: 0 -24px 24px; padding: 20px 24px;
  background: rgba(10, 12, 18, .78); backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px);
  font: 600 13px/1 var(--sans); letter-spacing: .12em; text-transform: uppercase; color: var(--text);
}
@media (min-width: 768px) {
  .section-heading { margin: 0 -48px 24px; padding: 20px 48px; }
}
@media (min-width: 1024px) {
  main section { margin-bottom: 144px; scroll-margin-top: 96px; }
  .section-heading {
    position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0;
    overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
  }
}

.items { display: flex; flex-direction: column; gap: 48px; list-style: none; margin: 0; padding: 0; }
.item { position: relative; isolation: isolate; transition: opacity .25s ease; }
.item::after {
  content: ""; position: absolute; inset: -16px -24px; z-index: -1; border-radius: 8px;
  transition: background-color .25s ease, box-shadow .25s ease;
}
.item p { font-size: 15px; }
.item > p:not(.eyebrow):last-of-type, .item > :last-child { margin-bottom: 0; }
.item .eyebrow { margin: 0 0 8px; font: 600 12px/1.4 var(--sans); letter-spacing: .08em; text-transform: uppercase; color: var(--muted); }
.item-title { margin: 0 0 8px; font: 500 17px/1.4 var(--sans); color: var(--text); transition: color .2s; }
.item-link { text-decoration: none; }
/* The whole item is clickable when its title is a link. */
.item-link::before { content: ""; position: absolute; inset: -16px -24px; z-index: 1; border-radius: 8px; }
.item-link:focus-visible { outline: none; }
.item-link:focus-visible::before { outline: 2px solid var(--accent); outline-offset: 0; }
.item .byline { margin: -4px 0 8px; font-size: 14px; color: var(--muted); }

.arrow { display: inline-block; margin-inline-start: 6px; font-weight: 400; transition: transform .2s ease; }
.item-link:hover .arrow, .item-link:focus-visible .arrow, .more a:hover .arrow { transform: translateX(3px); }
/* Right-to-left pages: arrows point the other way and nudge the other way. */
[dir="rtl"] .arrow { scale: -1 1; }
/* English kept inside right-to-left pages (paper titles, abstracts, event names): let each
   block take its reading direction from its own text, so "?" and arrows land at the end. */
[dir="rtl"] .item-title[translate="no"], [dir="rtl"] .abstract p, [dir="rtl"] td[translate="no"], [dir="rtl"] .byline { unicode-bidi: plaintext; }
[dir="rtl"] [translate="no"] .arrow { scale: none; }
[dir="rtl"] .item-link:hover .arrow, [dir="rtl"] .item-link:focus-visible .arrow, [dir="rtl"] .more a:hover .arrow { transform: translateX(-3px); }

/* Full abstract, revealed on demand. Sits above the whole-card link so it can be opened and selected. */
.abstract { position: relative; z-index: 2; margin: 10px 0 0; }
.abstract summary {
  display: inline-flex; align-items: center; gap: 6px; cursor: pointer; list-style: none;
  font: 600 12px/1.4 var(--sans); letter-spacing: .08em; text-transform: uppercase; color: var(--muted);
}
.abstract summary::-webkit-details-marker { display: none; }
.abstract summary::before { content: "▸"; display: inline-block; transition: rotate .2s ease; }
[dir="rtl"] .abstract summary::before { content: "◂"; }
.abstract[open] summary::before { rotate: 90deg; }
[dir="rtl"] .abstract[open] summary::before { rotate: -90deg; }
.abstract summary:hover { color: var(--text); }
.abstract summary:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; border-radius: 2px; }
.item .abstract p { margin: 10px 0 0; max-width: 64ch; font-size: 14.5px; line-height: 1.7; color: var(--body); }

/* Papers: Abstract toggle and topic tags share one row; an opened abstract takes the full width. */
.paper-foot { display: flex; flex-wrap: wrap; align-items: center; gap: 10px 16px; margin: 14px 0 0; }
.paper-foot .abstract, .paper-foot .tags { margin: 0; }
.paper-foot .abstract[open] { flex-basis: 100%; }
.papers .item-title { color: var(--warm); }
.papers .item:hover .item-title { color: var(--warm-hover); }

.tags { display: flex; flex-wrap: wrap; gap: 8px; list-style: none; margin: 14px 0 0; padding: 0; }
.tags li {
  padding: 6px 12px; border-radius: 999px;
  background: rgba(233, 229, 220, .07); color: #cfccc5;
  font: 500 12px/1.2 var(--sans);
}

@media (min-width: 1024px) and (hover: hover) {
  .items:has(.item:hover) .item:not(:hover):not(:focus-within) { opacity: .5; }
  .item:hover::after { background: rgba(233, 229, 220, .035); box-shadow: inset 0 1px 0 rgba(233, 229, 220, .06); }
  .item:hover .item-title { color: var(--accent); }
}

.more { margin: 48px 0 0; }
.more a {
  font: 600 15px var(--sans); color: var(--text); text-decoration: none;
  border-bottom: 1px solid transparent; transition: border-color .2s;
}
.more a:hover { border-color: var(--accent); }

/* Rotating student quotes: all share one grid cell, so the box keeps the tallest quote's height. */
.quotes { display: grid; margin: 0 0 40px; }
.quote { grid-area: 1 / 1; margin: 0; transition: opacity .8s ease, visibility .8s; }
.quote:not(.is-on) { opacity: 0; visibility: hidden; }
.quote blockquote::before { content: "\201C"; }
.quote blockquote::after { content: "\201D"; }
.quote blockquote {
  margin: 0; padding-inline-start: 20px; border-inline-start: 2px solid rgba(233, 229, 220, .35);
  font: 400 17px/1.6 var(--sans); color: var(--text);
}
.quote figcaption { margin-top: 10px; padding-inline-start: 22px; font-size: 13px; color: var(--muted); }

.colophon { max-width: 440px; padding-bottom: 48px; font-size: 13px; color: var(--muted); }
.colophon a { color: var(--body); font-weight: 400; text-decoration: underline; text-decoration-color: rgba(167, 170, 179, .45); text-underline-offset: 3px; }
.colophon a:hover { color: var(--text); }

/* ---------- Broadcast log page ---------- */
.archive-main { max-width: 1280px; margin: 0 auto; padding: 64px 24px 96px; }
.back { margin: 0 0 12px; }
.back a { font: 600 14px var(--sans); color: var(--text); text-decoration: none; }
.back .arrow { margin: 0; margin-inline-end: 8px; }
.back a:hover .arrow { transform: translateX(-3px); }
[dir="rtl"] .back a:hover .arrow { transform: translateX(3px); }

.log { width: 100%; margin-top: 48px; border-collapse: separate; border-spacing: 0; text-align: start; font-size: 15px; }
.log th {
  position: sticky; top: 0; z-index: 2;
  padding: 16px 0; padding-inline-end: 16px; border-bottom: 1px solid var(--rule);
  background: rgba(10, 12, 18, .85); backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px);
  font: 600 13px var(--sans); color: var(--text);
}
.log td { padding: 14px 0; padding-inline-end: 16px; border-bottom: 1px solid var(--rule); vertical-align: baseline; }
.log .col-place { white-space: nowrap; }
.log td:first-child { color: var(--muted); font-size: 14px; white-space: nowrap; }
.log td:nth-child(2) { color: var(--text); font-weight: 500; }
.log td:last-child { font-size: 13px; }
@media (max-width: 640px) {
  .log { font-size: 13px; }
  .log td, .log th { padding-inline-end: 8px; }
  .log-wrap { overflow-x: auto; }   /* very narrow screens scroll the table sideways instead of hiding columns */
}
@media (min-width: 768px) {
  .archive-main { padding: 96px 48px; }
}
@media (min-width: 1024px) {
  .archive-main { padding: 96px; }
}

/* ---------- Cities gallery page ---------- */
.gallery-main { max-width: 1280px; margin: 0 auto; padding: 64px 24px 96px; }
.gallery-main .tagline { max-width: 560px; }
.gallery {
  display: grid; grid-template-columns: 1fr; gap: 32px 16px;
  list-style: none; margin: 48px 0 0; padding: 0;
}
.tile { display: block; color: var(--text); text-decoration: none; }
.tile img {
  display: block; width: 100%; height: auto; aspect-ratio: 9 / 7;
  border-radius: 6px; background: #04060b;
  filter: brightness(.85); transition: filter .25s ease;
}
.tile span { display: block; margin-top: 10px; font: 500 15px var(--sans); }
.tile:hover img, .tile:focus-visible img { filter: brightness(1.15); }
.gallery-credit { max-width: 640px; margin: 48px 0 0; font-size: 13px; color: var(--muted); }
@media (min-width: 600px) { .gallery { grid-template-columns: repeat(3, 1fr); } }
@media (min-width: 1024px) { .gallery { gap: 32px 24px; } }
@media (min-width: 768px) { .gallery-main { padding: 96px 48px; } }
@media (min-width: 1024px) { .gallery-main { padding: 96px; } }

/* Full-screen viewer */
.viewer {
  position: fixed; inset: 0; width: 100%; height: 100%; max-width: none; max-height: none;
  margin: 0; padding: 0; border: 0; overflow: hidden;
  background: #000003; color: var(--text);   /* the images' own black, so their edges don't show */
}
.viewer::backdrop { background: #000003; }
.viewer:not([open]) { display: none; }
.viewer { touch-action: none; overscroll-behavior: contain; }
html:has(.viewer[open]) { overflow: hidden; }
.viewer-stage { position: absolute; inset: 0; overflow: hidden; touch-action: none; cursor: zoom-in; }
.viewer-stage.is-zoomed { cursor: grab; }
.viewer-stage.is-zoomed.is-dragging { cursor: grabbing; }
.viewer-img {
  position: absolute; left: 0; top: 0; max-width: none;
  transform-origin: 0 0; will-change: transform; user-select: none; -webkit-user-select: none;
}
.viewer-hint {
  position: absolute; top: 20px; left: 64px; right: 64px; margin: 0; text-align: center;
  font-size: 12px; color: var(--muted); pointer-events: none; transition: opacity .6s ease;
  text-shadow: 0 1px 8px rgba(0, 0, 0, .9), 0 0 2px rgba(0, 0, 0, .8);
}
.viewer.is-touched .viewer-hint { opacity: 0; }
.viewer-close, .viewer-tools button {
  min-width: 40px; height: 40px; padding: 0 12px; border-radius: 999px; cursor: pointer;
  border: 1px solid rgba(233, 229, 220, .2); background: rgba(10, 12, 18, .65); color: var(--text);
  font: 500 15px/1 var(--sans);
}
.viewer-close:hover, .viewer-tools button:hover { background: rgba(233, 229, 220, .14); }
.viewer-close:focus-visible, .viewer-tools button:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.viewer-close { position: absolute; top: 12px; right: 12px; }
.viewer-bar {
  position: absolute; left: 0; right: 0; bottom: 0;
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 12px;
  padding: 32px 24px 20px; background: linear-gradient(to top, rgba(3, 4, 9, .92), rgba(3, 4, 9, 0));
  pointer-events: none;
}
.viewer-bar > * { pointer-events: auto; }
.viewer-title { margin: 0; font: 500 16px var(--sans); }
.viewer-count { margin-inline-start: 6px; font-size: 13px; font-weight: 400; color: var(--muted); }
.viewer-tools { display: flex; gap: 8px; }
[dir="rtl"] .viewer-tools [data-act="prev"], [dir="rtl"] .viewer-tools [data-act="next"] { scale: -1 1; }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after { transition: none !important; }
  .sky-base .stack { filter: none; }
}

/* Publications page: a reading-width column instead of the wide broadcast table. */
.pubs-main { max-width: 760px; }
.pubs-main .tagline { max-width: none; margin-bottom: 48px; }
