/* ---------- font: Latin Modern (the LaTeX font) ---------- */
@font-face { font-family: "Latin Modern"; src: url("fonts/LM-regular.woff2") format("woff2"); font-weight: 400; font-style: normal; font-display: swap; }
@font-face { font-family: "Latin Modern"; src: url("fonts/LM-italic.woff2") format("woff2"); font-weight: 400; font-style: italic; font-display: swap; }
@font-face { font-family: "Latin Modern"; src: url("fonts/LM-bold.woff2") format("woff2"); font-weight: 700; font-style: normal; font-display: swap; }
@font-face { font-family: "CMU Typewriter"; src: url("fonts/CMU-typewriter.woff2") format("woff2"); font-weight: 400; font-style: normal; font-display: swap; }
@font-face { font-family: "Latin Modern"; src: url("fonts/LM-bold-italic.woff2") format("woff2"); font-weight: 700; font-style: italic; font-display: swap; }

/* ---------- other fonts for the font picker (fonts.js) ---------- */
@font-face { font-family: "IBM Plex Sans"; src: url("fonts/Plex-regular.woff2") format("woff2"); font-weight: 400; font-style: normal; font-display: swap; }
@font-face { font-family: "IBM Plex Sans"; src: url("fonts/Plex-italic.woff2") format("woff2"); font-weight: 400; font-style: italic; font-display: swap; }
@font-face { font-family: "IBM Plex Sans"; src: url("fonts/Plex-bold.woff2") format("woff2"); font-weight: 700; font-style: normal; font-display: swap; }
@font-face { font-family: "IBM Plex Sans"; src: url("fonts/Plex-bold-italic.woff2") format("woff2"); font-weight: 700; font-style: italic; font-display: swap; }
@font-face { font-family: "Source Serif 4"; src: url("fonts/SourceSerif-regular.woff2") format("woff2"); font-weight: 400; font-style: normal; font-display: swap; }
@font-face { font-family: "Source Serif 4"; src: url("fonts/SourceSerif-italic.woff2") format("woff2"); font-weight: 400; font-style: italic; font-display: swap; }
@font-face { font-family: "Source Serif 4"; src: url("fonts/SourceSerif-bold.woff2") format("woff2"); font-weight: 700; font-style: normal; font-display: swap; }
@font-face { font-family: "Source Serif 4"; src: url("fonts/SourceSerif-bold-italic.woff2") format("woff2"); font-weight: 700; font-style: italic; font-display: swap; }
@font-face { font-family: "Comic Mono"; src: url("fonts/ComicMono-regular.woff2") format("woff2"); font-weight: 400; font-style: normal; font-display: swap; }
@font-face { font-family: "Comic Mono"; src: url("fonts/ComicMono-bold.woff2") format("woff2"); font-weight: 700; font-style: normal; font-display: swap; }

/* ---------- colors ---------- */
:root {
  --text: #17191b;
  --muted: #585752;
  --rule: #cdccc4;
  --link: #3366cc;
  --bg: #fffffe;
  --highlight: #fff3b0;
  --code-bg: #f5f4ef;
  --code-head: #ebeae3;
  --img-bg: transparent;
  --tok-comment: #66655e;
  --tok-keyword: #a0306a;
  --tok-string: #25692a;
  --tok-number: #964c00;
  --tok-function: #2a5db0;
  --tok-class: #7b4bb3;
  --tok-operator: #585752;
  color-scheme: light;
}

/* ---------- page ---------- */
* { box-sizing: border-box; }

/* Michelangelus can't be hosted here (its license bans redistribution), so it only shows if the visitor has it installed */
:root { --font: "Latin Modern", Georgia, serif; --mono: "CMU Typewriter", Menlo, Consolas, monospace; }
:root[data-font="michelangelus"] { --font: "Michelangelus", Georgia, serif; }
:root[data-font="times"] { --font: "Times New Roman", Times, serif; }
:root[data-font="plex"] { --font: "IBM Plex Sans", Helvetica, Arial, sans-serif; }
:root[data-font="helvetica"] { --font: "Helvetica Neue", Helvetica, Arial, sans-serif; }
:root[data-font="source-serif"] { --font: "Source Serif 4", Georgia, serif; }
:root[data-font="comic-sans"] { --font: "Comic Sans MS", "Comic Sans", "Chalkboard SE", "Comic Neue", cursive; --mono: "Comic Mono", Menlo, Consolas, monospace; }

