/* One editorial system for every page: large sans headlines, serif reading text, one accent. */
@font-face{font-family:'IBM Plex Sans';font-style:normal;font-weight:100 700;font-display:swap;src:url(/assets/fonts/ibm-plex-sans-latin-wght-normal.woff2) format('woff2');unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}
@font-face{font-family:'IBM Plex Sans';font-style:normal;font-weight:100 700;font-display:swap;src:url(/assets/fonts/ibm-plex-sans-latin-ext-wght-normal.woff2) format('woff2');unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}
@font-face{font-family:'Source Serif 4';font-style:normal;font-weight:200 900;font-display:swap;src:url(/assets/fonts/source-serif-4-latin-wght-normal.woff2) format('woff2');unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}
@font-face{font-family:'Source Serif 4';font-style:normal;font-weight:200 900;font-display:swap;src:url(/assets/fonts/source-serif-4-latin-ext-wght-normal.woff2) format('woff2');unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}
@font-face{font-family:'Source Serif 4';font-style:italic;font-weight:200 900;font-display:swap;src:url(/assets/fonts/source-serif-4-latin-wght-italic.woff2) format('woff2');unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}
@font-face{font-family:'Source Serif 4';font-style:italic;font-weight:200 900;font-display:swap;src:url(/assets/fonts/source-serif-4-latin-ext-wght-italic.woff2) format('woff2');unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}

:root{color-scheme:light;--paper:#fcfcfa;--ink:#222;--muted:#555;--line:#d9d9d9;--accent:#385344;--tint:#e9eee9;
  --sans:'IBM Plex Sans',-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif;
  --serif:'Source Serif 4',Georgia,'Times New Roman',serif;
  --measure:45rem;--wide:70rem;--gutter:clamp(1rem,4vw,3.125rem)}
