/* ============================================================
   theme.css
   Canonical shared chrome for the AHLab site.

   This file is the single source of truth for:
   - Design tokens (:root)
   - Reset and base typography
   - .container
   - .rv reveal animations
   - .site-nav (two-mode: transparent over hero, white when scrolled)
   - .site-nav.nav-light variant (always-light, for detail pages)
   - .site-footer
   - .back-strip / .back-link
   - .sidebar-section / .sidebar-section-title

   Page-specific stylesheets (people.css, project.css, press.css,
   publications.css) MUST link this file FIRST. They contain only
   page-specific rules — heroes, grids, item cards, and so on.

   When changing a token, color, or shared layout, edit it HERE only.
   ============================================================ */

/* ── Tokens ──────────────────────────────────────────────── */
:root {
  --color-accent:       #6100FF;
  --color-accent-dark:  #4400B3;
  --color-accent-light: #904DFF;
  --gradient-start:     #00D7EE;
  --gradient-end:       #6100FF;
  --gradient:           linear-gradient(221deg, var(--gradient-start) 0%, var(--gradient-end) 100%);

  --color-neutral-10:   #FFFFFF;
  --color-neutral-20:   #F4F7F9;
  --color-neutral-30:   #EDF0F3;
  --color-neutral-40:   #C9D8E3;
  --color-neutral-60:   #AAAFB6;
  --color-neutral-70:   #838D95;
  --color-neutral-80:   #5E6875;
  --color-neutral-100:  #0E0F11;
  --color-black:        #000000;

  --font-display:       "neue-haas-grotesk-display", sans-serif;
  --font-text:          "neue-haas-grotesk-text", sans-serif;

  /* Corner radii — medium hierarchy.
     Small for tags/buttons, default for medium things, large for cards/images.
     Avatars (50%) and filter pills (999px) keep their hardcoded shape values
     because they're intentional shapes, not just rounded corners. */
  --radius-sm:          8px;
  --radius:             12px;
  --radius-lg:          16px;
}

/* ── Reset & base ────────────────────────────────────────── */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
html { scroll-behavior: smooth; }
body {
  font-family: var(--font-text);
  font-weight: 400;
  font-size: 16px;
  line-height: 24px;
  color: var(--color-neutral-100);
  background: var(--color-neutral-10);
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}
a   { color: inherit; text-decoration: none; }
img { max-width: 100%; height: auto; display: block; }
ul  { list-style: none; }

/* ── Container ───────────────────────────────────────────── */
.container { width: 100%; max-width: 1370px; margin: 0 auto; padding: 0 40px; }
@media (max-width: 767px) { .container { padding: 0 20px; } }

/* ── Reveal animations ───────────────────────────────────── */
.rv     { opacity: 0; transform: translateY(28px); transition: opacity .7s cubic-bezier(.16,1,.3,1), transform .7s cubic-bezier(.16,1,.3,1); }
.rv.vis { opacity: 1; transform: translateY(0); }
.rv-d1  { transition-delay: .1s; }
.rv-d2  { transition-delay: .2s; }
.rv-d3  { transition-delay: .3s; }

/* ── Navigation ──────────────────────────────────────────────
   Two modes:
   1. DEFAULT (used on index pages with a gradient hero):
      - Transparent over the hero
      - White links
      - On scroll (.scrolled), transitions to a white background with
        dark links — wired up by JS that toggles .scrolled when
        window.scrollY > ~60.

   2. NAV-LIGHT (used on detail pages without a hero):
      - Always white background
      - Always dark links
      - Add .nav-light to the <nav> element to opt in.
   ──────────────────────────────────────────────────────────── */
/* ============================================================
   NAV — shared across site, injected via nav-include.js
   Desktop: horizontal row. Mobile (<=991px): scroll-snap carousel
   with centered active item + hamburger drawer dropdown.
   ============================================================ */
/* ============================================================
   NAV — always-on frosted glass, shared across site.
   Desktop: horizontal row. Mobile (<=991px): scroll-snap carousel
   + fullscreen frosted drawer dropdown.
   ============================================================ */