html {
  font-family: var(--font);
  font-size: 17px;
  line-height: 1.5;
  color: var(--text);
  background: var(--bg);
}

body {
  width: min(760px, calc(100% - 32px));
  margin: 0 auto;
  counter-reset: fig;
}

img, video { max-width: 100%; height: auto; }
figure img { background: var(--img-bg); }  /* white behind transparent charts in dark mode, so their black lines stay visible */

a { color: var(--link); text-decoration: none; }
a:hover { text-decoration: underline; }

p { margin: 0 0 1em; }

h2, h3 { scroll-margin-top: 90px; }
/* a paragraph you link to from elsewhere in the post: <p id="name">...</p>, link with <a href="#name"> */
p[id] { scroll-margin-top: 90px; }

h1 { font-size: 1.9em; line-height: 1.25; margin: 0 0 .2em; }
h2 {
  font-size: 1.35em;
  margin: 1.6em 0 .7em;
  padding-bottom: 3px;
  border-bottom: 1px solid var(--muted);
}

ul { padding-left: 1.3em; }
li + li { margin-top: .35em; }

.muted { color: var(--muted); }
sup { white-space: nowrap; line-height: 0; }

/* ---------- figures: numbered automatically (Fig. 1, Fig. 2, ...) ---------- */
figure { margin: 1.4em 0; text-align: center; }
figure img, figure video { max-width: 100%; height: auto; }
figure.small img, figure.small video { width: 60%; }
figure.smaller img { width: 42%; }
figure.smallest img { width: 32%; }
figcaption {
  counter-increment: fig;
  font-size: .85em;
  font-style: italic;
  color: var(--muted);
  margin-top: .5em;
}
figcaption::before {
  content: "Fig. " counter(fig) "  ";
  font-style: normal;
  font-weight: 700;
  white-space: pre;
}
/* a figure that isn't part of a numbered sequence, like the photo on the about page */
figure.plain figcaption { counter-increment: none; }
figure.plain figcaption::before { content: none; }
/* a figure the text wraps around, like the chip next to the about-page intro */
figure.float-left { float: left; width: 36%; margin: .3em 1.5em .8em 0; }
figure.float-left img { width: 100%; }
h2 { clear: both; }  /* a new section always starts below a floated figure */

/* ---------- header and nav ---------- */
.header {
  position: sticky;
  top: 0;
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: .2rem 1rem;
  padding: 32px 0 6px;
  margin-bottom: 30px;
  border-bottom: 1px solid var(--rule);
  background: var(--bg);
}
.header a { color: var(--text); }
.header a:hover { color: var(--link); text-decoration: none; }
.header .name { flex-grow: 1; font-size: 1.3em; font-weight: 700; }
.header nav { display: flex; flex-wrap: wrap; align-items: center; gap: .6rem; }
.header nav span { color: var(--muted); }
.header nav a.here { text-decoration: underline; text-underline-offset: 3px; }
.header select {
  font: inherit;
  font-size: .85em;
  color: var(--muted);
  background: var(--bg);
  border: 1px solid var(--rule);
  border-radius: 3px;
  padding: 0 2px;
  cursor: pointer;
}

.footer {
  margin: 3em 0 4em;
  padding-top: 10px;
  border-top: 1px solid var(--rule);
  font-size: .85em;
  color: var(--muted);
  text-align: center;
}

/* ---------- about page ---------- */
.intro { margin-bottom: 1.6em; }
.intro p { margin: .3em 0; }

.row { display: flex; justify-content: space-between; flex-wrap: wrap; gap: 0 1em; }

.list { display: grid; grid-template-columns: 8.5em 1fr; gap: .3em 1em; margin: 1em 0; }
.list dt { font-style: italic; color: var(--muted); }
.list dd { margin: 0; }

/* ---------- blog list (like Eileen Yoon's) ---------- */
.post {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 0 1em;
  padding-bottom: 9px;
  margin-bottom: 9px;
  border-bottom: 1px dotted var(--muted);
}
.post a { color: var(--text); }
.post a:hover { color: var(--link); text-decoration: none; }
.post .meta { color: var(--muted); white-space: nowrap; }
.words { font-style: italic; }
.pin { width: .8em; height: .8em; margin-right: .35em; fill: var(--muted); transform: rotate(35deg); vertical-align: -.05em; }

