/* ---------------------------------------------------------------------------
   laneluo.com

   Palette, type scale, and the h2 accent bar are ported from
   ~/teaching/sample-ai-course/assets/yale-site.scss so this site reads as one
   system with the lecture decks. Dark is the default; the light values come
   from ~/.claude/assets/quarto-yale/yale-talk.scss.

   Note the inversion between the two: on the dark ground Yale blue #00356b
   measures 1.4:1 and is banned from body text, appearing only in the navbar
   where white on it is 12.2:1. On the light ground it becomes the heading ink.
   That is why --accent is a different hue in each theme rather than one value.

   Fonts are system stacks on purpose. A webfont would make every page fetch at
   display time, and the decks avoid it for the same reason.
--------------------------------------------------------------------------- */

/* --- Theme tokens -------------------------------------------------------- */

:root {
  --nav-bg: #00356b;
  --nav-fg: #ffffff;
  --nav-hl: #a8ceff;
  --nav-rule: #63aaff;

  --content-width: 880px;
  --gutter: 1.5rem;

  --font-sans: -apple-system, BlinkMacSystemFont, "Segoe UI", "Helvetica Neue",
    Helvetica, Arial, sans-serif;
  --font-mono: ui-monospace, "SF Mono", SFMono-Regular, Menlo, Consolas, monospace;

  --size-base: 1.0625rem;   /* 17px */
  --leading: 1.65;

  --space-h2-above: 4rem;
  --space-h2-below: 0.85rem;
  --space-block: 1.75rem;

  --radius: 4px;
  --radius-sm: 3px;
}

:root,
[data-theme="dark"] {
  color-scheme: dark;

  --bg: #1a1c1e;
  --raised: #24272a;
  --raised-high: #2b2f33;
  --hairline: #33373b;

  --ink: #e8e6e3;
  --ink-strong: #ffffff;
  --muted: #9aa0a6;

  --link: #63aaff;
  --link-hover: #a8ceff;
  --accent: #63aaff;
  --accent-soft: #a8ceff;

  --hover-tint: rgba(99, 170, 255, 0.09);
  --code-bg: rgba(255, 255, 255, 0.055);
  --code-fg: #ffa07a;
  --select-bg: rgba(99, 170, 255, 0.32);
  --shadow: 0 1px 3px rgba(0, 0, 0, 0.4), 0 8px 24px rgba(0, 0, 0, 0.28);
  --shadow-lift: 0 4px 8px rgba(0, 0, 0, 0.3), 0 14px 34px rgba(0, 0, 0, 0.26);
}

[data-theme="light"] {
  color-scheme: light;

  --bg: #ffffff;
  --raised: #f7f8fa;
  --raised-high: #eef1f5;
  --hairline: #d8d8d8;

  --ink: #1a1a1a;
  --ink-strong: #00356b;
  --muted: #4a4a4a;

  --link: #286dc0;
  --link-hover: #00356b;
  --accent: #00356b;
  --accent-soft: #286dc0;

  --hover-tint: rgba(40, 109, 192, 0.07);
  --code-bg: #f0f2f5;
  --code-fg: #00356b;
  --select-bg: rgba(99, 170, 255, 0.35);
  --shadow: 0 1px 2px rgba(0, 0, 0, 0.06), 0 8px 24px rgba(0, 0, 0, 0.07);
  --shadow-lift: 0 3px 6px rgba(0, 0, 0, 0.09), 0 14px 30px rgba(0, 0, 0, 0.11);
}

/* --- Reset and base ------------------------------------------------------ */

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

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}

body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--font-sans);
  font-size: var(--size-base);
  line-height: var(--leading);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  transition: background-color 0.18s ease, color 0.18s ease;
}

::selection {
  background: var(--select-bg);
}

img {
  max-width: 100%;
  height: auto;
  display: block;
}

a {
  color: var(--link);
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 0.14em;
  transition: color 0.14s ease;
}

a:hover {
  color: var(--link-hover);
}

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

code {
  font-family: var(--font-mono);
  font-size: 0.9em;
  background: var(--code-bg);
  color: var(--code-fg);
  padding: 0.12em 0.34em;
  border-radius: var(--radius-sm);
}

hr {
  border: 0;
  border-top: 1px solid var(--hairline);
  margin: 2.5rem 0;
}

.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  background: var(--nav-bg);
  color: #fff;
  padding: 0.6rem 1rem;
  z-index: 200;
  text-decoration: none;
}

.skip-link:focus {
  left: 0;
}

/* --- Typography ---------------------------------------------------------- */

