* {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

:root {
  --bg: #121212;
  --fg: #ffffff;
  --squiggle: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 4' width='12' height='4'%3E%3Cpath d='M0 2 Q3 0 6 2 T12 2' fill='none' stroke='%23ffffff' stroke-width='1'/%3E%3C/svg%3E");
}

:root[data-theme="light"] {
  --bg: #faf8f4;
  --fg: #1a1a1a;
  --squiggle: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 4' width='12' height='4'%3E%3Cpath d='M0 2 Q3 0 6 2 T12 2' fill='none' stroke='%231a1a1a' stroke-width='1'/%3E%3C/svg%3E");
}

::selection {
  background-color: var(--fg);
  color: var(--bg);
}

body {
  background-color: var(--bg);
  color: var(--fg);
  transition:
    background-color 0.45s ease,
    color 0.45s ease;
  font-family: Optima, Candara, "Noto Sans", source-sans-pro, sans-serif;
  line-height: 1.6;
  font-size: 15px;
  padding: 80px 20px 32px;
  display: flex;
  justify-content: center;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

.container {
  width: 100%;
  max-width: 600px;
  position: relative;
}

header {
  text-align: center;
  margin-bottom: 40px;
}

h1 {
  font-size: 30px;
  font-weight: 700;
  margin-bottom: 0;
  letter-spacing: 0.5px;
}

/* Hovering the name sends one gentle wave through the letters */
h1 span {
  display: inline-block;
}

h1:hover span {
  animation: letter-wave 0.5s ease;
  animation-delay: calc(var(--i) * 35ms);
}

@keyframes letter-wave {
  50% {
    transform: translateY(-4px);
  }
}

h2 {
  font-size: 22px;
  font-weight: 700;
  margin-top: 48px;
  margin-bottom: 16px;
}

h3 {
  font-size: 16px;
  font-weight: 700;
  margin-top: 24px;
  margin-bottom: 6px;
}

p {
  margin-bottom: 16px;
  font-weight: normal;
}

.intro-prose {
  font-size: 15px;
  line-height: 1.6;
  margin-bottom: 40px;
}

.intro-prose+.intro-prose {
  margin-top: -24px;
}

/* Collapsible entries: native <details>, pure-CSS fluid height */
.fold {
  interpolate-size: allow-keywords;
}

.fold summary {
  list-style: none;
  cursor: pointer;
  font-size: 16px;
  font-weight: 700;
  margin-top: 24px;
  margin-bottom: 6px;
  user-select: none;
  width: fit-content;
  transition: transform 0.25s ease;
}

/* Fold titles nudge right on hover, same motion language as the PR titles */
.fold summary:hover {
  transform: translateX(5px);
}

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

/* Toggle indicator: a folded (wavy) line after the title that straightens
   out when opened. Hover makes the wave swim, same motif as link underlines. */
.fold summary::after {
  content: "";
  display: inline-block;
  width: 24px;
  height: 4px;
  margin-left: 12px;
  vertical-align: middle;
  opacity: 0.55;
  background-image: var(--squiggle);
  background-size: 12px 4px;
  background-repeat: repeat-x;
  transition: opacity 0.2s ease;
  animation: squiggle 0.8s linear infinite;
}

.fold summary:hover::after {
  opacity: 1;
  animation: squiggle 0.4s linear infinite;
}

.fold[open] summary::after {
  background-image: linear-gradient(currentColor, currentColor);
  background-size: 24px 1px;
  background-position: 0 50%;
  background-repeat: no-repeat;
  animation: none;
}

.fold::details-content {
  block-size: 0;
  overflow: hidden;
  opacity: 0;
  transition:
    block-size 0.45s cubic-bezier(0.65, 0, 0.35, 1),
    opacity 0.3s ease 0.1s,
    content-visibility 0.45s allow-discrete;
}

.fold[open]::details-content {
  block-size: auto;
  opacity: 1;
}

.subtitle {
  font-style: italic;
  font-size: 13px;
  margin-top: -2px;
  margin-bottom: 12px;
  display: block;
}

ul {
  list-style-type: square;
  margin-left: 20px;
  margin-bottom: 16px;
}

li {
  margin-bottom: 8px;
}

/* Straight underline at rest; on hover it comes alive as a scrolling squiggle */
a {
  color: var(--fg);
  font: inherit;
  text-decoration: none;
  padding-bottom: 1px;
  background-image: linear-gradient(currentColor, currentColor);
  background-size: 100% 1px;
  background-position: 0 100%;
  background-repeat: no-repeat;
  transition: color 0.45s ease;
}

a:hover,
a:focus-visible {
  background-image: var(--squiggle);
  background-size: 12px 4px;
  background-repeat: repeat-x;
  animation: squiggle 0.4s linear infinite;
}

a:focus-visible,
.fold summary:focus-visible,
.theme-toggle:focus-visible {
  outline: 2px dashed var(--fg);
  outline-offset: 4px;
}

.fold summary:focus-visible::after {
  opacity: 1;
}

.fold:not([open]) summary:focus-visible::after {
  animation: squiggle 0.4s linear infinite;
}

.theme-toggle:focus-visible {
  opacity: 1;
}

@keyframes squiggle {
  to {
    background-position: 12px 100%;
  }
}

.links-row {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 8px 24px;
}

/* Focus-blur: hovering one link sharpens it and softens the rest, with thin
   brackets framing the focused one. */
.links-row a {
  position: relative;
  padding-bottom: 0;
  transition:
    filter 0.3s ease,
    opacity 0.3s ease;
}

.links-row:hover a:not(:hover) {
  filter: blur(2.5px);
  opacity: 0.4;
}

/* Focused link keeps a plain straight underline instead of the squiggle */
.links-row a:hover {
  animation: none;
  background-image: linear-gradient(currentColor, currentColor);
  background-size: 100% 1px;
  background-repeat: no-repeat;
  background-position: 0 100%;
}

.links-row a::before,
.links-row a::after {
  position: absolute;
  top: 50%;
  opacity: 0;
  transform: translateY(-50%) scale(1.4);
  transition:
    opacity 0.25s ease,
    transform 0.25s cubic-bezier(0.34, 1.56, 0.64, 1);
  pointer-events: none;
}

.links-row a::before {
  content: "[";
  left: -11px;
}

.links-row a::after {
  content: "]";
  right: -11px;
}

.links-row a:hover::before,
.links-row a:hover::after {
  opacity: 0.5;
  transform: translateY(-50%) scale(1);
}


/* Footer sign-off: a pen dot rides left-to-right, drawing the squiggle behind
   it, then lifts off. The site signs its own name. */
.footer {
  margin-top: 40px;
}

.footer-wave {
  height: 4px;
  margin-bottom: 20px;
  opacity: 0.5;
  background-image: var(--squiggle);
  background-size: 12px 4px;
  background-repeat: repeat-x;
  animation: squiggle 0.8s linear infinite;
}

/* Theme toggle: a live squiggle, top-right like a signature on a canvas.
   Dark = wavy line, light = wavy circle; app.js morphs the path between them. */
.theme-toggle {
  position: fixed;
  top: 20px;
  right: 24px;
  width: 32px;
  height: 32px;
  padding: 0;
  border: none;
  cursor: pointer;
  background: none;
  color: var(--fg);
  opacity: 0.6;
  transition:
    opacity 0.2s ease,
    color 0.45s ease,
    transform 0.3s cubic-bezier(0.34, 1.56, 0.64, 1);
}

.theme-toggle:hover {
  opacity: 1;
}

.theme-toggle:active {
  transform: scale(0.85);
}


/* Theme flip: View Transitions API circular reveal */
::view-transition-old(root),
::view-transition-new(root) {
  animation: none;
  mix-blend-mode: normal;
}

::view-transition-old(root) {
  z-index: 1;
}

::view-transition-new(root) {
  z-index: 9999;
}

html[data-theme-vt="active"]::view-transition-group(root) {
  animation-duration: var(--theme-vt-duration, 400ms);
}

:root.theme-snap *,
:root.theme-snap *::before,
:root.theme-snap *::after {
  transition: none !important;
}

.footer p {
  margin-bottom: 0;
}

.colophon {
  font-style: italic;
  font-size: 13px;
  opacity: 0.75;
  margin-top: 6px;
}

/* Open Source: PRs grouped under their repo. Monochrome octicons mark state
   (merge arrow = merged, branch = open); hovering one floats the tooltip. */
.repo-group {
  margin-bottom: 24px;
}

.pr-repo {
  font-family: monospace;
  font-size: 13px;
  font-weight: 700;
  margin-bottom: 10px;
}

.pr {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 12px;
  padding-left: 12px;
}

.pr-icon,
.pr-icon.note-ref {
  flex-shrink: 0;
  display: inline-flex;
  opacity: 0.65;
  transition: opacity 0.2s ease;
  border-bottom: none;
}

.pr-icon:hover {
  opacity: 1;
}

/* PR titles: quiet at rest, no full-width squiggle — hover nudges the title
   and wakes the state icon instead */
.pr a {
  background-image: none;
  padding-bottom: 0;
  transition: transform 0.25s ease;
}

.pr a:hover {
  background-image: none;
  animation: none;
  transform: translateX(5px);
}

.pr:has(a:hover) .pr-icon {
  opacity: 1;
}

/* Clean dot separator in subtitle lines */
.sep {
  display: inline-block;
  margin: 0 8px;
  opacity: 0.45;
  user-select: none;
}

.sep::before {
  content: "·";
  font-weight: 700;
}

/* Footnotes: tooltip on hover, no underline. The prose reads clean; the notes
   are there for the curious. */
.note-ref {
  cursor: default;
}

/* A footnote that is also a real link keeps the standard link affordance
   (underline + squiggle hover) so it still reads as clickable. */
a.note-ref {
  cursor: pointer;
}

.mono {
  font-family: monospace;
  font-size: 0.85em;
}

/* Floating Physics Tooltip styling */
.footnote-tooltip {
  position: fixed;
  pointer-events: none;
  background-color: var(--fg);
  color: var(--bg);
  padding: 10px 14px;
  font-size: 13px;
  line-height: 1.4;
  max-width: 280px;
  border-radius: 4px;
  /* Subtle rounded styling matching rounded-md variant */
  box-shadow: 0 10px 30px rgba(0, 0, 0, 0.4);
  z-index: 1000;
  display: none;
  /* Controlled dynamically in update loop */
  transform-origin: top left;
}

/* Easter egg: typing "nerd" makes every squiggle on the page swim */
body.nerding a,
body.nerding .note-ref {
  background-image: var(--squiggle);
  background-size: 12px 4px;
  background-position: 0 100%;
  background-repeat: repeat-x;
  animation: squiggle 0.4s linear infinite;
}

body.nerding .fold summary::after {
  animation: squiggle 0.4s linear infinite;
}

@media (prefers-reduced-motion: reduce) {

  *,
  *::before,
  *::after {
    animation: none !important;
    transition: none !important;
  }
}

@media (max-width: 600px) {
  body {
    padding: 40px 20px;
  }

  .theme-toggle {
    position: absolute;
    top: 16px;
    right: 16px;
  }

  .footnote-tooltip {
    display: none !important;
  }
}

@media (hover: none) {
  .footnote-tooltip {
    display: none !important;
  }
}

/* Print: the site doubles as a resume. Black on white, folds open, URLs shown. */
@media print {
  :root {
    --bg: #ffffff;
    --fg: #000000;
  }

  body {
    padding: 0;
  }

  .theme-toggle,
  #greet,
  .colophon,
  .sep,
  .fold summary::after,
  .footer-wave {
    display: none !important;
  }

  .fold::details-content {
    content-visibility: visible !important;
    block-size: auto !important;
    opacity: 1 !important;
  }

  a {
    background-image: none !important;
    animation: none !important;
  }

  a[href^="http"]::after {
    content: " (" attr(href) ")";
    font-size: 11px;
    word-break: break-all;
  }

  .footer {
    border-top: 1px solid #000;
    padding-top: 12px;
  }
}