/* kevgao.info — one stylesheet, three themes.
 *
 * Themes sit on a spectrum from social science to tech; pick one in
 * site/content/site.yaml. The dev build adds a switcher to compare them.
 *   journal  all-serif text, warm paper, oxblood accent    (econ / NBER feel)
 *   ledger   serif headings, sans body, indigo accent       (hybrid, default)
 *   plex     IBM Plex sans + mono, cool grey, teal accent   (tech / research lab)
 * Each theme defines light tokens and dark tokens; layout is shared. */

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

:root, :root[data-theme="ledger"] {
  --font-head: "Newsreader", Georgia, serif;
  --font-body: "Inter", system-ui, sans-serif;
  --font-mono: "JetBrains Mono", ui-monospace, monospace;
  --font-math: "Newsreader", Georgia, serif;
  --head-weight: 500;
  --body-size: 1rem;
  --bg: #fafaf8;  --ink: #17191e;  --muted: #5c636e;  --rule: #e4e4df;
  --accent: #3a4cc0;  --accent-soft: #eceefb;  --dot: #d9dae0;
}
:root[data-theme="journal"] {
  --font-head: "Source Serif 4", Georgia, serif;
  --font-body: "Source Serif 4", Georgia, serif;
  --font-mono: "IBM Plex Mono", ui-monospace, monospace;
  --font-math: "Source Serif 4", Georgia, serif;
  --head-weight: 600;
  --body-size: 1.075rem;
  --bg: #fbf9f4;  --ink: #1d1a17;  --muted: #66605a;  --rule: #e7e1d6;
  --accent: #8c2f2b;  --accent-soft: #f6e9e6;  --dot: #e2dacb;
}
:root[data-theme="plex"] {
  --font-head: "IBM Plex Sans", system-ui, sans-serif;
  --font-body: "IBM Plex Sans", system-ui, sans-serif;
  --font-mono: "IBM Plex Mono", ui-monospace, monospace;
  --font-math: "IBM Plex Serif", Georgia, serif;
  --head-weight: 600;
  --body-size: 1rem;
  --bg: #f7f8f9;  --ink: #141a1f;  --muted: #5a6570;  --rule: #e1e5e9;
  --accent: #0e7c74;  --accent-soft: #e3f3f1;  --dot: #d3dae0;
}

/* Dark tokens: applied under the OS preference unless forced light, and
 * whenever forced dark. Written twice because CSS can't share a block
 * between a media query and an attribute selector. */
@media (prefers-color-scheme: dark) {
  :root:not([data-mode="light"]), :root[data-theme="ledger"]:not([data-mode="light"]) {
    --bg: #121418; --ink: #e7e8ec; --muted: #9aa1ad; --rule: #2a2d34;
    --accent: #9aa8ff; --accent-soft: #23284a; --dot: #2a2d36;
  }
  :root[data-theme="journal"]:not([data-mode="light"]) {
    --bg: #171513; --ink: #ece6dc; --muted: #a59d92; --rule: #302b26;
    --accent: #e3938a; --accent-soft: #3a2421; --dot: #2f2a24;
  }
  :root[data-theme="plex"]:not([data-mode="light"]) {
    --bg: #101416; --ink: #e3e8eb; --muted: #94a0a9; --rule: #263036;
    --accent: #5cc8bc; --accent-soft: #13312e; --dot: #243037;
  }
}
:root[data-mode="dark"], :root[data-theme="ledger"][data-mode="dark"] {
  --bg: #121418; --ink: #e7e8ec; --muted: #9aa1ad; --rule: #2a2d34;
  --accent: #9aa8ff; --accent-soft: #23284a; --dot: #2a2d36;
}
:root[data-theme="journal"][data-mode="dark"] {
  --bg: #171513; --ink: #ece6dc; --muted: #a59d92; --rule: #302b26;
  --accent: #e3938a; --accent-soft: #3a2421; --dot: #2f2a24;
}
:root[data-theme="plex"][data-mode="dark"] {
  --bg: #101416; --ink: #e3e8eb; --muted: #94a0a9; --rule: #263036;
  --accent: #5cc8bc; --accent-soft: #13312e; --dot: #243037;
}

/* ---------------------------------------------------------------- base */

*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font: 400 var(--body-size)/1.65 var(--font-body);
  font-feature-settings: "kern", "liga";
  text-rendering: optimizeLegibility;
  -webkit-font-smoothing: antialiased;
}
a { color: var(--accent); text-decoration-thickness: 1px; text-underline-offset: 0.18em; }
a:hover { text-decoration-thickness: 2px; }
h1, h2, h3 { font-family: var(--font-head); font-weight: var(--head-weight); line-height: 1.2; margin: 0; }
img { max-width: 100%; height: auto; }

