/* AI Governance Lab — site styles
   Structure follows stanforddpl.org (Stanford's Democracy and Polarization
   Lab): light page, Stanford cardinal accent, full-bleed photo hero, centered
   section headings, circular avatars, ruled lists rather than cards.
   Typography is the lab's own: Public Sans (the US Web Design System's face,
   the vernacular of the field) for text, Newsreader for headings. */

:root {
  /* Surfaces alternate between sections so the page reads as bands without
     needing boxes or rules to separate them. */
  --paper: #ffffff;
  --paper-alt: #f7f5f2;
  --ink: #1b1a18;
  --ink-soft: #5c5850;
  --rule: #e3dfd7;
  --cardinal: #8c1515;
  --cardinal-deep: #5e0e0e;
  --cardinal-tint: #f2e6e6;
  --nav-bg: rgba(255, 255, 255, 0.94);
  --nav-ink: #4a4a4a;
  --switch-track: #b9b3aa;
  --switch-knob: #ffffff;

  --font-display: "Newsreader", Georgia, "Times New Roman", serif;
  --font-body: "Public Sans", -apple-system, BlinkMacSystemFont, "Segoe UI",
    Helvetica, Arial, sans-serif;

  --nav-height: 60px;
  --measure: 68ch;
}

:root[data-theme="dark"] {
  --paper: #14120f;
  --paper-alt: #1c1916;
  --ink: #ece7dd;
  --ink-soft: #a49c8e;
  --rule: #332e28;
  --cardinal: #e39494;
  --cardinal-deep: #f0bcbc;
  --cardinal-tint: #33241f;
  --nav-bg: rgba(20, 18, 15, 0.94);
  --nav-ink: #bdb5a8;
  --switch-track: #5c564d;
  --switch-knob: #ece7dd;
}

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

html {
  scroll-behavior: smooth;
  /* Anchored sections must clear the sticky nav when jumped to. */
  scroll-padding-top: var(--nav-height);
}

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: 17px;
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
}

a {
  color: var(--cardinal);
  text-decoration: none;
}

a:hover {
  color: var(--cardinal-deep);
  text-decoration: underline;
  text-underline-offset: 2px;
}

:focus-visible {
  outline: 2px solid var(--cardinal);
  outline-offset: 3px;
  border-radius: 2px;
}

code {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 0.88em;
  background: var(--cardinal-tint);
  padding: 0.1em 0.35em;
  border-radius: 3px;
}

.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}

.skip-link {
  position: absolute;
  left: 0.75rem;
  top: -4rem;
  z-index: 200;
  background: var(--paper);
  color: var(--cardinal);
  padding: 0.6rem 1rem;
  border: 1px solid var(--rule);
}

.skip-link:focus {
  top: 0.75rem;
}

/* ---------- Nav ---------- */

nav#top-nav {
  position: sticky;
  top: 0;
  z-index: 100;
  background: var(--nav-bg);
  backdrop-filter: saturate(180%) blur(10px);
  border-bottom: 1px solid var(--rule);
}

.nav-inner {
  max-width: 1140px;
  margin: 0 auto;
  min-height: var(--nav-height);
  padding: 0 1.5rem;
  display: flex;
  align-items: center;
  gap: 1rem;
}

#logo {
  font-family: var(--font-display);
  font-size: 1.24rem;
  font-weight: 600;
  letter-spacing: -0.005em;
  color: var(--ink);
  margin-right: auto;
  white-space: nowrap;
}

#logo:hover {
  color: var(--cardinal);
  text-decoration: none;
}

#nav-menu {
  display: flex;
  align-items: center;
  gap: 1.1rem;
}

.nav-links {
  display: flex;
  align-items: center;
  gap: 0.35rem;
  list-style: none;
  margin: 0;
  padding: 0;
}

.nav-link {
  display: block;
  color: var(--nav-ink);
  font-size: 0.92rem;
  font-weight: 500;
  padding: 0.4rem 0.6rem;
  white-space: nowrap;
}

.nav-link:hover {
  color: var(--cardinal);
  text-decoration: none;
}

.nav-link.active {
  color: var(--cardinal);
}

#nav-toggle {
  display: none;
  background: none;
  border: 1px solid var(--rule);
  border-radius: 4px;
  padding: 0.5rem 0.6rem;
  cursor: pointer;
  color: var(--nav-ink);
}