h1, h2, h3, h4 {
  color: var(--ink-strong);
  font-weight: 600;
  line-height: 1.25;
}

h1 {
  font-size: calc(var(--size-base) * 2.05);
  letter-spacing: -0.015em;
  margin: 0 0 0.2rem;
}

h2 {
  font-size: calc(var(--size-base) * 1.5);
  letter-spacing: -0.01em;
  margin: var(--space-h2-above) 0 var(--space-h2-below);
}

/* The accent bar under every h2. This is the shape that ties the site to the
   decks, where it appears at 7rem wide and 4px thick. */
h2::after {
  content: "";
  display: block;
  width: 2.5rem;
  height: 3px;
  margin: 0.45rem 0 0;
  background: var(--accent);
  border-radius: 1px;
}

h3 {
  font-size: calc(var(--size-base) * 1.2);
  margin: calc(var(--space-h2-above) * 0.62) 0 0.6rem;
}

h4 {
  font-size: calc(var(--size-base) * 1.05);
  color: var(--accent-soft);
  margin: calc(var(--space-h2-above) * 0.45) 0 0.5rem;
}

p {
  margin: 0 0 1.1rem;
}

.lead {
  font-size: 1.1rem;
}

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

.note {
  color: var(--muted);
  font-size: 0.92rem;
}

/* --- Navbar -------------------------------------------------------------- */

.nav {
  position: sticky;
  top: 0;
  z-index: 100;
  background: var(--nav-bg);
  border-bottom: 2px solid var(--nav-rule);
}

.nav-inner {
  max-width: var(--content-width);
  margin-inline: auto;
  padding: 0.7rem var(--gutter);
  display: flex;
  align-items: center;
  gap: 1rem;
  flex-wrap: wrap;
}

.nav-brand {
  color: var(--nav-fg);
  font-weight: 600;
  font-size: 1.05rem;
  letter-spacing: -0.01em;
  text-decoration: none;
  margin-right: auto;
  white-space: nowrap;
}

.nav-brand:hover {
  color: var(--nav-hl);
}

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

.nav-links a {
  display: block;
  color: var(--nav-fg);
  font-weight: 500;
  font-size: 0.95rem;
  text-decoration: none;
  padding: 0.3rem 0.6rem;
  border-radius: var(--radius);
  white-space: nowrap;
}

.nav-links a:hover {
  color: var(--nav-hl);
  background: rgba(255, 255, 255, 0.07);
}

/* The current tab reads as a filled chip with a pale ring. An underline here
   sat right above the navbar's own 2px rule and the pair looked like a brace. */
.nav-links a[aria-current="page"] {
  color: var(--nav-fg);
  background: rgba(255, 255, 255, 0.15);
  box-shadow: inset 0 0 0 1px rgba(168, 206, 255, 0.55);
}

.nav-links a[aria-current="page"]:hover {
  color: var(--nav-fg);
  background: rgba(255, 255, 255, 0.22);
}

/* --- Theme toggle -------------------------------------------------------- */

.theme-toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 34px;
  height: 34px;
  flex: 0 0 auto;
  background: rgba(255, 255, 255, 0.09);
  border: 1px solid rgba(255, 255, 255, 0.18);
  border-radius: 50%;
  color: var(--nav-fg);
  cursor: pointer;
  padding: 0;
  transition: background-color 0.14s ease, color 0.14s ease;
}

.theme-toggle:hover {
  background: rgba(255, 255, 255, 0.18);
  color: var(--nav-hl);
}

.theme-toggle svg {
  width: 17px;
  height: 17px;
  display: block;
}

/* Sun shows in dark mode (click for light), moon shows in light mode. */
.theme-toggle .icon-sun { display: none; }
.theme-toggle .icon-moon { display: block; }
[data-theme="dark"] .theme-toggle .icon-sun { display: block; }
[data-theme="dark"] .theme-toggle .icon-moon { display: none; }

/* --- Layout -------------------------------------------------------------- */

.wrap {
  max-width: var(--content-width);
  margin-inline: auto;
  padding: 0 var(--gutter);
}

main {
  padding-bottom: 4rem;
}

section {
  scroll-margin-top: 5rem;
}

/* An h2 opening a page sits closer to the masthead than the 4rem section
   rhythm, which is tuned for gaps between sections rather than the first one. */
main > .wrap > section:first-child > h2:first-child,
main > .wrap > h2:first-child {
  margin-top: 2.75rem;
}

/* --- Page head (interior pages) ------------------------------------------ */

.page-head {
  padding: 3rem 0 0;
}