.wrap { max-width: 50rem; margin: 0 auto; padding: 0 1.25rem; }

/* ---------------------------------------------------------------- masthead */

.masthead { border-bottom: 1px solid var(--rule); }
.masthead-row {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 1rem; flex-wrap: wrap; padding-top: 1.25rem; padding-bottom: 1.1rem;
}
.wordmark {
  font-family: var(--font-head); font-weight: var(--head-weight);
  font-size: 1.15rem; color: var(--ink); text-decoration: none; letter-spacing: -0.005em;
}
nav { display: flex; gap: 1.4rem; font-family: var(--font-mono); font-size: 0.8rem; }
nav a { color: var(--muted); text-decoration: none; letter-spacing: 0.02em; }
nav a:hover, nav a[aria-current="page"] { color: var(--ink); }
nav a[aria-current="page"] { box-shadow: inset 0 -2px 0 var(--accent); }
.nav-cv { color: var(--accent) !important; }

main.wrap { padding-top: 3rem; padding-bottom: 4rem; }

/* ---------------------------------------------------------------- shared type */

.eyebrow, .section-label, .status, .year, .tag, .chip, .code, .level, .terms, .role {
  font-family: var(--font-mono);
}
.eyebrow {
  margin: 0 0 0.6rem; font-size: 0.75rem; letter-spacing: 0.08em;
  text-transform: uppercase; color: var(--accent);
}
.page-title { font-size: clamp(1.8rem, 4vw, 2.2rem); letter-spacing: -0.01em; margin-bottom: 1.75rem; }
.section-label {
  display: flex; align-items: baseline; gap: 0.75rem;
  font-size: 0.78rem; font-weight: 500; letter-spacing: 0.08em; text-transform: uppercase;
  color: var(--muted); margin: 2.25rem 0 0.25rem; padding-bottom: 0.5rem;
  border-bottom: 1px solid var(--rule);
}
.section-label span { color: var(--accent); }
section:first-of-type .section-label { margin-top: 0; }
.prose p { margin: 0 0 1.15em; max-width: 40rem; }
.lede { font-size: 1.4rem; margin: 0 0 1.25rem; }

/* ---------------------------------------------------------------- home */

.hero {
  display: grid; grid-template-columns: 11rem 1fr; gap: 2.25rem; align-items: end;
  padding-bottom: 2.5rem; margin-bottom: 2.5rem; border-bottom: 1px solid var(--rule);
}
.portrait {
  width: 11rem; aspect-ratio: 360 / 468; object-fit: cover;
  border-radius: 6px; filter: grayscale(0.15) contrast(1.02);
  box-shadow: 0 0 0 1px var(--rule);
}
.hero h1 { font-size: clamp(2.1rem, 5.5vw, 2.9rem); letter-spacing: -0.015em; }
.affil { margin: 0.6rem 0 1rem; color: var(--muted); max-width: 28rem; }
.contact { list-style: none; padding: 0; margin: 0; display: flex; flex-wrap: wrap; gap: 0.4rem 1.25rem;
  font-family: var(--font-mono); font-size: 0.82rem; }

/* ---------------------------------------------------------------- research */

.papers { list-style: none; margin: 0; padding: 0; }
.paper { padding: 0.95rem 0; border-bottom: 1px solid var(--rule); }
.paper:last-child { border-bottom: 0; }
.paper-meta {
  margin: 0 0 0.2rem; font-family: var(--font-mono); font-size: 0.7rem;
  letter-spacing: 0.02em; color: var(--muted);
}
.paper-meta em { font-style: normal; color: var(--muted); }
.jmp {
  display: inline-block; margin-right: 0.6rem; padding: 0.05rem 0.45rem; border-radius: 3px;
  background: var(--accent); color: var(--bg); text-transform: uppercase; letter-spacing: 0.06em;
}
.paper-title { font-size: 1.03rem; line-height: 1.35; margin-bottom: 0.2rem; }
.authors, .venue, .note { margin: 0.1rem 0; font-size: 0.87rem; line-height: 1.5; color: var(--muted); }
.me { color: var(--ink); font-weight: 500; }
.note { font-style: italic; }
.paper-foot { display: flex; flex-wrap: wrap; align-items: baseline; gap: 0.4rem; margin-top: 0.45rem; }
.chip {
  font-family: var(--font-mono); font-size: 0.68rem; letter-spacing: 0.04em; text-decoration: none;
  padding: 0.05rem 0.45rem; border-radius: 3px;
  color: var(--muted); border: 1px solid var(--rule);
}
.chip:hover { color: var(--accent); border-color: var(--accent); }
.summary { flex-basis: 100%; font-size: 0.9rem; }
.summary > summary {
  display: inline-block; cursor: pointer; list-style: none;
  font-family: var(--font-mono); font-size: 0.68rem; letter-spacing: 0.04em; color: var(--muted);
}
.summary > summary::-webkit-details-marker { display: none; }
.summary > summary::before { content: "+ "; color: var(--accent); }
.summary[open] > summary::before { content: "− "; }
.summary > p, .summary > ul {
  margin: 0.6rem 0 0.2rem; padding-left: 0.9rem; border-left: 2px solid var(--accent-soft);
  max-width: 42rem; color: var(--ink);
}
.summary > ul { padding-left: 1.6rem; }
.summary li { margin-bottom: 0.35rem; }