/* ---------- journal timeline ---------- */
.semester {
  font-weight: 700;
  margin: 1.8em 0 .2em;
  padding-bottom: 3px;
  border-bottom: 1px solid var(--muted);
}
.entry {
  display: grid;
  grid-template-columns: 7.5em 1fr;
  gap: .3em 1.1em;
  padding: .7em 0;
  border-bottom: 1px dotted var(--rule);
}
.entry .date { font-weight: 700; }
.entry .date span { background: var(--highlight); padding: 0 4px; }
.entry p:last-child { margin-bottom: 0; }
.entry figure { text-align: left; }
.entry figure img { max-height: 340px; width: auto; }
.entry figure.wide img { max-height: none; width: 100%; }
.two-photos { display: flex; gap: 12px; }
.two-photos img { width: calc(50% - 6px); }

.note { border: 1px solid var(--text); padding: .5em .9em; margin: 1.3em 0; }

/* ---------- blog post ---------- */
.post-date { color: var(--muted); margin-bottom: 1.5em; }

/* small two-column spec table (RoboMaster post) */
table.spec { border-collapse: collapse; margin: .8em 0 1.2em; }
table.spec td { padding: 4px 14px 4px 0; border-bottom: 1px solid var(--rule); }
table.spec td:first-child { font-style: italic; color: var(--muted); }

/* LaTeX booktabs table: heavy top and bottom rules, thin rule under the header */
.table-wrap { overflow-x: auto; margin: 1.2em 0 1.4em; }
table.booktabs {
  border-collapse: collapse;
  margin: 0 auto;
  font-size: .92em;
  border-top: 1.5px solid var(--text);
  border-bottom: 1.5px solid var(--text);
}
table.booktabs th, table.booktabs td { padding: 4px 12px; text-align: left; vertical-align: top; }
table.booktabs thead th { border-bottom: 1px solid var(--text); font-weight: 700; }
table.booktabs tbody tr:first-child td { padding-top: 6px; }
table.booktabs tbody tr:last-child td { padding-bottom: 6px; }
table.booktabs.num td + td, table.booktabs.num th + th { text-align: right; }  /* numbers: right-align every column after the first */
table.booktabs.num td + td { white-space: nowrap; }
table.booktabs tr.group td { font-style: italic; color: var(--muted); padding-top: 8px; }  /* a row naming a group, like a benchmark suite */
table.booktabs tr.total td { border-top: 1px solid var(--text); font-weight: 700; }  /* geomean row */
table.booktabs td.desc { min-width: 14em; }  /* a long text column that shouldn't get squeezed */
table.booktabs td.input { min-width: 9em; }  /* input-size column in the benchmark tables */
table.booktabs .nowrap { white-space: nowrap; }

.eq { text-align: center; margin: 1em 0 1.2em; }  /* a centered one-line equation */
.eq code { background: none; padding: 0; }  /* code in an equation looks like LaTeX \texttt, no box */
/* a stacked fraction, like LaTeX \frac. Use inside .eq:
   <p class="eq">x = <span class="frac"><span>top</span><span>bottom</span></span></p> */
.frac { display: inline-flex; flex-direction: column; vertical-align: middle; text-align: center; margin: 0 .25em; }
.frac > span { padding: 0 .3em; }
.frac > span:first-child { border-bottom: 1px solid currentColor; padding-bottom: .2em; }
.frac > span:last-child { padding-top: .2em; }

/* code, in Computer Modern Typewriter (LaTeX's \texttt) */
code, pre { font-family: var(--mono); }
code { font-size: .92em; line-height: 1; background: var(--code-bg); padding: 0 4px; border-radius: 3px; }
pre {
  overflow-x: auto;
  margin: 1em 0 1.2em;
  padding: .7em 1em;
  background: var(--code-bg);
  border: 1px solid var(--rule);
  border-radius: 4px;
  font-size: .8em;
  line-height: 1.45;
}
code { overflow-wrap: anywhere; }  /* long names like a::b() can break on phones instead of pushing the page wider */
pre code { font-size: 1em; background: none; padding: 0; border-radius: 0; }

/* code block with a file name on top, like an editor tab:
   <div class="code-file" data-file="allocator.py"><pre><code class="language-python">...</code></pre></div>
   The language class turns on syntax colors (needs the two Prism <script> tags, see posts/kv-pimple.html).
   Leave the class off for diagrams and plain text. */
.code-file { margin: 1em 0 1.2em; border: 1px solid var(--rule); border-radius: 4px; overflow: hidden; background: var(--code-bg); }
.code-file::before {
  content: attr(data-file);
  display: block;
  padding: .3em 1em;
  border-bottom: 1px solid var(--rule);
  background: var(--code-head);
  color: var(--muted);
  font-family: var(--mono);
  font-size: .78em;
}
.code-file pre { margin: 0; border: none; border-radius: 0; }

