/* ---------------------------------------------------------------
   Shared stylesheet — Ciaran Johnson
   --------------------------------------------------------------- */

:root {
  --bg:            #fbfaf8;
  --surface:       #ffffff;
  --text:          #1c1b19;
  --text-muted:    #5f5c56;
  --text-subtle:   #8a867e;
  --accent:        #2f6b4f;
  --accent-soft:   #e8f0eb;
  --border:        #e3e0da;
  --shadow:        0 1px 2px rgba(28, 27, 25, .04), 0 8px 24px rgba(28, 27, 25, .05);
  --radius:        12px;
  --measure:       68ch;
}

@media (prefers-color-scheme: dark) {
  :root {
    --bg:          #16171a;
    --surface:     #1d1f23;
    --text:        #e9e7e3;
    --text-muted:  #a8a49c;
    --text-subtle: #7d7972;
    --accent:      #7fc39c;
    --accent-soft: #22302a;
    --border:      #2c2f34;
    --shadow:      0 1px 2px rgba(0, 0, 0, .3), 0 8px 24px rgba(0, 0, 0, .25);
  }
}

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

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Inter, Roboto,
               "Helvetica Neue", Arial, sans-serif;
  font-size: 17px;
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
}

.wrap {
  max-width: 860px;
  margin: 0 auto;
  padding: 0 24px;
}

/* ---------- Navigation ---------- */

.site-nav {
  border-bottom: 1px solid var(--border);
  background: var(--bg);
  position: sticky;
  top: 0;
  z-index: 10;
}

.site-nav .wrap {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
  min-height: 60px;
  flex-wrap: wrap;
}

.site-nav .brand {
  font-weight: 600;
  letter-spacing: -.01em;
  color: var(--text);
  text-decoration: none;
}

.site-nav ul {
  display: flex;
  gap: 22px;
  list-style: none;
  margin: 0;
  padding: 0;
  font-size: .94rem;
}

.site-nav a {
  color: var(--text-muted);
  text-decoration: none;
}

.site-nav a:hover,
.site-nav a[aria-current="page"] {
  color: var(--accent);
}

/* ---------- Headings & text ---------- */

h1, h2, h3 {
  line-height: 1.25;
  letter-spacing: -.02em;
  margin: 0 0 .4em;
}

h1 { font-size: clamp(2rem, 5vw, 2.6rem); }
h2 { font-size: 1.32rem; margin-top: 0; }
h3 { font-size: 1.05rem; }

p { margin: 0 0 1.1em; max-width: var(--measure); }

a { color: var(--accent); text-underline-offset: 3px; }
a:hover { text-decoration: none; }

.lead {
  font-size: 1.12rem;
  color: var(--text-muted);
}

.muted { color: var(--text-muted); }

/* ---------- Hero ---------- */

/* Photo left, name and intro right, columns vertically centred so the
   two sides read as one balanced block. */
.hero {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 40px;
  align-items: center;
  padding: 48px 0 44px;
}

.hero-photo {
  width: 100%;
  aspect-ratio: 4 / 3;
  object-fit: cover;
  object-position: center 45%;
  border-radius: var(--radius);
  border: 1px solid var(--border);
  box-shadow: var(--shadow);
  display: block;
}

.hero-text { min-width: 0; }

/* Slightly tighter than the global h1 so the name sits on one line
   inside the narrower column. */
.hero-text h1 {
  font-size: clamp(1.85rem, 3.2vw, 2.3rem);
  margin-bottom: .3em;
}

.affiliation {
  font-size: 1rem;
  color: var(--text-muted);
  margin: 0 0 1em;
}

.affiliation strong { color: var(--text); font-weight: 600; }

.hero-text .lead {
  font-size: 1.02rem;
  margin-bottom: 0;
}

@media (max-width: 700px) {
  .hero {
    grid-template-columns: 1fr;
    gap: 26px;
    padding: 28px 0 34px;
  }
}

/* ---------- Sections ---------- */