/* ---------------------------------------------------------------- teaching */

.role { font-size: 0.8rem; color: var(--muted); margin: 0 0 0.5rem; }
.courses { list-style: none; margin: 0; padding: 0; }
.course {
  display: grid; grid-template-columns: 6.5rem 1fr auto; gap: 1.25rem; align-items: baseline;
  padding: 0.7rem 0; border-bottom: 1px dashed var(--rule);
}
.course:last-child { border-bottom: 0; }
.code { font-size: 0.8rem; color: var(--accent); white-space: nowrap; }
.course-title { font-size: 0.98rem; }
.level {
  font-size: 0.66rem; letter-spacing: 0.05em; color: var(--muted);
  border: 1px solid var(--rule); border-radius: 3px; padding: 0.05rem 0.35rem; margin-left: 0.25rem;
  vertical-align: 0.1em;
}
.course .note { font-style: normal; font-size: 0.86rem; margin-top: 0.3rem; max-width: 34rem; }
.terms { font-size: 0.74rem; color: var(--muted); text-align: right; max-width: 12rem; }

/* ---------------------------------------------------------------- art */
/* SVGs from tools/banner.py, shown once per page. From 60rem up: one panel
 * in the right margin, behind the content, fading in from the column edge and
 * out toward the screen edge and down the page. Clipped to the page so it
 * never lengthens a short one. Below 60rem: one strip under the header.
 *
 * To keep >= 18rem free on the right, the content column slides left of
 * centre on mid-size screens and narrows below ~68rem; it is centred again
 * from ~86rem. --col and --left are percentages of the page width, so they
 * resolve the same for every full-width container that uses them. */