/* syntax colors (Prism token classes), a light theme to match the page */
.token.comment, .token.prolog { color: var(--tok-comment); font-style: italic; }
.token.keyword, .token.important { color: var(--tok-keyword); }
.token.string, .token.char { color: var(--tok-string); }
.token.number, .token.boolean, .token.constant { color: var(--tok-number); }
.token.function { color: var(--tok-function); }
.token.class-name, .token.builtin { color: var(--tok-class); }
.token.operator, .token.punctuation { color: var(--tok-operator); }
.token.variable, .token.parameter { color: var(--text); }

/* footnotes, at the end of the section they belong to.
   In the text:  <sup><a href="#fn1" id="fnref1">1</a></sup>
   Before the next <h2>:
   <div class="footnotes"><ol><li id="fn1" value="1">The note. <a href="#fnref1">&#8617;</a></li></ol></div> */
.footnotes { margin: 1.4em 0 0; padding-top: .5em; border-top: 1px solid var(--rule); font-size: .85em; color: var(--muted); }
.footnotes ol { margin: 0; padding-left: 1.3em; }
.footnotes li, sup a { scroll-margin-top: 90px; }

/* references, IEEE style, as the last section of a post. Numbers fill in automatically.
   <h2 id="references">References</h2>
   <ol class="refs"><li id="ref1">A. Author, &ldquo;Title,&rdquo; ...</li></ol>
   Cite in the text with <a href="#ref1">[1]</a>. */
.refs { list-style: none; counter-reset: ref; margin: 0; padding-left: 2.4em; font-size: .9em; }
.refs li { counter-increment: ref; position: relative; margin: .4em 0; overflow-wrap: anywhere; scroll-margin-top: 90px; }
.refs li::before { content: "[" counter(ref) "]"; position: absolute; left: -2.4em; color: var(--muted); }

blockquote { margin: 1em 0; padding-left: 1em; border-left: 2px solid var(--rule); font-style: italic; }

.contents { margin: 1.4em 0; }
.contents p { margin: 0; }
.contents ul { margin: .3em 0 0; }
.contents li + li { margin-top: .1em; }

/* table of contents built by toc.js. Inline (h2 only) by default, a sidebar on the right on wide screens */
.toc ul { list-style: none; padding-left: 0; }
.toc li + li, .toc li > ul { margin-top: .1em; }
.toc .toc-title > a, .toc ul ul ul { display: none; }
.toc .toc-title > ul { padding-left: 1.3em; list-style: disc; margin: .3em 0 0; }

@media (min-width: 1300px) {
  .toc {
    position: fixed;
    top: 110px;
    left: calc(50% + 380px + 32px);
    width: 220px;
    max-height: calc(100vh - 130px);
    overflow-y: auto;
    scrollbar-width: none;
    margin: 0;
    font-size: .82em;
    line-height: 1.3;
  }
  .toc::-webkit-scrollbar { display: none; }
  .toc .toc-head { padding-bottom: 6px; margin-bottom: 10px; border-bottom: 1px solid var(--rule); }
  .toc .toc-head b { font-weight: 400; color: var(--text); font-size: 1.15em; }
  .toc .toc-title > a, .toc ul ul ul { display: block; }
  .toc .toc-title > ul { list-style: none; margin: 0; }
  .toc ul ul { padding-left: 1.1em; }
  .toc ul { padding-left: .7em; }
  .toc li + li, .toc li > ul { margin-top: .45em; }
  .toc a { display: block; color: var(--muted); }
  .toc a:hover { color: var(--link); text-decoration: none; }
  .toc a.active { color: var(--text); font-weight: 700; }
  .toc a.active::before {
    content: "";
    position: absolute;
    left: 0;
    width: 2px;
    height: 1.3em;
    background: var(--link);
  }
}

figure .pair { display: flex; gap: 12px; justify-content: center; align-items: flex-start; }
figure .pair img { width: calc(50% - 6px); }
/* same, with each image linking to its full-size file:
   <figure><div class="pair"><a href="a.webp"><img ...></a><a href="b.webp"><img ...></a></div><figcaption>...</figcaption></figure> */
figure .pair > a { width: calc(50% - 6px); }
figure .pair > a img { width: 100%; }