section { padding: 34px 0; border-top: 1px solid var(--border); }

.eyebrow {
  font-size: .76rem;
  font-weight: 600;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--text-subtle);
  margin: 0 0 .9em;
}

/* ---------- Research themes ---------- */

.themes {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
  gap: 16px;
  margin-top: 26px;
}

.theme {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 18px 20px;
}

.theme h3 { margin-bottom: .35em; font-size: .98rem; }

.theme p {
  margin: 0;
  font-size: .92rem;
  color: var(--text-muted);
  line-height: 1.55;
}

/* ---------- Publication / project cards ---------- */

.card {
  display: block;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 22px 24px;
  text-decoration: none;
  color: inherit;
  transition: border-color .15s ease, transform .15s ease, box-shadow .15s ease;
}

a.card:hover {
  border-color: var(--accent);
  transform: translateY(-2px);
  box-shadow: var(--shadow);
}

.card h3 { margin-bottom: .3em; }
.card p  { margin: 0; font-size: .94rem; color: var(--text-muted); max-width: none; }

.tag {
  display: inline-block;
  font-size: .72rem;
  font-weight: 600;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--accent);
  background: var(--accent-soft);
  border-radius: 999px;
  padding: 3px 10px;
  margin-bottom: 10px;
}

.card-more {
  display: inline-block;
  margin-top: 12px;
  font-size: .9rem;
  font-weight: 500;
  color: var(--accent);
}

/* ---------- Publication list ----------
   Lighter than .card: a reference list, hairline-separated, with the
   title as the DOI link and the site owner's name picked out in bold. */

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

.pub {
  padding: 18px 2px;
  border-bottom: 1px solid var(--border);
}

.pub h3 {
  margin: 0 0 .35em;
  font-size: 1rem;
  line-height: 1.45;
  letter-spacing: -.01em;
}

.pub h3 a { text-decoration: none; }
.pub h3 a:hover { text-decoration: underline; }

.pub p {
  margin: 0 0 .2em;
  max-width: none;
  font-size: .9rem;
  line-height: 1.5;
}

.pub p:last-child { margin-bottom: 0; }

.pub-authors { color: var(--text-muted); }
.pub-authors strong { color: var(--text); font-weight: 600; }
.pub-venue { color: var(--text-subtle); }

/* ---------- Image gallery ---------- */

.gallery {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: 20px;
  margin-top: 26px;
}

.gallery figure { margin: 0; }

.gallery img {
  width: 100%;
  height: auto;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  display: block;
}

/* ---------- Paper page ---------- */

.paper-head { padding: 56px 0 30px; }

.paper-head h1 { font-size: clamp(1.7rem, 4vw, 2.25rem); }

.authors {
  font-size: 1rem;
  color: var(--text-muted);
  margin: 0 0 .5em;
  max-width: none;
}

/* Keep a name, its affiliation and its icons on one line when wrapping. */
.authors .author { white-space: nowrap; }

.authors .sep {
  color: var(--text-subtle);
  margin: 0 .2em;
}

.author-link {
  display: inline-block;
  line-height: 0;
  vertical-align: -.15em;
  border-radius: 3px;
  transition: opacity .15s ease;
}

.author-link:hover { opacity: .75; }

.author-link svg {
  width: 1em;
  height: 1em;
}

.venue {
  font-size: .95rem;
  color: var(--text-subtle);
  margin: 0 0 1.4em;
}

.paper-links {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  list-style: none;
  margin: 0;
  padding: 0;
}

.paper-links a {
  display: inline-block;
  border: 1px solid var(--border);
  background: var(--surface);
  border-radius: 999px;
  padding: 7px 18px;
  font-size: .9rem;
  font-weight: 500;
  color: var(--text);
  text-decoration: none;
}

.paper-links a:hover { border-color: var(--accent); color: var(--accent); }

figure {
  margin: 0 0 1.4em;
  padding: 0;
}

figure img {
  width: 100%;
  height: auto;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  display: block;
}