.site-nav {
  position: fixed; top: 0; left: 0; right: 0; z-index: 10000;
  padding: 28px 40px 0; height: 120px;
  display: flex; align-items: flex-start; justify-content: space-between;
  background: var(--gradient);
  -webkit-mask-image: linear-gradient(to bottom, #000 0%, #000 60%, transparent 100%);
          mask-image: linear-gradient(to bottom, #000 0%, #000 60%, transparent 100%);
  transition: filter .3s;
}
.site-nav.scrolled {
  filter: brightness(.92);
}
.site-nav .logo { display: flex; align-items: center; flex-shrink: 0; }
.site-nav .logo img { height: 32px; width: auto; transition: opacity .3s; filter: brightness(0) invert(1); }
.site-nav .logo:hover img { opacity: .7; }
.site-nav .logo .logo-l { display: block; }
.site-nav .logo .logo-d { display: none; }

.nav-links-wrap { display: flex; align-items: center; }
.nav-links {
  display: flex; gap: 36px; align-items: center;
  list-style: none; margin: 0; padding: 0;
}
.nav-links li { list-style: none; }
.nav-links a {
  font-family: var(--font-text); font-weight: 500;
  font-size: 16px; letter-spacing: .01em;
  color: rgba(255,255,255,.75);
  transition: color .3s;
  text-decoration: none;
}
.nav-links a:hover  { color: #fff; }
.nav-links a.active { color: #fff; }

.nav-toggle {
  display: none; background: none; border: none; cursor: pointer;
  width: 35px; height: 19px; position: relative; flex-shrink: 0;
  z-index: 9001;
}
.nav-toggle span {
  display: block; width: 100%; height: 2px; background: #fff;
  position: absolute; left: 0; transition: all .3s;
}
.nav-toggle span:nth-child(1) { top: 0; }
.nav-toggle span:nth-child(2) { top: 8px; }
.nav-toggle span:nth-child(3) { top: 16px; }

/* nav-light variant — kept for backward compat, now a no-op since base is light */
.site-nav.nav-light { }

.nav-drawer { display: none; }

@media (max-width: 991px) {
  /* Mobile nav: tighter horizontal padding, but enough top breathing
     so the logo/hamburger don't clip into the device's notch / status
     bar area. Using env(safe-area-inset-top) adds the device's own
     reported notch height where supported (iOS); the 14px floor keeps
     a comfortable gap on Android / desktop browsers that report 0. */
  .site-nav {
    gap: 12px;
    padding: max(14px, env(safe-area-inset-top, 0px)) 20px 0;
    align-items: center;
    height: 64px;
  }
  /* The logo is dead weight on mobile (it duplicates the brand already
     present on every page header) and steals space from the nav links
     carousel. Hidden entirely so the carousel + hamburger get the full
     row width. */
  .site-nav .logo { display: none; }
  .nav-links-wrap {
    flex: 1; min-width: 0; overflow: hidden;
    -webkit-mask-image: linear-gradient(90deg, transparent 0, #000 8%, #000 92%, transparent 100%);
            mask-image: linear-gradient(90deg, transparent 0, #000 8%, #000 92%, transparent 100%);
  }
  /* Mobile nav-links carousel: a horizontally scrollable strip that
     starts flush with the left edge and ends flush with the right.
     No scroll-snap, no symmetric padding runway — the browser clamps
     scroll position at the natural edges. So when the user is on Home
     (the first link), it sits at the left edge with subsequent links
     visible to its right; when on Join Us (the last link), it sits at
     the right edge. JS in nav.html scrolls the active link into view
     on page load, with smooth scrolling clamped by the browser so the
     edge links don't get force-centered. */
  .nav-links {
    gap: 24px;
    padding: 0 4px;
    overflow-x: auto;
    scroll-behavior: smooth;
    scrollbar-width: none; -ms-overflow-style: none;
  }
  .nav-links::-webkit-scrollbar { display: none; }
  .nav-links li { flex-shrink: 0; }
  .nav-links a {
    display: block; padding: 8px 0; font-size: 14px;
    white-space: nowrap; opacity: .55; position: relative;
    transition: opacity .3s, transform .3s;
  }
  .nav-links a.active { opacity: 1; transform: scale(1.05); }
  .nav-links a.active::after {
    content: ""; position: absolute;
    left: 50%; bottom: -4px; width: 20px; height: 2px;
    background: currentColor; transform: translateX(-50%); border-radius: 2px;
  }
  .nav-toggle { display: block; }

  /* Fullscreen frosted glass drawer.
     Sits at z-index: 9000 — well above the nav (100) and any
     page-level sticky content (year-nav at 30, etc.). The drawer
     is a body-level sibling of <nav> (NOT a child) so it isn't
     subject to the nav's mask-image fade or local stacking
     context. The hamburger button needs an even higher z-index
     so it's still clickable / visible to switch back to the X.

     Visual treatment: heavy frosted glass at the top (where the
     menu links sit) fading to a softer, more transparent glass at
     the bottom — lets the page underneath subtly bleed through
     the lower edge for a layered feel. The mask-image applied to
     the BACKGROUND (via mask-mode) is what produces the gradient;
     the content (links) stays fully opaque. */
  .nav-drawer {
    display: flex; flex-direction: column;
    position: fixed; top: 0; left: 0; right: 0; bottom: 0;
    -webkit-backdrop-filter: saturate(180%) blur(30px);
            backdrop-filter: saturate(180%) blur(30px);
    background: linear-gradient(to bottom,
      rgba(255, 255, 255, .82) 0%,
      rgba(255, 255, 255, .60) 35%,
      rgba(255, 255, 255, .12) 60%,
      rgba(255, 255, 255, .03) 85%,
      rgba(255, 255, 255, 0)   100%
    );
    transform: translateY(-100%); opacity: 0; pointer-events: none;
    transition: transform .4s cubic-bezier(.16,1,.3,1), opacity .3s;
    z-index: 9000;
    overflow-y: auto;
  }
  .nav-drawer.open { transform: translateY(0); opacity: 1; pointer-events: auto; }

  /* Hide hamburger lines, show X when drawer open. The toggle button itself
     stays in place (acts as the close target). The nav's gradient background
     is hidden in this state — the drawer's frosted surface should be the
     only thing the user sees, with just the X icon on top. */
  body:has(.nav-drawer.open) .site-nav { background: transparent; }
  body:has(.nav-drawer.open) .nav-links-wrap { opacity: 0; pointer-events: none; }
  body:has(.nav-drawer.open) .nav-toggle span:nth-child(1) { top: 8px; transform: rotate(45deg); background: var(--color-neutral-100); }
  body:has(.nav-drawer.open) .nav-toggle span:nth-child(2) { opacity: 0; }
  body:has(.nav-drawer.open) .nav-toggle span:nth-child(3) { top: 8px; transform: rotate(-45deg); background: var(--color-neutral-100); }

  /* Two-column grid: 7 links lay out as 2 cols × 4 rows, last cell
     blank. Reset margin/padding on both <ul> and <li> because browser
     defaults add ~40px left padding on <ul>, which would push the
     second column off the right edge of narrow phones. */
  .nav-drawer-grid {
    display: grid; grid-template-columns: 1fr 1fr; gap: 4px 16px;
    max-width: 520px; margin: 0 auto; padding: 24px 20px;
    list-style: none; width: 100%;
    box-sizing: border-box;
  }
  .nav-drawer-grid li { list-style: none; margin: 0; padding: 0; }
  .nav-drawer-grid a {
    display: block; padding: 16px 8px;
    font-family: var(--font-display); font-weight: 500; font-size: 18px;
    color: var(--color-neutral-100);
    border-bottom: 1px solid rgba(0,0,0,.08);
    transition: color .3s; text-decoration: none;
  }
  .nav-drawer-grid a:hover { color: var(--color-accent); }

  /* Logo at the top-left of the drawer, aligned vertically with the
     X (hamburger) button on the right side of the nav row. The nav
     is 64px tall with `align-items: center`, so its content sits
     centered around y=32px. We pad the logo top with the same
     safe-area-aware offset the nav uses, plus extra to bring its
     vertical center in line with the X. The horizontal 20px matches
     the nav's own padding so logo and X are in the same gutters. */
  .nav-drawer-logo {
    display: block;
    padding: max(18px, calc(env(safe-area-inset-top, 0px) + 18px)) 20px 0;
    opacity: .7;
    transition: opacity .3s;
  }
  .nav-drawer-logo img {
    height: 28px;
    width: auto;
    /* Source PNG is white; invert it to dark so it's legible on
       the light frosted glass background. */
    filter: brightness(0);
  }
  .nav-drawer-logo:hover { opacity: 1; }
}



/* ── Sidebar section helpers (used by project + person bodies) ── */
.sidebar-section { margin-bottom: 40px; }
.sidebar-section-title {
  font-family: var(--font-display);
  font-weight: 800;
  font-size: 12px;
  letter-spacing: 1.71px;
  text-transform: uppercase;
  color: var(--color-neutral-60);
  margin-bottom: 16px;
}

/* ── Index-page hero (gradient band under the nav) ──────────
   Shared across /people/, /projects/, /publications/, /press/.
   Deliberately minimalist: just enough top padding to clear the
   120px-tall transparent site nav plus a little breathing, and
   a tight bottom gap so the page's content starts quickly.
   The gradient is provided by the --gradient token (configured
   in :root). All four pages use this as-is; page-specific
   overrides (e.g. typography tweaks) can still be added in their
   own stylesheets since these rules are deliberately unopinionated
   about h1 sizing. */
.hero { position: relative; padding: 132px 0 48px; overflow: hidden; }
.hero::before {
  content: "";
  position: absolute;
  inset: 0;
  background: var(--gradient);
}
.hero .container { position: relative; z-index: 2; }
.hero h1 {
  font-family: var(--font-display); font-weight: 700;
  font-size: 48px; line-height: 52px; color: #fff;
  letter-spacing: -.02em;
}
@media (max-width: 991px) {
  .hero { padding: 112px 0 40px; }
  .hero h1 { font-size: 36px; line-height: 42px; }
}

/* ── Hero summary sentence with inline clickable chips ──────
   Shared control used by the people and publications index heroes.
   Reads as prose sitting under the headline — e.g.
     "8 SRF / RF, 5 RE / RA, 5 Students, and 4 Interns."
   Each count+noun span (`.hero-chip`) is actionable: clicking it
   applies a filter on the surrounding list. Styling is deliberately
   text-first (no button chrome), with a dotted underline as the
   only "this is interactive" affordance. Lives in theme.css so any
   index page with a gradient hero can use the same treatment.

   States:
     .hero-summary                — normal (all chips at rest)
     .hero-summary.is-filtered    — a chip is currently active; non-
                                    active chips fade and the reset
                                    link becomes visible.
     .hero-chip.is-active         — the chip matching the active
                                    filter; solid underline + tinted
                                    background so it stands out. */
.hero-summary {
  margin-top: 22px;
  font-family: var(--font-display);
  font-weight: 400;
  font-size: 20px;
  line-height: 1.55;
  color: rgba(255, 255, 255, .75);
  letter-spacing: -.005em;
  /* No max-width: lets longer chip sentences (e.g. the 6 principle
     filters on /projects/) stay on one line at desktop widths rather
     than wrapping and making that hero visibly taller than the others.
     The surrounding .container already caps the reach at ~1290px. */
}
.hero-filter-group {
  /* inline container — no layout of its own, chips are just inline text */
  display: inline;
}

.hero-chip {
  color: #fff;
  font-weight: 600;
  cursor: pointer;
  padding: 1px 2px;
  border-radius: 3px;
  /* Subtle dotted underline suggests "this is interactive" without
     looking like a link. Becomes solid on hover / when active. */
  text-decoration: underline dotted rgba(255, 255, 255, .45);
  text-underline-offset: 4px;
  text-decoration-thickness: 1.5px;
  transition: color .2s ease, text-decoration-color .2s ease, background .2s ease, opacity .25s ease;
  -webkit-tap-highlight-color: transparent;
}
.hero-chip:hover,
.hero-chip:focus-visible {
  text-decoration: underline solid #fff;
  text-decoration-thickness: 2px;
  outline: none;
}
.hero-chip.is-active {
  color: #fff;
  background: rgba(255, 255, 255, .14);
  text-decoration: underline solid #fff;
  text-decoration-thickness: 2px;
}
.hero-summary.is-filtered .hero-chip:not(.is-active) {
  opacity: .4;
}

/* "Show all" reset link — hidden by default, appears next to the
   sentence when any filter is active. Styled as a small inline text
   link rather than a button. */
.hero-filter-reset {
  margin-left: .5em;
  padding: 0;
  border: 0;
  background: none;
  font: inherit;
  color: rgba(255, 255, 255, .75);
  cursor: pointer;
  text-decoration: underline solid rgba(255, 255, 255, .35);
  text-underline-offset: 4px;
  text-decoration-thickness: 1px;
  opacity: 0;
  pointer-events: none;
  transition: opacity .25s ease, color .2s ease, text-decoration-color .2s ease;
}
.hero-filter-reset:hover,
.hero-filter-reset:focus-visible {
  color: #fff;
  text-decoration-color: #fff;
  outline: none;
}
.hero-summary.is-filtered .hero-filter-reset {
  opacity: 1;
  pointer-events: auto;
}

@media (max-width: 767px) {
  .hero-summary { font-size: 17px; }
}

/* ── Back link strip (used by detail pages) ──────────────── */
.back-strip {
  padding: 60px 0;
  border-top: 2px solid var(--color-neutral-30);
  text-align: center;
}
.back-link {
  display: inline-flex; align-items: center; gap: 10px;
  font-family: var(--font-text); font-weight: 600; font-size: 18px;
  color: var(--color-accent);
  border: 1px solid var(--color-accent);
  padding: 16px 60px; border-radius: var(--radius);
  transition: all .4s;
}
.back-link:hover { background: var(--color-accent); color: #fff; }

/* ── Footer ──────────────────────────────────────────────── */
.site-footer { background: var(--color-neutral-100); padding: 80px 0 24px; }
.footer-top {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  gap: 40px;
  padding-bottom: 60px;
  border-bottom: 1px solid rgba(255,255,255,.08);
}
.footer-brand img { height: 28px; width: auto; margin-bottom: 24px; }
.footer-brand p {
  font-size: 15px; line-height: 24px;
  color: var(--color-neutral-70); max-width: 280px;
}
.footer-nav-col h5 {
  font-family: var(--font-display); font-weight: 700;
  font-size: 14px; color: var(--color-neutral-60);
  text-transform: uppercase; letter-spacing: .1em;
  margin-bottom: 20px;
}
.footer-nav-col a {
  display: block; font-size: 15px;
  color: rgba(255,255,255,.5);
  margin-bottom: 12px;
  transition: color .3s;
}
.footer-nav-col a:hover { color: #fff; }

.footer-contact h5 {
  font-family: var(--font-display); font-weight: 700;
  font-size: 14px; color: var(--color-neutral-60);
  text-transform: uppercase; letter-spacing: .1em;
  margin-bottom: 20px;
}
.footer-contact a,
.footer-contact p {
  font-size: 15px; line-height: 24px;
  color: rgba(255,255,255,.5);
  transition: color .3s;
}
.footer-contact a:hover { color: #fff; }

.footer-bottom {
  display: flex; justify-content: space-between; align-items: center;
  padding-top: 24px;
}
.footer-copy { font-size: 12px; color: rgba(255,255,255,.3); }

@media (max-width: 767px) {
  .footer-top    { grid-template-columns: 1fr; gap: 40px; }
  .footer-bottom { flex-direction: column-reverse; gap: 16px; text-align: center; }
}