/* ---------- phones ---------- */
@media (max-width: 600px) {
  html { font-size: 16px; }
  .toc { display: none; }
  .header { padding-top: 16px; }
  .list, .entry { grid-template-columns: 1fr; }
  .eq:has(.frac) { font-size: .74em; }  /* keep a fraction on one line */
  .list dd { margin-bottom: .5em; }
  figure.small img, figure.small video { width: 100%; }
  figure.float-left { float: none; width: auto; margin: 1.4em 0; }
  figure.float-left img { width: 75%; }
  .bio { display: flex; flex-direction: column; }
  .bio figure { order: 1; }  /* on phones the intro text comes first, the chip after it */
  figure.smaller img { width: 75%; }
  figure.smallest img { width: 60%; }
  table.booktabs { font-size: .82em; }
  table.booktabs th, table.booktabs td { padding: 4px 8px; }
}

/* ---------- color themes, picked from the swatch menu in the nav (fonts.js) ----------
   paper is the default (the :root colors above). Every theme keeps text, muted text,
   links and code colors at 4.5:1 contrast or better against its background. */

:root[data-theme="cream"] {
  --text: #2a251e;
  --muted: #675d4f;
  --rule: #e0d6c2;
  --link: #2f5c9e;
  --bg: #f9f4e8;
  --highlight: #f4df92;
  --code-bg: #f1e9d8;
  --code-head: #e8ddc8;
  --img-bg: transparent;
  --tok-comment: #66655e;
  --tok-keyword: #a0306a;
  --tok-string: #25692a;
  --tok-number: #964c00;
  --tok-function: #2a5db0;
  --tok-class: #7b4bb3;
  --tok-operator: #675d4f;
  color-scheme: light;
}

:root[data-theme="cocoa"] {
  --text: #f0e6d6;
  --muted: #c4b5a1;
  --rule: #56493f;
  --link: #ecc37f;
  --bg: #3b322b;
  --highlight: #6e5527;
  --code-bg: #453b33;
  --code-head: #4e433a;
  --img-bg: #f2efe8;
  --tok-comment: #b8b5ab;
  --tok-keyword: #f0a3c8;
  --tok-string: #a6dca0;
  --tok-number: #f2b880;
  --tok-function: #a8c8f8;
  --tok-class: #cdb4f2;
  --tok-operator: #c4b5a1;
  color-scheme: dark;
}

:root[data-theme="dusk"] {
  --text: #ebe6dd;
  --muted: #b5afa5;
  --rule: #4d4b55;
  --link: #a8c8f8;
  --bg: #34333b;
  --highlight: #6e5d2c;
  --code-bg: #3d3c45;
  --code-head: #46454e;
  --img-bg: #f2efe8;
  --tok-comment: #b8b5ab;
  --tok-keyword: #f0a3c8;
  --tok-string: #a6dca0;
  --tok-number: #f2b880;
  --tok-function: #a8c8f8;
  --tok-class: #cdb4f2;
  --tok-operator: #b5afa5;
  color-scheme: dark;
}

:root[data-theme="moss"] {
  --text: #e5eae1;
  --muted: #adb8aa;
  --rule: #4a554d;
  --link: #a9d3e8;
  --bg: #2f3631;
  --highlight: #5f5a2c;
  --code-bg: #38403a;
  --code-head: #414a43;
  --img-bg: #f2efe8;
  --tok-comment: #b8b5ab;
  --tok-keyword: #f0a3c8;
  --tok-string: #a6dca0;
  --tok-number: #f2b880;
  --tok-function: #a8c8f8;
  --tok-class: #cdb4f2;
  --tok-operator: #adb8aa;
  color-scheme: dark;
}

/* the swatch button and its menu */
.header { z-index: 10; }
.theme-picker { position: relative; display: inline-flex; }
.swatch {
  display: block;
  width: 1.15em;
  height: 1.15em;
  padding: 0;
  border: 1px solid var(--muted);
  border-radius: 3px;
  cursor: pointer;
}
.theme-picker > .swatch:hover { border-color: var(--link); }
.theme-menu {
  position: absolute;
  top: calc(100% + 6px);
  right: 0;
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 6px;
  background: var(--bg);
  border: 1px solid var(--rule);
  border-radius: 4px;
  box-shadow: 0 4px 14px rgba(0, 0, 0, .12);
}
.theme-menu[hidden] { display: none; }
.theme-menu .swatch { width: 1.6em; height: 1.6em; }
.theme-menu .swatch:hover { transform: scale(1.08); }
.theme-menu .swatch[aria-checked="true"] { outline: 2px solid var(--link); outline-offset: 2px; }