figcaption {
  font-size: .88rem;
  color: var(--text-subtle);
  margin-top: 10px;
  line-height: 1.5;
}

/* Placeholder box for content still to be written */
.placeholder {
  border: 1px dashed var(--border);
  border-radius: var(--radius);
  padding: 20px 22px;
  color: var(--text-subtle);
  font-size: .93rem;
  background: transparent;
}

.placeholder p:last-child { margin-bottom: 0; }

pre {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 18px 20px;
  overflow-x: auto;
  font-size: .85rem;
  line-height: 1.6;
}

code { font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace; }

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

footer {
  border-top: 1px solid var(--border);
  margin-top: 20px;
  padding: 28px 0 48px;
  font-size: .88rem;
  color: var(--text-subtle);
}

footer p { margin: 0; }

/* ---------------------------------------------------------------
   Paper page: dataset facts, video slots
   --------------------------------------------------------------- */

/* ---------- Key-numbers grid ----------
   Facts are grouped into related sets, and sized by importance. Width comes
   from a span class (.s3/.s4/.s6/.s8) on a 12-column grid; type scale comes
   from a size class (.fact--xl / --lg, with the base .fact as the default).
   Each group's spans should add up to 12 so it forms one clean row. */

.fact-group { margin-top: 26px; }

.fact-group > h3 {
  font-size: .78rem;
  font-weight: 600;
  letter-spacing: .09em;
  text-transform: uppercase;
  color: var(--text-subtle);
  margin: 0 0 10px;
}

.facts {
  display: grid;
  grid-template-columns: repeat(12, 1fr);
  gap: 14px;
  margin: 0;
}

.fact {
  grid-column: span 4;
  display: flex;
  flex-direction: column;
  justify-content: center;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 16px 18px;
}

.fact .num {
  display: block;
  font-size: 1.32rem;
  font-weight: 600;
  letter-spacing: -.02em;
  line-height: 1.2;
  color: var(--text);
}

.fact .label {
  display: block;
  margin-top: 4px;
  font-size: .84rem;
  color: var(--text-muted);
  line-height: 1.4;
}

/* Widths */
.fact.s3 { grid-column: span 3; }
.fact.s4 { grid-column: span 4; }
.fact.s6 { grid-column: span 6; }
.fact.s8 { grid-column: span 8; }

/* Emphasis */
.fact--lg { padding: 20px 22px; }
.fact--lg .num { font-size: 1.7rem; }
.fact--lg .label { font-size: .88rem; }

.fact--xl { padding: 24px 26px; }
.fact--xl .num { font-size: 2.35rem; color: var(--accent); }
.fact--xl .label { font-size: .92rem; }

@media (max-width: 720px) {
  .fact,
  .fact.s3,
  .fact.s4 { grid-column: span 6; }
  .fact.s6,
  .fact.s8 { grid-column: span 12; }
}

@media (max-width: 440px) {
  .fact,
  .fact.s3,
  .fact.s4 { grid-column: span 12; }
}

/* Definition-style list for protocols and pipeline stages */
.deflist { margin: 0; }

.deflist dt {
  font-weight: 600;
  font-size: .97rem;
  margin-top: 18px;
}

.deflist dt:first-child { margin-top: 0; }

.deflist dd {
  margin: .3em 0 0;
  color: var(--text-muted);
  font-size: .94rem;
  max-width: var(--measure);
}

/* ---------- Video slots ----------
   A .video-slot is a 16:9 box that holds either a <video> element or,
   until the footage exists, a dashed placeholder describing what goes
   there. To publish a clip: drop the file in media/, uncomment the
   <video> block inside the slot, and delete the .video-pending div. */

.video-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 20px;
  margin-top: 22px;
}

.video-grid.two-up { grid-template-columns: repeat(auto-fit, minmax(320px, 1fr)); }

.video-item { margin: 0; }

.video-slot {
  position: relative;
  aspect-ratio: 16 / 9;
  border-radius: var(--radius);
  overflow: hidden;
  background: var(--surface);
}