/* Three bars drawn from one element: the middle is the box, the outer two are
   its pseudo-elements. */
.nav-toggle-bars,
.nav-toggle-bars::before,
.nav-toggle-bars::after {
  display: block;
  width: 20px;
  height: 2px;
  background: currentColor;
}

.nav-toggle-bars {
  position: relative;
}

.nav-toggle-bars::before,
.nav-toggle-bars::after {
  content: "";
  position: absolute;
  left: 0;
}

.nav-toggle-bars::before {
  top: -6px;
}

.nav-toggle-bars::after {
  top: 6px;
}

/* Light/dark toggle — sliding sun/moon pill (design adapted from the CS283
   site, which adapted it from vitalik.eth.limo). The knob position is driven by
   the data-theme attribute, so it is already correct pre-paint; the hidden
   checkbox is the accessible control that assets/js/theme.js keeps in sync.
   Icons stroke via currentColor. */
#color-mode-switch {
  display: flex;
  align-items: center;
  flex: none;
  color: var(--nav-ink);
}

#color-mode-switch .cms-icon {
  width: 17px;
  height: 17px;
  margin: 0 5px;
  flex: none;
}

/* Visually-hidden checkbox; the label is the pill the user actually clicks. */
#color-mode-switch input {
  position: absolute;
  width: 0;
  height: 0;
  opacity: 0;
}

#color-mode-switch label {
  cursor: pointer;
  text-indent: -9999px;
  width: 38px;
  height: 19px;
  border-radius: 30px;
  background: var(--switch-track);
  display: block;
  position: relative;
  margin: 0;
}

/* The knob. Base position = light (left, by the sun). */
#color-mode-switch label::after {
  content: "";
  position: absolute;
  top: 3px;
  left: 3px;
  width: 13px;
  height: 13px;
  background: var(--switch-knob);
  border-radius: 90px;
  transition: 0.3s;
}

#color-mode-switch label:active::after {
  width: 26px;
}

/* The real checkbox is invisible, so its focus ring would be too. Put a visible
   ring on the pill instead when the control is reached by keyboard. */
#color-mode-switch input:focus-visible + label {
  outline: 2px solid var(--cardinal);
  outline-offset: 3px;
}

/* Dark: knob slides right, toward the moon. */
:root[data-theme="dark"] #color-mode-switch label::after {
  left: calc(100% - 3px);
  transform: translateX(-100%);
}

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

.hero {
  position: relative;
  min-height: min(74vh, 620px);
  display: grid;
  place-items: center;
  padding: 5rem 1.5rem;
  text-align: center;
  color: #ffffff;
  /* --hero-image is set inline on the element from `hero_image` in _config.yml,
     so swapping the photo is a config change, not a CSS edit. The scrim is
     weighted toward the middle rather than flat: the title sits in that band,
     and on the CODA photo it falls across bright glass that a uniform wash
     leaves too light to read white type against. */
  background-image: linear-gradient(
      to bottom,
      rgba(0, 0, 0, 0.3) 0%,
      rgba(0, 0, 0, 0.58) 40%,
      rgba(0, 0, 0, 0.58) 64%,
      rgba(0, 0, 0, 0.32) 100%
    ),
    var(--hero-image);
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
}

/* `width: 100%` is load-bearing: the hero is a grid with `place-items: center`,
   which sizes its child to max-content, so without it the h1 refuses to wrap
   and pushes the whole document wider than a phone screen. The max-width is
   set so "AI Governance Lab" lands on one line on a laptop; `ch` would be wrong
   here, since it resolves against this element's body-sized font rather than
   the display-sized h1. */
.hero-inner {
  width: 100%;
  max-width: 900px;
}

.hero-title {
  font-family: var(--font-display);
  font-weight: 500;
  font-size: clamp(2.6rem, 7.5vw, 4.6rem);
  line-height: 1.02;
  letter-spacing: -0.02em;
  margin: 0;
  text-wrap: balance;
}

.hero-subtitle {
  font-size: clamp(1rem, 2.2vw, 1.22rem);
  font-weight: 400;
  color: rgba(255, 255, 255, 0.86);
  margin: 0.9rem 0 0;
}