.page-head .subtitle {
  color: var(--accent-soft);
  font-size: 1.1rem;
  font-weight: 400;
  margin: 0.35rem 0 0;
}

/* --- Hero (home) --------------------------------------------------------- */

.hero {
  padding: 3.25rem 0 0.5rem;
  display: grid;
  grid-template-columns: minmax(0, 1fr) 260px;
  gap: 2.75rem;
  align-items: start;
}

.hero-title {
  margin-bottom: 0.35rem;
}

.hero-role {
  color: var(--accent-soft);
  font-size: 1.1rem;
  margin: 0 0 1.6rem;
}

.hero-photo {
  width: 260px;
  aspect-ratio: 1 / 1;
  object-fit: cover;
  border-radius: var(--radius);
  border: 1px solid var(--hairline);
  box-shadow: var(--shadow);
}

/* --- Social / link buttons ----------------------------------------------- */

.links-row {
  display: flex;
  flex-wrap: wrap;
  gap: 0.6rem;
  margin: 1.6rem 0 0;
  padding: 0;
  list-style: none;
}

.btn {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  padding: 0.42rem 0.85rem;
  font-size: 0.92rem;
  font-weight: 500;
  color: var(--ink);
  background: var(--raised);
  border: 1px solid var(--hairline);
  border-radius: var(--radius);
  text-decoration: none;
  transition: background-color 0.14s ease, border-color 0.14s ease,
    color 0.14s ease, transform 0.14s ease;
}

.btn:hover {
  color: var(--ink-strong);
  background: var(--raised-high);
  border-color: var(--accent);
  transform: translateY(-1px);
}

.btn svg {
  width: 16px;
  height: 16px;
  flex: 0 0 auto;
  fill: currentColor;
}

.btn-primary {
  color: #fff;
  background: var(--nav-bg);
  border-color: var(--nav-bg);
}

.btn-primary:hover {
  color: #fff;
  background: #004a92;
  border-color: var(--nav-rule);
}

/* --- Publication list ---------------------------------------------------- */

.pubs {
  list-style: none;
  margin: 0;
  padding: 0;
  counter-reset: pub;
}

.pubs > li {
  position: relative;
  padding: 0 0 0 2.1rem;
  margin: 0 0 1.9rem;
}

.pubs > li::before {
  counter-increment: pub;
  content: counter(pub);
  position: absolute;
  left: 0;
  top: 0.16em;
  width: 1.4rem;
  height: 1.4rem;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 0.78rem;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  color: var(--accent);
  background: var(--raised);
  border: 1px solid var(--hairline);
  border-radius: 50%;
}

.pub-title {
  display: block;
  color: var(--ink-strong);
  font-weight: 600;
  font-size: 1.06rem;
  line-height: 1.35;
  margin-bottom: 0.22rem;
}

.pub-authors {
  display: block;
  font-size: 0.96rem;
  margin-bottom: 0.12rem;
}

.pub-authors .me {
  font-weight: 700;
  color: var(--ink-strong);
}

.pub-venue {
  display: block;
  color: var(--muted);
  font-style: italic;
  font-size: 0.94rem;
}

.pub-links {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
  margin-top: 0.6rem;
}

.pub-links a {
  font-size: 0.85rem;
  font-weight: 500;
  text-decoration: none;
  padding: 0.16rem 0.55rem;
  border: 1px solid var(--hairline);
  border-radius: var(--radius-sm);
  background: var(--raised);
  color: var(--link);
  transition: border-color 0.14s ease, background-color 0.14s ease,
    color 0.14s ease;
}

.pub-links a:hover {
  color: var(--link-hover);
  border-color: var(--accent);
  background: var(--hover-tint);
}

/* --- Collapsible abstracts ----------------------------------------------- */

details.abstract {
  margin-top: 0.6rem;
}

details.abstract > summary {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  cursor: pointer;
  list-style: none;
  color: var(--muted);
  font-size: 0.85rem;
  font-weight: 500;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  user-select: none;
  padding: 0.1rem 0;
  transition: color 0.14s ease;
}

details.abstract > summary::-webkit-details-marker {
  display: none;
}

details.abstract > summary:hover {
  color: var(--accent);
}

details.abstract > summary::before {
  content: "";
  width: 0;
  height: 0;
  border-left: 5px solid currentColor;
  border-top: 4px solid transparent;
  border-bottom: 4px solid transparent;
  transition: transform 0.15s ease;
}

details.abstract[open] > summary::before {
  transform: rotate(90deg);
}

details.abstract[open] > summary {
  color: var(--accent);
}