.video-slot video,
.video-slot iframe {
  width: 100%;
  height: 100%;
  display: block;
  border: 0;
  object-fit: cover;
  background: #000;
  border-radius: var(--radius);
}

/* Placeholder shown while the clip is still to be recorded */
.video-pending {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 6px;
  text-align: center;
  padding: 18px;
  border: 1px dashed var(--border);
  border-radius: var(--radius);
  color: var(--text-subtle);
}

.video-pending .vp-icon {
  font-size: 1.4rem;
  line-height: 1;
  opacity: .55;
}

.video-pending .vp-title {
  font-size: .95rem;
  font-weight: 600;
  color: var(--text-muted);
  max-width: 34ch;
}

.video-pending .vp-note {
  font-size: .8rem;
  max-width: 40ch;
  line-height: 1.45;
}

.video-item figcaption { margin-top: 10px; }

/* A single wide slot, e.g. the seasonal point-cloud flythrough */
.video-slot.wide { aspect-ratio: 21 / 9; }

/* The protocol captures are portrait video, cropped to 4:5 by
   scripts/compress_videos.sh. The default 16/9 slot would crop them to a
   band, so they get their own upright box. */
.video-slot.portrait { aspect-ratio: 4 / 5; }

/* Upright clips are taller than the 16:9 default, so pack more per row. */
.video-grid.portrait-grid {
  grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
}

/* Protocols section: the intro copy sits beside the first clip, and the
   remaining four sit in a 2x2 below. Equal columns throughout keep every
   clip exactly the same size. */
.intro-row,
.video-grid.portrait-grid.cols-2 {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 34px;
  margin-top: 26px;
}

.intro-row { align-items: center; }
.intro-copy { min-width: 0; }
.intro-copy p:last-child { margin-bottom: 0; }
.intro-row .video-item { margin: 0; }

@media (max-width: 700px) {
  .intro-row,
  .video-grid.portrait-grid.cols-2 {
    grid-template-columns: 1fr;
    gap: 20px;
  }
}

@media (max-width: 620px) {
  .video-slot.wide { aspect-ratio: 16 / 9; }
}

/* Small note under a section heading */
.section-note {
  font-size: .92rem;
  color: var(--text-muted);
  margin-top: -.4em;
}

/* Compact table for schedules and measurements */
.table-wrap { overflow-x: auto; margin: 22px 0 0; }

.data-table {
  border-collapse: collapse;
  width: 100%;
  font-size: .9rem;
}

.data-table th,
.data-table td {
  text-align: left;
  padding: 9px 14px 9px 0;
  border-bottom: 1px solid var(--border);
  white-space: nowrap;
}

.data-table th {
  font-weight: 600;
  color: var(--text-muted);
  font-size: .82rem;
  letter-spacing: .02em;
}

/* Status chip for links that are not live yet */
.paper-links a[aria-disabled="true"] {
  opacity: .55;
  pointer-events: none;
}

/* ---------------------------------------------------------------
   Paper page width
   The paper page runs prose to the full container width so it lines
   up with the video blocks and figures. The home page keeps the
   narrower reading measure.
   --------------------------------------------------------------- */

.paper main p,
.paper main .deflist dd { max-width: none; }

/* Trial landmark photos: portrait originals, cropped to a consistent
   landscape frame so the pair sits level. Bias the crop downward so the
   robot stays in frame. */
.gallery--landmarks img {
  aspect-ratio: 4 / 3;
  object-fit: cover;
  object-position: center 62%;
}

/* Three robot views sit as equal portrait tiles */
.gallery--views {
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
}

.gallery--views img {
  aspect-ratio: 3 / 4;
  object-fit: cover;
}

/* The base/arm/merged comparison is a two-row render (base and arm above,
   merged full width below), so it needs its own box shape. */
.video-slot.triptych {
  aspect-ratio: 1440 / 1184;
  /* Matches the render's own background, so the panels sit flush on the page. */
  background: var(--bg);
}