/* ---------- Bands, headings, prose ---------- */

.band {
  background: var(--paper);
  padding: 4.5rem 0;
  scroll-margin-top: var(--nav-height);
}

.band-alt {
  background: var(--paper-alt);
}

.wrap {
  max-width: 1040px;
  margin: 0 auto;
  padding: 0 1.5rem;
}

.section-heading {
  font-family: var(--font-display);
  font-weight: 500;
  font-size: clamp(1.75rem, 4vw, 2.3rem);
  line-height: 1.15;
  letter-spacing: -0.015em;
  text-align: center;
  margin: 0 0 2.5rem;
}

/* A short cardinal rule beneath each section heading: the one place the
   institutional color appears as structure rather than as a link. */
.section-heading::after {
  content: "";
  display: block;
  width: 44px;
  height: 2px;
  background: var(--cardinal);
  margin: 0.85rem auto 0;
}

.prose {
  max-width: var(--measure);
  margin: 0 auto;
}

.prose p {
  margin: 0 0 1.15rem;
}

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

.empty-state {
  max-width: var(--measure);
  margin: 0 auto;
  color: var(--ink-soft);
  font-size: 0.92rem;
  font-style: italic;
  text-align: center;
}

/* Inner pages run left-aligned, so a centered message would float free of the
   list it is about. */
.page .empty-state {
  margin-left: 0;
  text-align: left;
}

.placeholder {
  color: var(--ink-soft);
  font-style: italic;
}

.see-all {
  text-align: center;
  margin: 2rem 0 0;
  font-size: 0.95rem;
}

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

.group-heading {
  font-family: var(--font-display);
  font-weight: 500;
  font-size: 1.3rem;
  letter-spacing: -0.01em;
  margin: 2.75rem 0 1.5rem;
  padding-bottom: 0.5rem;
  border-bottom: 1px solid var(--rule);
}

.group-heading:first-of-type {
  margin-top: 0;
}

/* A flex row rather than a grid: group sizes here are small and uneven (two
   co-directors, three members), and a grid would stretch a lone person to the
   full width. Flex keeps every card in a group the same size wherever it
   lands; the width itself is per-group, set below. */
.people-grid {
  display: flex;
  flex-wrap: wrap;
  gap: 2.5rem 2rem;
  list-style: none;
  margin: 0;
  padding: 0;
}

.person {
  flex: 0 0 200px;
  max-width: 100%;
  text-align: center;
}

/* The co-directors' role line is a full endowed chair — "McGregor-Girand
   Professor of Social Ethics of Science and Technology" wraps to four lines in
   a 200px card and leaves the two cards badly uneven. Widening just this group
   brings it down to two. `max-width: 100%` above still applies, so on a phone
   the card shrinks to the screen and the pair stacks one per row rather than
   overflowing. */
.people-grid-faculty .person {
  flex-basis: 300px;
}

/* The whole card is the link target, not just the name, so the photo is
   clickable too and the hover state has something to fill. `.person-card` is
   the same box whether it renders as an <a> or a <div>, so a person without a
   URL sits flush with the rest of the row. */
.person-card {
  display: block;
  padding: 1rem 0.75rem 1.25rem;
  border-radius: 8px;
  color: inherit;
  transition: background-color 0.15s ease;
}

a.person-card:hover,
a.person-card:focus-visible {
  background: var(--cardinal-tint);
  text-decoration: none;
}

a.person-card:hover .person-name {
  color: var(--cardinal);
}

.avatar {
  display: block;
  width: 132px;
  height: 132px;
  border-radius: 50%;
  background: var(--cardinal-tint);
  margin: 0 auto 0.9rem;
  overflow: hidden;
}

/* The avatar's own tint is the hover color, so give it a ring to stay legible
   once the card behind it turns the same shade. */
a.person-card:hover .avatar {
  box-shadow: 0 0 0 2px var(--cardinal);
}

.avatar img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center center;
  display: block;
}

.avatar img.pos-top {
  object-position: center 28%;
}

.person-name {
  display: block;
  font-family: var(--font-display);
  font-size: 1.1rem;
  font-weight: 600;
  line-height: 1.25;
}

.person-role {
  display: block;
  color: var(--ink-soft);
  font-size: 0.88rem;
  margin-top: 0.2rem;
}

