@font-face { font-family: "IBM Plex Mono"; font-weight: 400; font-display: swap; src: url("/fonts/ibmplexmono-regular.woff2") format("woff2"); }
@font-face { font-family: "IBM Plex Mono"; font-weight: 500; font-display: swap; src: url("/fonts/ibmplexmono-medium.woff2") format("woff2"); }

:root {
  --paper: #fdfdfc;
  --ink: #141412;
  --ink-2: #4b4b47;
  --line: #d4d4cf;
  --link: #0000ee;
  --ease-out: cubic-bezier(0.23, 1, 0.32, 1);
}
:root { color-scheme: light; }
:root[data-theme="dark"] { --paper: #111110; --ink: #f5f5f3; --ink-2: #b5b4ae; --line: #3b3a37; --link: #8ab4f8; color-scheme: dark; }

*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font: 400 1rem/1.6 "IBM Plex Mono", ui-monospace, Menlo, monospace;
  font-kerning: normal;
  letter-spacing: -0.03em;
  overflow-wrap: break-word;
  -webkit-font-smoothing: antialiased;
}
h1, h2, p, ul, ol { margin: 0; padding: 0; font: inherit; }
h1, h2, .site-name { font-weight: 500; }
ul, ol { list-style: none; }
a { color: inherit; text-decoration: none; }
a:focus-visible { outline: 2px solid var(--ink); outline-offset: 3px; border-radius: 2px; }
[tabindex="-1"]:focus { outline: none; }

.skip {
  position: absolute; left: 1.5rem; top: 0.75rem;
  background: var(--ink); color: var(--paper); padding: 0.375rem 0.75rem; border-radius: 4px;
  transform: translateY(-200%);
}
.skip:focus { transform: none; }

.page {
  max-width: calc(40rem + 3rem);
  margin: 0 auto;
  padding: clamp(3.5rem, 9vw, 6rem) 1.5rem clamp(4rem, 9vw, 6rem);
}

/* The switch sits over the right end of the name line, so the lines below get the full column width. */
.masthead { position: relative; }

/* Dark/light switch: icon button, the two icons swap with a short blur crossfade. */
.theme {
  position: absolute; top: -0.375rem; right: -0.5rem; width: 2.5rem; height: 2.5rem;
  display: grid; place-items: center; border: 0; border-radius: 8px; background: none; color: var(--line); cursor: pointer;
  transition: color 160ms ease, background-color 160ms ease, transform 160ms var(--ease-out);
}
.theme:active { transform: scale(0.94); }
.theme:focus-visible { outline: 2px solid var(--ink); outline-offset: 2px; }
@media (hover: hover) { .theme:hover { color: var(--ink); background: color-mix(in srgb, var(--ink) 5%, transparent); } }
/* Icon drawn like the box borders: 1px, --line color. */
.theme svg * { vector-effect: non-scaling-stroke; }
.theme svg { grid-area: 1 / 1; width: 1.25rem; height: 1.25rem; stroke-width: 1px; overflow: visible; transition: opacity 200ms var(--ease-out), transform 200ms var(--ease-out), filter 200ms var(--ease-out); }
:root[data-theme="light"] .theme .sun, :root[data-theme="dark"] .theme .moon { opacity: 0; transform: scale(0.6) rotate(-30deg); filter: blur(3px); }
body { transition: background-color 200ms ease, color 200ms ease; }
/* Hover: the sun's rays turn a quarter, the moon rocks back with a small overshoot. */
.theme svg { transition: opacity 200ms var(--ease-out), transform 200ms var(--ease-out), filter 200ms var(--ease-out), rotate 900ms var(--ease-out); }
.theme .moon { transition-property: opacity, transform, filter, rotate; transition-timing-function: var(--ease-out), var(--ease-out), var(--ease-out), cubic-bezier(0.34, 1.56, 0.64, 1); transition-duration: 200ms, 200ms, 200ms, 600ms; }
@media (hover: hover) {
  .theme:hover .sun { rotate: 90deg; }
  .theme:hover .moon { rotate: -22deg; }
}
@media (prefers-reduced-motion: reduce) { .theme svg, body { transition: none; } .theme:hover svg { rotate: none; } }
.muted { color: var(--ink-2); }
.masthead p { text-wrap: pretty; }
.masthead .bio { margin-top: 0.9em; }

main > * { min-width: 0; }
main { display: grid; gap: 0.75rem; margin-top: clamp(3rem, 8vw, 5rem); }