.page { position: relative; }
.art { position: absolute; inset: 0; overflow: hidden; pointer-events: none; z-index: -1; display: none; }
.art-panel {
  position: absolute; top: 0; width: 700px; height: 1200px;
  -webkit-mask-image: linear-gradient(to right, transparent, #000 110px, #000 45%, transparent 92%),
                      linear-gradient(to bottom, transparent, #000 40px, #000 70%, transparent);
  -webkit-mask-composite: source-in;
          mask-image: linear-gradient(to right, transparent, #000 110px, #000 45%, transparent 92%),
                      linear-gradient(to bottom, transparent, #000 40px, #000 70%, transparent);
          mask-composite: intersect;
}
@media (min-width: 60rem) {
  :root {
    --col: min(50rem, calc(100% - 18rem));
    --left: max(1.25rem, min(calc((100% - 50rem) / 2), calc(100% - 68rem)));
  }
  .wrap { max-width: none; width: var(--col); margin-left: var(--left); margin-right: 0; }
  .art { display: block; }
  .art-panel { left: calc(var(--left) + var(--col) - 2rem); }
  .strip { display: none; }
}
.panel-art { display: block; }

.strip { max-width: 1920px; margin: 0 auto; overflow: hidden; border-bottom: 1px solid var(--rule);
  -webkit-mask-image: linear-gradient(to right, transparent, #000 6%, #000 94%, transparent);
          mask-image: linear-gradient(to right, transparent, #000 6%, #000 94%, transparent); }
.strip-art { display: block; width: 100%; height: 150px; }


.bn-grid line { stroke: var(--rule); stroke-width: 1; opacity: 0.7; }
.bn-edge line { stroke: var(--muted); stroke-width: 0.8; opacity: 0.22; }
.bn-hot line { stroke: var(--accent); stroke-width: 1.6; }
.bn-node { fill: var(--bg); stroke: var(--muted); stroke-width: 1.2; }
.bn-node.hot { fill: var(--accent); stroke: var(--accent); }
.bn-attn rect { fill: var(--accent); }
.bn-code { font-family: var(--font-mono); font-size: 13px; fill: var(--muted); }
.bn-tiny { font-size: 10.5px; letter-spacing: 0.03em; }
.bn-tab { font-size: 12px; fill: var(--ink); opacity: 0.8; }
.bn-accent { fill: var(--accent); }
.bn-train { fill: none; stroke: var(--accent); stroke-width: 1.6; }
.bn-val { fill: none; stroke: var(--muted); stroke-width: 1.4; stroke-dasharray: 4 3; }
.bn-emb { opacity: 0.75; }
.bn-emb.a { fill: var(--accent); }
.bn-emb.b { fill: var(--muted); }
.bn-emb.c { fill: none; stroke: var(--ink); stroke-width: 1; opacity: 0.5; }
.bn-econ-bg { fill: var(--accent-soft); opacity: 0.35; }
.bn-math { font-family: var(--font-math); font-style: italic; font-size: 17px; fill: var(--ink); }
.bn-eq { font-size: 22px; }
.bn-eq-b { font-size: 20px; opacity: 0.8; }
.bn-sub { font-size: 0.7em; }
.bn-caption { font-size: 10.5px; font-style: normal; letter-spacing: 0.06em; opacity: 0.85; }
.bn-small { font-size: 14px; fill: var(--muted); }
.bn-axis { fill: none; stroke: var(--muted); stroke-width: 1.2; }
.bn-pt { fill: var(--muted); opacity: 0.55; }
.bn-band { fill: var(--accent); opacity: 0.14; }
.bn-fit { stroke: var(--accent); stroke-width: 2; }
.bn-fitline { fill: none; stroke: var(--accent); stroke-width: 2; }
.bn-rug { stroke: var(--muted); stroke-width: 1; opacity: 0.6; }
.bn-fold { fill: var(--rule); }
.bn-fold.hot { fill: var(--accent); }
.bn-rule { stroke: var(--muted); stroke-width: 1; opacity: 0.6; }
.bn-curve { fill: none; stroke: var(--ink); stroke-width: 1.6; opacity: 0.75; }
.bn-dash { fill: none; stroke: var(--muted); stroke-width: 1; stroke-dasharray: 3 4; }
.bn-eqpt { fill: var(--accent); }
.bn-coef { stroke: var(--muted); fill: var(--muted); stroke-width: 1.3; }
.bn-coef.hot { stroke: var(--accent); fill: var(--accent); }
.bn-seam { stroke: var(--accent); stroke-width: 1.5; opacity: 0.8; }

/* ---------------------------------------------------------------- footer */

.footer {
  display: flex; justify-content: space-between; flex-wrap: wrap; gap: 0.5rem;
  padding-top: 1.25rem; padding-bottom: 2.5rem;
  font-family: var(--font-mono); font-size: 0.72rem; color: var(--muted);
}

/* ---------------------------------------------------------------- dev switcher */

.devbar {
  position: fixed; right: 1rem; bottom: 1rem; z-index: 10;
  display: grid; grid-template-columns: auto auto; gap: 0.4rem 0.6rem; align-items: center;
  padding: 0.6rem 0.75rem; border-radius: 8px;
  background: var(--bg); border: 1px solid var(--rule);
  box-shadow: 0 6px 24px rgb(0 0 0 / 0.12);
  font-family: var(--font-mono); font-size: 0.7rem;
}
.devbar-label { color: var(--muted); text-transform: uppercase; letter-spacing: 0.08em; }
.devbar-group { display: flex; gap: 0.25rem; }
.devbar button {
  font: inherit; cursor: pointer; padding: 0.2rem 0.5rem; border-radius: 4px;
  border: 1px solid var(--rule); background: transparent; color: var(--ink);
}
.devbar button[aria-pressed="true"] { background: var(--accent); border-color: var(--accent); color: var(--bg); }

/* ---------------------------------------------------------------- small screens */

@media (max-width: 40rem) {
  main.wrap { padding-top: 2rem; }
  nav { gap: 1rem; }
  .hero { grid-template-columns: 1fr; gap: 1.25rem; align-items: start; }
  .portrait { width: 8rem; }
  .strip-art { height: 100px; }
  .course { grid-template-columns: 1fr; gap: 0.15rem; }
  .terms { text-align: left; max-width: none; }
  .devbar { left: 1rem; right: 1rem; }
}