/* ---------- Substack ---------- */

.substack-embed {
  max-width: 480px;
  margin: 2rem auto 0;
  border: 1px solid var(--rule);
  overflow: hidden;
}

.substack-embed iframe {
  display: block;
  background: #ffffff;
}

/* The post list under the embed is centered over the same 820px column, so
   its heading sits above rather than ruling across the full band the way the
   People group headings do. */
.posts-heading {
  font-family: var(--font-display);
  font-weight: 500;
  font-size: 1.15rem;
  letter-spacing: 0.01em;
  text-align: center;
  color: var(--ink-soft);
  margin: 3rem 0 1.25rem;
}

/* Substack lists a post as a cover image beside its title, subtitle and
   byline, and that shape is what makes the section read as the newsletter
   rather than as one more list of links. The shape is borrowed; the type,
   color and hairline rules stay the site's own. */
.post-list {
  max-width: 820px;
  margin: 0 auto;
  padding: 0;
  list-style: none;
  border-top: 1px solid var(--rule);
}

.post {
  border-bottom: 1px solid var(--rule);
}

/* The whole row is the link, so the cover is a target too. */
.post-card {
  display: flex;
  align-items: flex-start;
  gap: 1.75rem;
  padding: 1.4rem 0.25rem;
  color: inherit;
}

.post-card:hover {
  text-decoration: none;
}

.post-text {
  flex: 1;
  min-width: 0;
}

.post-title {
  display: block;
  font-family: var(--font-display);
  font-weight: 500;
  font-size: 1.22rem;
  line-height: 1.25;
  letter-spacing: -0.01em;
  color: var(--cardinal);
}

.post-card:hover .post-title {
  color: var(--cardinal-deep);
  text-decoration: underline;
  text-underline-offset: 2px;
}

.post-summary {
  display: block;
  margin-top: 0.4rem;
  color: var(--ink-soft);
  font-size: 0.93rem;
  line-height: 1.5;
}

.post-byline {
  display: block;
  margin-top: 0.6rem;
  color: var(--ink-soft);
  font-size: 0.82rem;
}

.post-cover {
  flex: none;
  display: block;
  width: 170px;
}

/* Covers arrive at whatever size and shape the post used — one of them is a
   portrait illustration — so every one is cropped to the same landscape box
   to keep the rows even. */
.post-cover img {
  display: block;
  width: 100%;
  height: 113px;
  object-fit: cover;
  border-radius: 3px;
  background: var(--paper-alt);
}

/* ---------- Recent news ---------- */

.news-list {
  max-width: 820px;
  margin: 0 auto;
  padding: 0;
  list-style: none;
  border-top: 1px solid var(--rule);
}

.news-item {
  display: grid;
  grid-template-columns: 7.5rem 1fr;
  gap: 0 1.5rem;
  padding: 1.05rem 0;
  border-bottom: 1px solid var(--rule);
}

.news-date {
  margin: 0;
  color: var(--ink-soft);
  font-size: 0.85rem;
  font-variant-numeric: tabular-nums;
  padding-top: 0.15rem;
}

.news-body {
  margin: 0;
}

.news-outlet {
  display: block;
  color: var(--ink-soft);
  font-size: 0.85rem;
}

/* Events reuse the news list. An event with no link still needs its title to
   read as the primary line. */
.news-title {
  font-weight: 600;
}

.news-summary {
  display: block;
  color: var(--ink-soft);
  font-size: 0.9rem;
  margin-top: 0.2rem;
}

/* ---------- Inner pages ---------- */

.page {
  padding-top: 3.75rem;
  padding-bottom: 5rem;
}

.page-title {
  font-family: var(--font-display);
  font-weight: 500;
  font-size: clamp(2.1rem, 5vw, 2.9rem);
  line-height: 1.1;
  letter-spacing: -0.02em;
  margin: 0;
}

.page-standfirst {
  color: var(--ink-soft);
  font-size: 1.05rem;
  margin: 0.4rem 0 2.5rem;
  padding-bottom: 1.75rem;
  border-bottom: 1px solid var(--rule);
}

/* ---------- Publications ---------- */

.pub-list,
.course-list {
  list-style: none;
  margin: 0;
  padding: 0;
}

.pub {
  padding: 1.4rem 0;
  border-bottom: 1px solid var(--rule);
  max-width: 78ch;
}