*{box-sizing:border-box}
html{scroll-padding-top:1.5rem;-webkit-text-size-adjust:100%;text-size-adjust:100%}
body{margin:0;background:var(--paper);color:var(--ink);font-family:var(--serif);font-size:1.25rem;line-height:1.6;overflow-x:clip;-webkit-font-smoothing:antialiased}
img{display:block;max-width:100%;height:auto}
a{color:inherit;text-decoration-thickness:.07em;text-underline-offset:.18em}
a:hover{color:var(--accent);text-decoration-thickness:.12em}
:focus-visible{outline:3px solid var(--accent);outline-offset:3px;border-radius:1px}
::selection{background:#cfe0d3;color:#14261a}
.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap;border:0}
.skip{position:absolute;left:1rem;top:-5rem;z-index:10;padding:.75rem 1rem;background:var(--ink);color:#fff;font-family:var(--sans);font-weight:600}
.skip:focus{top:1rem;color:#fff}
h1,h2,h3,h4,p,ul,ol,figure{margin-top:0}
h1,h2,h3,h4{font-family:var(--sans);line-height:1.15;color:var(--ink)}
h1{font-weight:700;font-size:clamp(2.75rem,1.4rem + 5.6vw,5.75rem);line-height:1.02;letter-spacing:-.03em;margin-bottom:1.5rem}
h2{font-weight:700;font-size:clamp(1.75rem,1.3rem + 1.6vw,2.5rem);letter-spacing:-.02em;margin-bottom:1rem}
h3{font-weight:600;font-size:1.375rem;letter-spacing:-.01em;margin-bottom:.6rem}
p{margin-bottom:1.25rem}
.shell{max-width:90rem;margin-inline:auto;padding-inline:var(--gutter)}
.measure{max-width:var(--measure)}

/* Header: serif wordmark, large underlined links, the academic record on the right. */
.site-header{padding-block:1.75rem .5rem;display:grid;gap:.4rem}
.wordmark{justify-self:start;font-family:var(--serif);font-size:1.75rem;font-weight:600;letter-spacing:-.01em;line-height:1.3;text-decoration:none}
.site-nav{display:flex;flex-wrap:wrap;align-items:baseline;gap:.25rem 1.1em;font-family:var(--sans);font-weight:500;font-size:clamp(1.125rem,.95rem + .75vw,1.625rem);line-height:1.3}
.site-nav a{display:inline-block;padding-block:.2rem;text-decoration-thickness:.06em}
.site-nav a[aria-current=page]{color:var(--accent);text-decoration-thickness:.16em}
.site-nav .nav-record{margin-left:auto}

/* Hero: a large page word in a pale tint sits behind the title. Research uses a photo instead. */
.hero{position:relative;isolation:isolate;padding-block:clamp(3rem,9vw,7.5rem) clamp(2rem,5vw,4rem)}
.hero::before{content:attr(data-ghost) / "";position:absolute;z-index:-1;left:-.06em;top:clamp(1rem,4vw,3rem);font-family:var(--sans);font-weight:700;font-size:clamp(6rem,2rem + 17vw,16rem);line-height:.82;letter-spacing:-.04em;white-space:nowrap;color:var(--tint);pointer-events:none;user-select:none}
.eyebrow,.label{font-family:var(--sans);font-size:.8125rem;font-weight:600;letter-spacing:.09em;text-transform:uppercase;color:var(--accent);line-height:1.4}
.eyebrow{margin-bottom:1.25rem}
.label{display:block;margin-bottom:1rem}
.hero h1{max-width:16ch}
.dek{max-width:var(--measure);font-family:var(--sans);font-weight:500;font-size:clamp(1.375rem,1.1rem + 1.1vw,2rem);line-height:1.4;letter-spacing:-.01em;margin-bottom:0}
/* Research: a faded photo behind the header and hero. At this opacity, ink and accent text stay above 4.5:1. */
.research::before{content:"";position:absolute;z-index:-1;inset:0 0 auto;height:clamp(34rem,80vh,52rem);background:url(/assets/research/ibm-1410-1600.webp) 70% 40%/cover no-repeat;opacity:.17;filter:grayscale(1);-webkit-mask-image:linear-gradient(#000 45%,transparent);mask-image:linear-gradient(#000 45%,transparent);pointer-events:none}
.image-credit{max-width:var(--measure);margin-top:clamp(3rem,6vw,4.5rem);padding-top:1rem;border-top:1px solid var(--line);font-family:var(--sans);font-size:.875rem;line-height:1.5;color:var(--muted)}

/* Spine: on wide screens, the page word runs down the right edge and stays in view. */
.spine{display:none}
@media(min-width:75em){
  .page{display:grid;grid-template-columns:minmax(0,1fr) auto;column-gap:3rem}
  .spine{display:block}
  .spine span{position:sticky;top:1rem;display:block;writing-mode:vertical-rl;font-family:var(--sans);font-weight:700;font-size:clamp(6rem,14vh,11rem);line-height:.8;letter-spacing:-.03em;white-space:nowrap;max-height:calc(100vh - 2rem);overflow-x:visible;overflow-y:clip;user-select:none}
}

/* Shared parts. */
.image-link{display:block;width:100%}
.image-link img{transition:border-color .15s}
.image-link:hover img{border-color:var(--accent)}
.section{margin-top:clamp(3.5rem,8vw,6rem)}
.text-link{font-family:var(--sans);font-size:1rem;font-weight:600}
.arrow{display:inline-block;margin-left:.3em;font-family:var(--sans);font-weight:400;text-decoration:none}
.credit{font-family:var(--sans);font-size:.9375rem;color:var(--muted)}
.endnote{max-width:var(--measure);margin-top:clamp(3rem,6vw,4.5rem);font-size:1.25rem;color:var(--muted)}

/* Footer: a dark band. */
.site-footer{margin-top:clamp(4rem,10vw,7.5rem);background:var(--ink);color:#fff;font-family:var(--sans);font-size:1rem}
.site-footer .shell{display:flex;flex-wrap:wrap;justify-content:space-between;align-items:baseline;gap:1rem 2rem;padding-block:2.5rem 3rem}
.site-footer a{color:#fff}
.site-footer a:hover{color:#fff;text-decoration-thickness:.14em}
.site-footer :focus-visible{outline-color:#fff}
.footer-name{margin:0;font-family:var(--serif);font-size:1.5rem;font-weight:600}
.footer-name a{text-decoration:none}
.footer-links{display:flex;flex-wrap:wrap;gap:.5rem 1.5rem;list-style:none;margin:0;padding:0}
.footer-links a{display:inline-block;padding-block:.2rem}

/* Home: name, portrait and bio, then a numbered table of contents. */
.home .hero h1{font-size:clamp(3.5rem,1rem + 11vw,9.5rem);line-height:.92;letter-spacing:-.045em;max-width:none;margin-bottom:1.25rem}
.about{display:grid;grid-template-columns:minmax(0,15rem) minmax(0,1fr);gap:clamp(1.5rem,4vw,3rem);align-items:start;max-width:56rem}
.portrait{width:100%;aspect-ratio:1;object-fit:cover;border-radius:50%;background:var(--tint)}
.bio{font-size:clamp(1.25rem,1.1rem + .5vw,1.5rem);line-height:1.55;margin:0}
.toc{max-width:var(--wide)}
.toc ol{list-style:none;margin:0;padding:0;border-top:2px solid var(--ink)}
.toc li{border-bottom:1px solid var(--line)}
.toc a{display:grid;grid-template-columns:3.5rem minmax(0,1fr);column-gap:1rem;align-items:baseline;padding-block:1.5rem;text-decoration:none}
.toc .index{grid-row:span 2;font-family:var(--sans);font-size:1rem;font-weight:500;color:var(--muted)}
.toc h2{margin:0;font-size:clamp(2.25rem,1.4rem + 3vw,4rem);line-height:1.05;text-decoration:underline;text-decoration-thickness:.05em;text-underline-offset:.12em}
.toc p{margin:.5rem 0 0;font-size:1.125rem;color:var(--muted)}
.toc a:hover h2{color:var(--accent);text-decoration-thickness:.09em}
.record-invite{margin-top:2rem;font-family:var(--sans);font-size:1rem;color:var(--muted)}
.record-invite a{color:var(--ink);font-weight:600;margin-right:.75rem}

/* Teach: course cards with a screenshot of each website. */
.course-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:clamp(2.5rem,5vw,3.5rem) clamp(1.5rem,4vw,3rem);max-width:var(--wide)}
.course{display:flex;flex-direction:column;align-items:flex-start}
.shot{width:100%;aspect-ratio:16/10;object-fit:cover;object-position:top left;border:1px solid var(--line);background:var(--tint)}
.course .shot{margin-bottom:1.5rem}
.course h2{font-size:clamp(1.625rem,1.3rem + 1vw,2.125rem);margin-bottom:.75rem}
.course p{max-width:32rem;margin-bottom:.75rem}
.course .credit{margin-top:-.25rem}
.course .text-link{margin-top:auto;padding-top:.5rem}

/* Research: a statement, the book, and selected works. */
.statement{max-width:var(--measure)}
.book{display:grid;grid-template-columns:11rem minmax(0,1fr);gap:clamp(1.5rem,4vw,2.5rem);max-width:var(--wide);padding-block:2.5rem;border-block:2px solid var(--ink)}
.book-aside{font-family:var(--sans);font-size:.9375rem;color:var(--muted);line-height:1.5}
.book-aside .cover{width:100%;border:1px solid var(--line);margin-bottom:1.25rem;box-shadow:0 1px 2px rgb(0 0 0/.08),0 8px 24px -8px rgb(0 0 0/.25)}
.book-aside .year{display:block;font-weight:700;font-size:3.5rem;line-height:1;letter-spacing:-.03em;color:var(--accent);margin-bottom:.5rem}
.book h2{max-width:var(--measure);font-size:clamp(1.75rem,1.3rem + 1.5vw,2.5rem);margin-bottom:.5rem}
.book .subtitle{font-style:italic;font-size:1.25rem;max-width:var(--measure)}
.book p{max-width:var(--measure)}
.reception{display:grid;gap:.5rem;margin:2rem 0 0;padding-top:1.25rem;border-top:1px solid var(--line);font-family:var(--sans);font-size:1rem;line-height:1.5}
.reception div{display:grid;grid-template-columns:6rem minmax(0,1fr);gap:1rem}
.reception dt{font-size:.8125rem;font-weight:600;letter-spacing:.09em;text-transform:uppercase;color:var(--accent);padding-top:.15rem}
.reception dd{margin:0}
.work-list{max-width:var(--wide)}
.work{display:grid;grid-template-columns:7rem minmax(0,1fr);gap:clamp(1.25rem,3vw,2rem);align-items:start;padding-block:1.75rem;border-top:1px solid var(--line)}
.work .first-page{width:100%;aspect-ratio:2/3;object-fit:cover;object-position:top;border:1px solid var(--line);background:#fff;box-shadow:0 1px 2px rgb(0 0 0/.06),0 6px 16px -8px rgb(0 0 0/.2)}
.work .year{display:block;font-family:var(--sans);font-size:1rem;font-weight:500;color:var(--muted);margin-bottom:.35rem}
.work h3{font-size:clamp(1.375rem,1.2rem + .6vw,1.75rem);line-height:1.25;margin-bottom:.5rem}
.work p{max-width:var(--measure);margin:0;color:var(--muted)}
.work .credit{margin-top:.5rem}

/* Build: three featured projects with screenshots, then a grid of tools separated by rules. */
.features{max-width:var(--wide)}
.feature{display:grid;grid-template-columns:minmax(0,1.35fr) minmax(0,1fr);gap:clamp(1.5rem,4vw,3rem);align-items:center;padding-block:2.5rem;border-top:2px solid var(--ink)}
.feature h3{font-size:clamp(1.75rem,1.3rem + 1.5vw,2.5rem);margin-bottom:.75rem}
.feature p{max-width:32rem;margin-bottom:1rem}
.software-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));column-gap:clamp(1.5rem,4vw,3rem);max-width:var(--wide)}
.software{display:flex;flex-direction:column;align-items:flex-start;padding-block:1.75rem 2.25rem;border-top:2px solid var(--ink)}
.software h3{font-size:clamp(1.5rem,1.25rem + .8vw,1.875rem);margin-bottom:.75rem}
.software p{max-width:32rem;margin-bottom:.75rem}
.software .credit{margin-top:-.25rem}
.software .text-link{margin-top:auto;padding-top:.5rem}

/* Academic: the content is the interface. */
.downloads{display:flex;gap:.75rem;flex-wrap:wrap;margin-top:2rem}
.download{display:inline-block;padding:.7rem 1.25rem;border:2px solid var(--ink);font-family:var(--sans);font-size:1rem;font-weight:600;text-decoration:none}
.download:hover{background:var(--accent);border-color:var(--accent);color:#fff}
.academic-layout{display:grid;grid-template-columns:12rem minmax(0,1fr);gap:clamp(2rem,4vw,3.5rem);align-items:start}
.record-nav{position:sticky;top:1.5rem;max-height:calc(100vh - 3rem);overflow-y:auto;font-family:var(--sans);font-size:.9375rem;line-height:1.4}
.record-nav a{display:block;padding-block:.3rem;text-decoration:none}
.record-nav a:hover{text-decoration:underline}
.record-nav .nav-group{font-weight:600;color:var(--accent);margin-top:1.25rem}
.record-nav .nav-group:first-child{margin-top:0}
.record{font-size:1.0625rem;min-width:0;max-width:var(--measure);overflow-wrap:anywhere}
.record h2{font-size:clamp(1.75rem,1.4rem + 1vw,2.25rem);margin:0 0 1.5rem;padding-top:1.75rem;border-top:2px solid var(--ink)}
.record h2:not(:first-child){margin-top:4rem}
.record h3{font-size:1.375rem;line-height:1.3;margin:2.25rem 0 1.25rem;padding-top:1rem;border-top:1px solid var(--line)}
.record h4{font-size:1.0625rem;font-weight:600;line-height:1.5;margin:1.5rem 0 .5rem}
.record ul{padding-left:1.2rem}
.record dl{display:grid;grid-template-columns:9.5rem minmax(0,1fr);gap:.9rem 1.5rem;margin:0 0 1.75rem}
.record dt{font-family:var(--sans);font-size:.9375rem;line-height:1.5;color:var(--muted);padding-top:.15rem}
.record dd{margin:0}
.record li{padding-left:.2rem;margin-bottom:.65rem}
.record .csl-entry{margin-bottom:1.4rem}
.record .csl-entry p{margin-bottom:.4rem}
.record .hanging-indent .csl-entry{padding-left:1.4rem;text-indent:-1.4rem}
.record .hanging-indent .csl-entry p+p{text-indent:0;font-family:var(--sans);font-size:.875rem;color:var(--muted)}

/* Legal and error pages: plain reading text. */
.prose{max-width:var(--measure)}
.prose h2{margin-top:3rem;padding-top:1.5rem;border-top:2px solid var(--ink)}
.prose h3{margin-top:2rem}
.prose address{font-style:normal;margin-bottom:1.25rem}

@media(max-width:47.5em){
  body{font-size:1.125rem}
  .site-header{padding-top:1.25rem}
  .wordmark{font-size:1.5rem}
  .site-nav{gap:.25rem 1em}
  .site-nav .nav-record{margin-left:0;flex-basis:100%}
  .about{grid-template-columns:minmax(0,9rem) minmax(0,1fr)}
  .toc a{grid-template-columns:2.25rem minmax(0,1fr);column-gap:.5rem;padding-block:1.25rem}
  .toc p{font-size:1rem}
  .course-grid,.software-grid,.feature{grid-template-columns:1fr}
  .research::before{background-image:url(/assets/research/ibm-1410-960.webp)}
  .book{grid-template-columns:1fr;gap:1rem;padding-block:2rem}
  .book-aside .cover{max-width:9rem}
  .reception div{grid-template-columns:1fr;gap:0}
  .book-aside .year{display:inline;font-size:2.25rem;margin-right:.75rem}
  .work{grid-template-columns:5rem minmax(0,1fr);gap:1rem}
  .academic-layout{grid-template-columns:1fr;gap:2rem}
  .record-nav{position:static;max-height:none;overflow:visible;columns:2;column-gap:1.5rem;border-block:1px solid var(--line);padding-block:1rem}
  .record-nav .nav-group{margin-top:0}
  .record{font-size:1rem}
  .record dl{grid-template-columns:1fr;gap:0}
  .record dt{padding-top:0}
  .record dd{margin-bottom:1rem}
}
@media(max-width:30em){
  .about{grid-template-columns:1fr}
  .portrait{max-width:12rem}
}
@media print{
  body{background:#fff;color:#000;font-size:11pt}
  .shell{max-width:none;padding:0}
  .site-header,.site-footer,.skip,.spine,.hero::before,.research::before,.record-nav,.downloads{display:none}
  .hero{padding:0 0 1rem}
  .academic-layout,.page{display:block}
  h1{font-size:28pt}
  h2,h3,h4{break-after:avoid}
  .record{font-size:10pt;max-width:none}
  .csl-entry,.course,.software,.book,.work{break-inside:avoid}
}