.abstract-body {
  margin-top: 0.65rem;
  padding: 0.9rem 1.1rem;
  background: var(--raised);
  border: 1px solid var(--hairline);
  border-left: 3px solid var(--accent);
  border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
  font-size: 0.95rem;
  line-height: 1.6;
  color: var(--ink);
}

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

/* --- Generic entry lists (awards, coursework, teaching) ------------------- */

.entries {
  list-style: none;
  margin: 0 0 var(--space-block);
  padding: 0;
}

.entries > li {
  padding: 0.55rem 0;
  border-bottom: 1px solid var(--hairline);
  display: flex;
  flex-wrap: wrap;
  gap: 0.35rem 1rem;
  align-items: baseline;
  justify-content: space-between;
}

.entries > li:last-child {
  border-bottom: none;
}

.entries .what {
  flex: 1 1 auto;
  min-width: 0;
}

.entries .when {
  flex: 0 0 auto;
  color: var(--muted);
  font-size: 0.88rem;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.entries .who {
  display: block;
  color: var(--muted);
  font-size: 0.9rem;
}

/* --- Credential blocks --------------------------------------------------- */

.record {
  padding: 1rem 1.15rem;
  margin-bottom: 1rem;
  background: var(--raised);
  border: 1px solid var(--hairline);
  border-radius: var(--radius);
}

.record-head {
  display: flex;
  flex-wrap: wrap;
  gap: 0.2rem 1rem;
  align-items: baseline;
  justify-content: space-between;
}

.record-org {
  color: var(--ink-strong);
  font-weight: 600;
  font-size: 1.02rem;
}

.record-where,
.record-when {
  color: var(--muted);
  font-size: 0.9rem;
}

.record-when {
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.record-detail {
  margin: 0.35rem 0 0;
  font-size: 0.95rem;
}

.record ul {
  margin: 0.6rem 0 0;
  padding-left: 1.15rem;
}

.record ul li {
  margin-bottom: 0.25rem;
}

.record ul li::marker {
  color: var(--accent);
}

/* --- Fun facts: book covers ---------------------------------------------- */

.books {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
  gap: 1.5rem;
  margin: 1.5rem 0 var(--space-block);
  padding: 0;
  list-style: none;
}

.book figure {
  margin: 0;
}

/* Each cover links to the edition it actually shows. The hover lift below was
   already there and now reads as the click affordance. */
.book-link {
  display: block;
  text-decoration: none;
  border-radius: var(--radius);
}

.book-link:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
}

.book img {
  width: 100%;
  aspect-ratio: 2 / 3;
  object-fit: cover;
  border-radius: var(--radius);
  border: 1px solid var(--hairline);
  box-shadow: var(--shadow);
  transition: transform 0.18s ease, box-shadow 0.18s ease;
}

.book:hover img {
  transform: translateY(-3px);
  box-shadow: var(--shadow-lift);
}

.book figcaption {
  margin-top: 0.65rem;
  font-size: 0.9rem;
  line-height: 1.4;
}

.book .book-title {
  display: block;
  color: var(--ink-strong);
  font-weight: 600;
}

.book .book-author {
  display: block;
  color: var(--muted);
  font-size: 0.85rem;
}

/* Credit line. Smaller and quieter than the author, because on this page the
   author identifies the book and the credit names who made the thing. */
.book .book-credit {
  display: block;
  margin-top: 0.32rem;
  color: var(--muted);
  font-size: 0.78rem;
  line-height: 1.35;
  text-wrap: pretty;
}

/* --- Resource cards ------------------------------------------------------ */

.resources {
  list-style: none;
  margin: 2.75rem 0 0;
  padding: 0;
  display: grid;
  gap: 1.25rem;
}

.resource {
  padding: 1.5rem 1.6rem;
  background: var(--raised);
  border: 1px solid var(--hairline);
  border-radius: var(--radius);
  transition: border-color 0.16s ease, background-color 0.16s ease;
}

.resource:hover {
  border-color: var(--accent);
  background: var(--raised-high);
}

.resource-head {
  display: flex;
  flex-wrap: wrap;
  gap: 0.3rem 1rem;
  align-items: baseline;
  justify-content: space-between;
  margin-bottom: 0.9rem;
}

/* Reuses the h2 size without the section accent bar, which belongs to page
   structure rather than to a card sitting inside it. */
.resource-title {
  margin: 0;
  font-size: calc(var(--size-base) * 1.28);
  line-height: 1.3;
}

.resource-title::after {
  content: none;
}

.resource-meta {
  flex: 0 0 auto;
  color: var(--muted);
  font-size: 0.85rem;
  white-space: nowrap;
}

.resource p {
  font-size: 0.97rem;
  margin-bottom: 0.9rem;
}

.resource p:last-of-type {
  margin-bottom: 0;
}

.resource-links {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
  margin-top: 1.1rem;
}

.resource-links a {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  font-size: 0.88rem;
  font-weight: 500;
  text-decoration: none;
  padding: 0.34rem 0.8rem;
  border: 1px solid var(--accent);
  border-radius: var(--radius-sm);
  background: var(--hover-tint);
  color: var(--link);
  transition: background-color 0.14s ease, color 0.14s ease, transform 0.14s ease;
}

.resource-links a::after {
  content: "\2197";
  font-size: 0.9em;
}

.resource-links a:hover {
  color: var(--ink-strong);
  background: var(--accent);
  transform: translateY(-1px);
}

[data-theme="dark"] .resource-links a:hover {
  color: #14161a;
}

[data-theme="light"] .resource-links a:hover {
  color: #ffffff;
}

/* --- Video embeds -------------------------------------------------------- */

.videos {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 1.25rem;
  margin: 1.25rem 0 var(--space-block);
  padding: 0;
  list-style: none;
}

.videos figure {
  margin: 0;
}

.video-frame {
  position: relative;
  aspect-ratio: 16 / 9;
  border-radius: var(--radius);
  overflow: hidden;
  border: 1px solid var(--hairline);
  background: #000;
}

.video-frame iframe {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  border: 0;
}

.videos figcaption {
  margin-top: 0.5rem;
  font-size: 0.88rem;
  color: var(--muted);
}

/* --- CV page ------------------------------------------------------------- */

.cv-frame {
  width: 100%;
  height: min(85vh, 1000px);
  border: 1px solid var(--hairline);
  border-radius: var(--radius);
  background: var(--raised);
  margin-bottom: 1.25rem;
}

/* --- Callout ------------------------------------------------------------- */

.callout {
  padding: 0.85rem 1.1rem;
  margin: 1.5rem 0 var(--space-block);
  background: var(--raised);
  border: 1px solid var(--hairline);
  border-left: 3px solid var(--accent);
  border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
  font-size: 0.95rem;
}

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

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

.footer {
  border-top: 1px solid var(--hairline);
  background: var(--bg);
  color: var(--muted);
  font-size: 0.88rem;
  padding: 1.75rem 0;
}

.footer .wrap {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem 1.5rem;
  justify-content: space-between;
  align-items: baseline;
}

.footer a {
  color: var(--muted);
}

.footer a:hover {
  color: var(--accent-soft);
}

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

@media (max-width: 780px) {
  .hero {
    grid-template-columns: 1fr;
    gap: 1.75rem;
    padding-top: 2.25rem;
  }

  .hero-photo {
    width: 190px;
    order: -1;
  }

  .nav-inner {
    padding-inline: 1rem;
  }

  .nav-brand {
    font-size: 1rem;
  }

  /* One row, never two, and never a scroller. The tabs drop to their own line
     below the brand so they get the full width, then type and padding scale
     with the viewport so all six fit side by side down to a 320px phone. An
     earlier horizontal scroll here had no visual cue and hid the last tab. */
  .nav-links {
    order: 3;
    width: 100%;
    flex-wrap: nowrap;
    justify-content: center;
    gap: 0.1rem;
  }

  .nav-links a {
    font-size: clamp(0.6rem, 3.05vw, 0.85rem);
    padding: 0.3rem clamp(0.1rem, 0.8vw, 0.42rem);
  }

  .wrap {
    padding-inline: 1rem;
  }

  :root {
    --space-h2-above: 3rem;
  }

  h1 {
    font-size: calc(var(--size-base) * 1.7);
  }

  .entries > li {
    flex-direction: column;
    gap: 0.15rem;
  }

  .cv-frame {
    height: min(70vh, 700px);
  }

  .resource {
    padding: 1.15rem 1.15rem;
  }

  .resource-head {
    flex-direction: column;
    gap: 0.15rem;
  }

  .resource-meta {
    white-space: normal;
  }
}

@media (max-width: 420px) {
  .books {
    grid-template-columns: repeat(2, 1fr);
    gap: 1rem;
  }
}

/* --- Print --------------------------------------------------------------- */

@media print {
  .nav, .footer, .theme-toggle { display: none; }
  body { background: #fff; color: #000; }
  details.abstract { display: none; }
  a { color: #000; text-decoration: none; }
}