.pub:first-child {
  padding-top: 0;
}

.pub-authors {
  margin: 0;
  font-size: 0.9rem;
  color: var(--ink-soft);
}

.pub-title {
  font-family: var(--font-display);
  font-size: 1.22rem;
  font-weight: 500;
  line-height: 1.3;
  margin: 0.25rem 0 0;
}

.pub-venue {
  margin: 0.25rem 0 0;
  font-size: 0.92rem;
  color: var(--ink-soft);
}

.pub-venue-name {
  font-style: italic;
}

.pub-links {
  margin: 0.7rem 0 0;
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
}

.pub-links a {
  font-size: 0.8rem;
  font-weight: 600;
  letter-spacing: 0.01em;
  border: 1px solid var(--cardinal);
  padding: 0.2rem 0.6rem;
  border-radius: 3px;
}

.pub-links a:hover {
  background: var(--cardinal);
  color: var(--paper);
  text-decoration: none;
}

/* ---------- Teaching ---------- */

.course {
  padding: 1.6rem 0;
  border-bottom: 1px solid var(--rule);
  max-width: 78ch;
}

.course:first-child {
  padding-top: 0;
}

.course-title {
  font-family: var(--font-display);
  font-size: 1.32rem;
  font-weight: 500;
  line-height: 1.3;
  margin: 0;
}

.course-meta {
  margin: 0.3rem 0 0;
  font-size: 0.9rem;
  color: var(--ink-soft);
}

.course-description {
  margin: 0.6rem 0 0;
}

.course-link {
  margin: 0.7rem 0 0;
  font-size: 0.95rem;
}

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

footer {
  border-top: 1px solid var(--rule);
  background: var(--paper);
  padding: 2.25rem 0 3rem;
}

.footer-inner {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.5rem 1.5rem;
  color: var(--ink-soft);
  font-size: 0.88rem;
}

.footer-identity {
  display: flex;
  flex-wrap: wrap;
  gap: 0.15rem 1.25rem;
}

.footer-name,
.footer-copyright,
.footer-links {
  margin: 0;
}

.footer-links a {
  margin-left: 1.25rem;
}

.footer-links a:first-child {
  margin-left: 0;
}

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

/* Parallax only where it can be smooth: not on touch, not for anyone who has
   asked for less motion. */
@media (min-width: 900px) and (hover: hover) and (prefers-reduced-motion: no-preference) {
  .hero {
    background-attachment: fixed;
  }
}

/* Raised from 920px when the nav went to seven tabs: below this the row
   crowds the logo before it actually overflows. */
@media (max-width: 980px) {
  #nav-toggle {
    display: block;
  }

  #nav-menu {
    display: none;
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    flex-direction: column;
    align-items: stretch;
    gap: 0;
    background: var(--paper);
    border-bottom: 1px solid var(--rule);
    padding: 0.5rem 1.5rem 1rem;
  }

  #nav-menu.open {
    display: flex;
  }

  .nav-links {
    flex-direction: column;
    align-items: stretch;
    gap: 0;
  }

  .nav-link {
    padding: 0.65rem 0;
    border-bottom: 1px solid var(--rule);
  }

  #color-mode-switch {
    padding-top: 0.9rem;
  }
}

@media (max-width: 600px) {
  .band {
    padding: 3.25rem 0;
  }

  .people-grid {
    gap: 2rem 1.25rem;
    justify-content: center;
  }

  .person {
    flex-basis: calc(50% - 0.625rem);
  }

  .news-item {
    grid-template-columns: 1fr;
    gap: 0.2rem;
  }

  /* Too narrow for a side-by-side row: the cover goes full width above the
     title, which is how Substack stacks it on a phone too. */
  .post-card {
    flex-direction: column;
    /* Stacked, the rows must fill the column: left at flex-start they shrink
       to their content and the titles run off the side of the screen. */
    align-items: stretch;
    gap: 1rem;
  }

  .post-cover {
    order: -1;
    width: 100%;
  }

  .post-cover img {
    height: auto;
    aspect-ratio: 16 / 9;
  }

}

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

  *,
  *::before,
  *::after {
    transition-duration: 0.01ms !important;
    animation-duration: 0.01ms !important;
  }
}