/* Each section is a collapsed box; the summary row opens it. */
details { border: 1px solid var(--line); border-radius: 10px; scroll-margin-top: 1.5rem; }
summary {
  display: flex; justify-content: space-between; align-items: center; gap: 1rem;
  padding: 0.875rem 1.25rem; cursor: pointer; list-style: none; border-radius: 9px;
}
summary::-webkit-details-marker { display: none; }
@media (hover: hover) { summary:hover { background: color-mix(in srgb, var(--ink) 3%, transparent); } }
details[open] summary { border-radius: 9px 9px 0 0; }
summary:focus-visible { outline: 2px solid var(--ink); outline-offset: 2px; }
summary svg { flex: none; width: 1.125rem; height: 1.125rem; color: var(--ink-2); }
details[open] summary svg { transform: rotate(180deg); }
.panel { padding: 0.25rem 1.25rem 1.375rem; }
/* Opening: the box grows on a drawer curve (300ms) while its lines fade up out of a slight
   blur, 40ms apart. Closing is faster (200ms): slow where the reader decides, fast where the
   page responds. Height animates where interpolate-size is supported; the line fade works everywhere. */
:root { --ease-drawer: cubic-bezier(0.32, 0.72, 0, 1); }
@supports (interpolate-size: allow-keywords) {
  :root { interpolate-size: allow-keywords; }
  details::details-content {
    block-size: 0; overflow: clip; opacity: 0;
    transition: block-size 200ms var(--ease-out), opacity 150ms ease, content-visibility 200ms allow-discrete;
  }
  details[open]::details-content {
    block-size: auto; opacity: 1;
    transition: block-size 300ms var(--ease-drawer), opacity 150ms ease, content-visibility 300ms allow-discrete;
  }
}
summary svg { transition: transform 250ms var(--ease-out); }
details[open] .prose > p, details[open] .panel li, details[open] .panel > p {
  animation: line-in 300ms var(--ease-out) both;
}
details[open] :is(.prose > p, .panel li):nth-child(2) { animation-delay: 40ms; }
details[open] :is(.prose > p, .panel li):nth-child(3) { animation-delay: 80ms; }
details[open] :is(.prose > p, .panel li):nth-child(4) { animation-delay: 120ms; }
details[open] :is(.prose > p, .panel li):nth-child(5) { animation-delay: 160ms; }
details[open] :is(.prose > p, .panel li):nth-child(n+6) { animation-delay: 200ms; }
@keyframes line-in { from { opacity: 0; transform: translateY(-4px); filter: blur(2px); } }
/* Press feedback on the box title row. */
summary { transition: background-color 160ms ease, scale 160ms var(--ease-out); }
summary:active { scale: 0.995; }
@media (prefers-reduced-motion: reduce) {
  details::details-content, details[open]::details-content, summary svg, summary { transition: none; }
  summary:active { scale: none; }
  details[open] .prose > p, details[open] .panel li, details[open] .panel > p { animation: line-fade 200ms ease both; animation-delay: 0ms; }
  @keyframes line-fade { from { opacity: 0; } }
}
.prose { display: grid; gap: 0.9em; color: var(--ink-2); }
.prose p { text-wrap: pretty; }

.inline { color: var(--link); text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 0.2em; }
.inline:hover { text-decoration-thickness: 2px; }

.projects { display: grid; gap: 1.5rem; }
.projects .name { font-weight: 500; color: var(--link); text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 0.2em; }
.projects .name:hover { text-decoration-thickness: 2px; }
.projects p { color: var(--ink-2); text-wrap: pretty; }

/* Project pages */
.home { color: inherit; }
.home:hover { text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 0.2em; }
.intro { display: grid; gap: 0.25rem; margin-bottom: 1.25rem; }
.timeline { display: grid; gap: 0.75rem; }
.timeline li { display: grid; grid-template-columns: 7.5rem 1fr; gap: 1rem; color: var(--ink-2); }
.timeline time { color: var(--ink); font-variant-numeric: tabular-nums; }
.facts { display: grid; gap: 0.75rem; color: var(--ink-2); list-style: disc; padding-left: 1.1rem; }
.back { margin-top: 1.25rem; }
@media (max-width: 30rem) { .timeline li { grid-template-columns: 1fr; gap: 0; } }

/* One entrance: each block fades up out of a slight blur, in reading order. */
@media (prefers-reduced-motion: no-preference) {
  .reveal { animation: reveal 700ms var(--ease-out) both; animation-delay: calc(var(--i) * 70ms); }
  @keyframes reveal { from { opacity: 0; transform: translateY(6px); filter: blur(4px); } }
}
.nw { white-space: nowrap; }
