@charset "UTF-8";
/**
 * Reset some basic elements
 */
body, h1, h2, h3, h4, h5, h6,
p, blockquote, pre, hr,
dl, dd, ol, ul, figure {
  margin: 0;
  padding: 0;
}

/**
 * Basic styling
 */
body {
  font: 400 16px/1.5 -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
  color: #111;
  background-color: #fdfdfd;
  -webkit-text-size-adjust: 100%;
  -webkit-font-feature-settings: "kern" 1;
  -moz-font-feature-settings: "kern" 1;
  -o-font-feature-settings: "kern" 1;
  font-feature-settings: "kern" 1;
  font-kerning: normal;
  display: flex;
  min-height: 100vh;
  flex-direction: column;
}

/**
 * Set `margin-bottom` to maintain vertical rhythm
 */
h1, h2, h3, h4, h5, h6,
p, blockquote, pre,
ul, ol, dl, figure,
.highlight {
  margin-bottom: 15px;
}

/**
 * `main` element
 */
main {
  display: block; /* Default value of `display` of `main` element is 'inline' in IE 11. */
}

/**
 * Images
 */
img {
  max-width: 100%;
  vertical-align: middle;
}

/**
 * Figures
 */
figure > img {
  display: block;
}

figcaption {
  font-size: 14px;
}

/**
 * Lists
 */
ul, ol {
  margin-left: 30px;
}

li > ul,
li > ol {
  margin-bottom: 0;
}

/**
 * Headings
 */
h1, h2, h3, h4, h5, h6 {
  font-weight: 400;
}

/**
 * Links
 */
a {
  color: #2a7ae2;
  text-decoration: none;
}
a:visited {
  color: rgb(8.9993518068%, 33.8251498947%, 66.0986874088%);
}
a:hover {
  color: #111;
  text-decoration: underline;
}
.social-media-list a:hover {
  text-decoration: none;
}
.social-media-list a:hover .username {
  text-decoration: underline;
}

/**
 * Blockquotes
 */
blockquote {
  color: #828282;
  border-left: 4px solid #e8e8e8;
  padding-left: 15px;
  font-size: 18px;
  letter-spacing: -1px;
  font-style: italic;
}
blockquote > :last-child {
  margin-bottom: 0;
}

/**
 * Code formatting
 */
pre,
code {
  font-size: 15px;
  border: 1px solid #e8e8e8;
  border-radius: 3px;
  background-color: #eef;
}

code {
  padding: 1px 5px;
}

pre {
  padding: 8px 12px;
  overflow-x: auto;
}
pre > code {
  border: 0;
  padding-right: 0;
  padding-left: 0;
}

/**
 * Wrapper
 */
.wrapper {
  max-width: -webkit-calc(800px - (30px * 2));
  max-width: calc(800px - 30px * 2);
  margin-right: auto;
  margin-left: auto;
  padding-right: 30px;
  padding-left: 30px;
}
@media screen and (max-width: 800px) {
  .wrapper {
    max-width: -webkit-calc(800px - (30px));
    max-width: calc(800px - (30px));
    padding-right: 15px;
    padding-left: 15px;
  }
}

/**
 * Clearfix
 */
.footer-col-wrapper:after, .wrapper:after {
  content: "";
  display: table;
  clear: both;
}

/**
 * Icons
 */
.svg-icon {
  width: 16px;
  height: 16px;
  display: inline-block;
  fill: #828282;
  padding-right: 5px;
  vertical-align: text-top;
}

.social-media-list li + li {
  padding-top: 5px;
}

/**
 * Tables
 */
table {
  margin-bottom: 30px;
  width: 100%;
  text-align: left;
  color: rgb(24.6666666667%, 24.6666666667%, 24.6666666667%);
  border-collapse: collapse;
  border: 1px solid #e8e8e8;
}
table tr:nth-child(even) {
  background-color: rgb(96.9803921569%, 96.9803921569%, 96.9803921569%);
}
table th, table td {
  padding: 9.999999999px 15px;
}
table th {
  background-color: rgb(93.9803921569%, 93.9803921569%, 93.9803921569%);
  border: 1px solid rgb(86.9803921569%, 86.9803921569%, 86.9803921569%);
  border-bottom-color: rgb(78.9803921569%, 78.9803921569%, 78.9803921569%);
}
table td {
  border: 1px solid #e8e8e8;
}

/**
 * Site header
 */
.site-header {
  border-top: 5px solid rgb(25.9803921569%, 25.9803921569%, 25.9803921569%);
  border-bottom: 1px solid #e8e8e8;
  min-height: 55.95px;
  position: relative;
}

.site-title {
  font-size: 26px;
  font-weight: 300;
  line-height: 54px;
  letter-spacing: -1px;
  margin-bottom: 0;
  float: left;
}
.site-title, .site-title:visited {
  color: rgb(25.9803921569%, 25.9803921569%, 25.9803921569%);
}

.site-nav {
  float: right;
  line-height: 54px;
}
.site-nav .nav-trigger {
  display: none;
}
.site-nav .menu-icon {
  display: none;
}
.site-nav .page-link {
  color: #111;
  line-height: 1.5;
}
.site-nav .page-link:not(:last-child) {
  margin-right: 20px;
}
@media screen and (max-width: 600px) {
  .site-nav {
    position: absolute;
    top: 9px;
    right: 15px;
    background-color: #fdfdfd;
    border: 1px solid #e8e8e8;
    border-radius: 5px;
    text-align: right;
  }
  .site-nav label[for=nav-trigger] {
    display: block;
    float: right;
    width: 36px;
    height: 36px;
    z-index: 2;
    cursor: pointer;
  }
  .site-nav .menu-icon {
    display: block;
    float: right;
    width: 36px;
    height: 26px;
    line-height: 0;
    padding-top: 10px;
    text-align: center;
  }
  .site-nav .menu-icon > svg {
    fill: rgb(25.9803921569%, 25.9803921569%, 25.9803921569%);
  }
  .site-nav input ~ .trigger {
    clear: both;
    display: none;
  }
  .site-nav input:checked ~ .trigger {
    display: block;
    padding-bottom: 5px;
  }
  .site-nav .page-link {
    display: block;
    margin-left: 20px;
    padding: 5px 10px;
  }
  .site-nav .page-link:not(:last-child) {
    margin-right: 0;
  }
}

/**
 * Site footer
 */
.site-footer {
  border-top: 1px solid #e8e8e8;
  padding: 30px 0;
}

.footer-heading {
  font-size: 18px;
  margin-bottom: 15px;
}

.contact-list,
.social-media-list {
  list-style: none;
  margin-left: 0;
}

.footer-col-wrapper {
  font-size: 15px;
  color: #828282;
  margin-left: -15px;
}

.footer-col {
  float: left;
  margin-bottom: 15px;
  padding-left: 15px;
}

.footer-col-1 {
  width: -webkit-calc(35% - (30px / 2));
  width: calc(35% - 30px / 2);
}

.footer-col-2 {
  width: -webkit-calc(20% - (30px / 2));
  width: calc(20% - 30px / 2);
}

.footer-col-3 {
  width: -webkit-calc(45% - (30px / 2));
  width: calc(45% - 30px / 2);
}

@media screen and (max-width: 800px) {
  .footer-col-1,
  .footer-col-2 {
    width: -webkit-calc(50% - (30px / 2));
    width: calc(50% - 30px / 2);
  }
  .footer-col-3 {
    width: -webkit-calc(100% - (30px / 2));
    width: calc(100% - 30px / 2);
  }
}
@media screen and (max-width: 600px) {
  .footer-col {
    float: none;
    width: -webkit-calc(100% - (30px / 2));
    width: calc(100% - 30px / 2);
  }
}
/**
 * Page content
 */
.page-content {
  padding: 30px 0;
  flex: 1;
}

.page-heading {
  font-size: 32px;
}

.post-list-heading {
  font-size: 28px;
}

.post-list {
  margin-left: 0;
  list-style: none;
}
.post-list > li {
  margin-bottom: 30px;
}

.post-meta {
  font-size: 14px;
  color: #828282;
}

.post-link {
  display: block;
  font-size: 24px;
}

/**
 * Posts
 */
.post-header {
  margin-bottom: 30px;
}

.post-title {
  font-size: 42px;
  letter-spacing: -1px;
  line-height: 1;
}
@media screen and (max-width: 800px) {
  .post-title {
    font-size: 36px;
  }
}

.post-content {
  margin-bottom: 30px;
}
.post-content h2 {
  font-size: 32px;
}
@media screen and (max-width: 800px) {
  .post-content h2 {
    font-size: 28px;
  }
}
.post-content h3 {
  font-size: 26px;
}
@media screen and (max-width: 800px) {
  .post-content h3 {
    font-size: 22px;
  }
}
.post-content h4 {
  font-size: 20px;
}
@media screen and (max-width: 800px) {
  .post-content h4 {
    font-size: 18px;
  }
}

/**
 * Syntax highlighting styles
 */
.highlight {
  background: #fff;
}
.highlighter-rouge .highlight {
  background: #eef;
}
.highlight .c {
  color: #998;
  font-style: italic;
}
.highlight .err {
  color: #a61717;
  background-color: #e3d2d2;
}
.highlight .k {
  font-weight: bold;
}
.highlight .o {
  font-weight: bold;
}
.highlight .cm {
  color: #998;
  font-style: italic;
}
.highlight .cp {
  color: #999;
  font-weight: bold;
}
.highlight .c1 {
  color: #998;
  font-style: italic;
}
.highlight .cs {
  color: #999;
  font-weight: bold;
  font-style: italic;
}
.highlight .gd {
  color: #000;
  background-color: #fdd;
}
.highlight .gd .x {
  color: #000;
  background-color: #faa;
}
.highlight .ge {
  font-style: italic;
}
.highlight .gr {
  color: #a00;
}
.highlight .gh {
  color: #999;
}
.highlight .gi {
  color: #000;
  background-color: #dfd;
}
.highlight .gi .x {
  color: #000;
  background-color: #afa;
}
.highlight .go {
  color: #888;
}
.highlight .gp {
  color: #555;
}
.highlight .gs {
  font-weight: bold;
}
.highlight .gu {
  color: #aaa;
}
.highlight .gt {
  color: #a00;
}
.highlight .kc {
  font-weight: bold;
}
.highlight .kd {
  font-weight: bold;
}
.highlight .kp {
  font-weight: bold;
}
.highlight .kr {
  font-weight: bold;
}
.highlight .kt {
  color: #458;
  font-weight: bold;
}
.highlight .m {
  color: #099;
}
.highlight .s {
  color: #d14;
}
.highlight .na {
  color: #008080;
}
.highlight .nb {
  color: #0086B3;
}
.highlight .nc {
  color: #458;
  font-weight: bold;
}
.highlight .no {
  color: #008080;
}
.highlight .ni {
  color: #800080;
}
.highlight .ne {
  color: #900;
  font-weight: bold;
}
.highlight .nf {
  color: #900;
  font-weight: bold;
}
.highlight .nn {
  color: #555;
}
.highlight .nt {
  color: #000080;
}
.highlight .nv {
  color: #008080;
}
.highlight .ow {
  font-weight: bold;
}
.highlight .w {
  color: #bbb;
}
.highlight .mf {
  color: #099;
}
.highlight .mh {
  color: #099;
}
.highlight .mi {
  color: #099;
}
.highlight .mo {
  color: #099;
}
.highlight .sb {
  color: #d14;
}
.highlight .sc {
  color: #d14;
}
.highlight .sd {
  color: #d14;
}
.highlight .s2 {
  color: #d14;
}
.highlight .se {
  color: #d14;
}
.highlight .sh {
  color: #d14;
}
.highlight .si {
  color: #d14;
}
.highlight .sx {
  color: #d14;
}
.highlight .sr {
  color: #009926;
}
.highlight .s1 {
  color: #d14;
}
.highlight .ss {
  color: #990073;
}
.highlight .bp {
  color: #999;
}
.highlight .vc {
  color: #008080;
}
.highlight .vg {
  color: #008080;
}
.highlight .vi {
  color: #008080;
}
.highlight .il {
  color: #099;
}

/* ---- Fonts ----
   Self-hosted Lora (SIL OFL), latin subset, so there's no third-party request
   and no tracking. This is the typeface Chip Huyen uses on huyenchip.com,
   where every element is set in Lora at 400 (size carries the hierarchy); code
   falls back to the browser's default monospace, as it does on her site. The
   normal file is the variable weight-axis (one file covers 400-700); italic is
   loaded separately. `swap` paints in the fallback immediately and swaps in
   Lora once it loads. */
@font-face {
  font-family: "Lora";
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url("/assets/fonts/lora-latin-wght-normal.woff2") format("woff2");
}
@font-face {
  font-family: "Lora";
  font-style: italic;
  font-weight: 400;
  font-display: swap;
  src: url("/assets/fonts/lora-latin-italic-400.woff2") format("woff2");
}
body {
  font-family: "Lora", Georgia, "Times New Roman", serif;
}

h1, h2, h3, h4, h5, h6,
.site-title, .post-title {
  font-family: "Lora", Georgia, "Times New Roman", serif;
  font-weight: 400;
}

/* ---- Theme ----
   Light values live on bare :root so the page is correct with no JS at all.
   The media query follows the system setting; [data-theme] overrides both when
   the visitor has made an explicit choice. */
:root {
  color-scheme: light;
  --bg: #fdfdfd;
  --text: #111;
  --muted: #828282;
  --border: #e8e8e8;
  /* HRT brand orange. --accent is the true colour for decorative use (the
     header rule); --link is a darkened variant so link text clears WCAG AA
     4.5:1 on the light background, which #ff8200 does not. */
  --accent: #ff8200;
  --border-strong: #ff8200;
  --link: #ff8200;
  --link-visited: #cc6800;
  --code-bg: #fff3e8;
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme=light]) {
    color-scheme: dark;
    --bg: #16181d;
    --text: #e8e8e8;
    --muted: #9a9a9a;
    --border: #2c2f36;
    /* True brand orange is readable on the dark bg (~6.8:1), so use it as-is. */
    --accent: #ff8200;
    --border-strong: #ff8200;
    --link: #ff8200;
    --link-visited: #d99a5c;
    --code-bg: #22252c;
  }
}
:root[data-theme=dark] {
  color-scheme: dark;
  --bg: #16181d;
  --text: #e8e8e8;
  --muted: #9a9a9a;
  --border: #2c2f36;
  --accent: #ff8200;
  --border-strong: #ff8200;
  --link: #ff8200;
  --link-visited: #d99a5c;
  --code-bg: #22252c;
}

/* Repoint Minima's hardcoded colours at the tokens above. */
body {
  background-color: var(--bg);
  color: var(--text);
}

a, a:visited {
  color: var(--link);
}

a:hover {
  color: var(--text);
}

.site-header {
  border-top-color: var(--border-strong);
  border-bottom-color: var(--border);
}

.site-title, .site-title:visited {
  color: var(--text);
}

.site-nav .page-link {
  color: var(--text);
}

.site-footer {
  border-top-color: var(--border);
}

/* ---- Footer ----
   Minima's default footer floats three fixed-width columns (35/20/45%). With
   only a short link list that leaves a lopsided empty right half, so we lay it
   out ourselves: a single row of links, wrapping to a stack on narrow screens. */
.site-footer__links {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 8px 24px;
}

.site-footer__links a {
  display: inline-flex;
  align-items: center;
  white-space: nowrap;
  color: var(--muted);
}

.site-footer__links a:hover {
  color: var(--link);
}

.site-footer__links .svg-icon {
  fill: currentColor;
}

.footer-col-wrapper, .post-meta, .update-meta, .update-list-heading {
  color: var(--muted);
}

pre, code {
  background-color: var(--code-bg);
  border-color: var(--border);
}

blockquote {
  color: var(--muted);
  border-left-color: var(--border);
}

table {
  color: var(--text);
  border-color: var(--border);
}

table th {
  background-color: var(--code-bg);
  border-color: var(--border);
  font-weight: normal;
}

table td {
  border-color: var(--border);
}

table tr:nth-child(even) {
  background-color: rgba(128, 128, 128, 0.06);
}

/* ---- Theme toggle button ----
   36px hit area for desktop precision pointers; bumped to the 44px floor
   (iOS HIG / Material / WCAG 2.5.5) for coarse touch pointers. */
.theme-toggle {
  order: 2;
  background: none;
  border: 0;
  padding: 0;
  margin-left: 8px;
  cursor: pointer;
  color: var(--muted);
  line-height: 1;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 36px;
  min-height: 36px;
  border-radius: 8px;
}

.theme-toggle:hover {
  color: var(--text);
}

.theme-toggle:focus-visible {
  outline: 2px solid var(--link);
  outline-offset: 2px;
}

/* Sun in light mode, moon in dark. */
.theme-toggle-icon::before {
  content: "☀";
  font-size: 1.25rem;
}

:root[data-theme=dark] .theme-toggle-icon::before {
  content: "☽";
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme=light]) .theme-toggle-icon::before {
    content: "☽";
  }
}
/* ---- Mobile nav: hamburger, scrim, slide-in drawer ----
   Minima's tiny absolute-positioned corner box (toggle + hamburger crammed
   into 76px) is replaced with flexible in-flow controls sized to touch, and
   the accordion dropdown becomes a full-height drawer. The {checkbox hack}
   drives open/close with no JS; nav.js only adds scroll-lock, Escape-to-close
   and focus management on top. Minima's own mobile rules pierce through as
   .site-nav label[for=nav-trigger] (0,2,1), so our controls are selected with
   the element in the compound (label.nav-burger) to tie and win on order. */
#nav-trigger:focus-visible ~ .nav-burger {
  outline: 2px solid var(--link);
  outline-offset: 2px;
}

.site-nav label.nav-burger {
  order: 3;
  display: none;
  align-items: center;
  justify-content: center;
  min-width: 36px;
  min-height: 36px;
  cursor: pointer;
  border-radius: 8px;
}

.site-nav label.nav-burger:hover {
  color: var(--text);
}

.site-nav label.nav-burger svg {
  fill: var(--text);
}

.site-nav label.nav-scrim {
  order: 4;
  display: none;
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  width: auto;
  height: auto;
  z-index: 10;
  background: rgba(12, 14, 18, 0.45);
  cursor: pointer;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.22s ease;
}

/* Touch-pointer floor of 44px sits after the 36px base so it wins by source
   order. */
@media (pointer: coarse) {
  .theme-toggle,
  .site-nav label.nav-burger {
    min-width: 44px;
    min-height: 44px;
  }
}
/* ---- Header ----
   Minima lays the header out with floats and a hardcoded line-height: 54px,
   so when text is zoomed (or the title wraps on a narrow screen) the enlarged
   title overflows that fixed line and collides with the floated nav. Replace
   the float layout with a flex row that wraps cleanly and a unitless
   line-height that scales with the font size. */
/* Minima's default content measure (800px minus padding) is tuned for prose.
   A lot of the notes here are wide tables, which previously had to scroll
   inside their own box. Widen the wrapper a bit so two-column tables get room
   to breathe on desktop without stretching prose lines too far. */
.wrapper {
  max-width: 900px;
}

.site-header {
  /* Let the header grow with its content instead of clipping at a fixed line. */
  min-height: 0;
}

.site-header > .wrapper {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  column-gap: 20px;
  row-gap: 0.25rem;
  padding-block: 0.6rem;
}

/* Minima scales this responsively; pin it to 24px (1.5rem so it still scales
   with the user's font size). float:none + unitless line-height lets it wrap
   under zoom without overlapping the nav. */
.site-title {
  font-size: 1.5rem;
  float: none;
  line-height: 1.2;
}

/* Undo minima's float + fixed 54px line-height; push nav to the right of the
   flex row on wide screens. Flex keeps the toggle and links vertically
   centred; order puts links first, theme toggle after them. */
.site-nav {
  float: none;
  margin-left: auto;
  line-height: 1.2;
  display: flex;
  align-items: center;
}

/* ---- Mobile breakpoint: hamburger + slide-in drawer ----
   ≤37.5em (600px) is minima's palm breakpoint, where the accordion menu
   kicks in. Replace its absolute 76px corner box with in-flow controls and
   turn the trigger into a right-hand drawer over a scrim. */
@media screen and (max-width: 37.5em) {
  .site-title {
    /* One row on narrow screens: "Sean W (…)" at 24px plus the two 44px
       controls needs ~362px; shrink slightly so it still fits at 320-375px. */
    font-size: 1.25rem;
  }
  /* Narrow phones (≤384px): tighten so the title and the two controls keep
     sharing one row instead of wrapping the nav below. */
}
@media screen and (max-width: 37.5em) and (max-width: 24em) {
  .site-header > .wrapper {
    column-gap: 12px;
  }
  .site-title {
    font-size: 1.125rem;
  }
}
@media screen and (max-width: 37.5em) {
  /* Undo minima's absolutely-positioned bordered box; the nav is a plain
     flex row again, right-aligned by margin-left:auto. */
  .site-nav {
    position: static;
    background: transparent;
    border: 0;
    border-radius: 0;
    text-align: right;
  }
  .site-nav label.nav-burger {
    display: flex;
    margin-left: 2px;
  }
  .site-nav .menu-icon {
    float: none;
    width: auto;
    height: auto;
    line-height: 0;
    padding-top: 0;
    text-align: center;
    display: flex;
    align-items: center;
  }
  /* Keep the trigger checkbox focusable (1px, invisible) so Tab reaches the
     Menu control and :focus-visible can light up the hamburger. */
  .site-nav input.nav-trigger {
    position: fixed;
    top: 0;
    left: 0;
    width: 1px;
    height: 1px;
    margin: 0;
    opacity: 0;
    display: block;
  }
  .site-nav label.nav-scrim {
    display: block;
  }
  /* .nav-trigger ~ .trigger out-scopes minima's `input ~ .trigger` and its
     checked sibling, so our display/padding win even while checked. */
  .site-nav .nav-trigger ~ .trigger {
    position: fixed;
    top: 0;
    right: 0;
    bottom: 0;
    width: min(20rem, 84vw);
    margin: 0;
    padding: 0.75rem 0 1rem;
    background: var(--bg);
    border: 0;
    border-left: 1px solid var(--border);
    box-shadow: -10px 0 28px rgba(0, 0, 0, 0.14);
    display: flex;
    flex-direction: column;
    justify-content: flex-start;
    text-align: left;
    z-index: 20;
    overflow-y: auto;
    transform: translateX(102%);
    transition: transform 0.25s ease-in-out;
  }
  .site-nav .nav-trigger:checked ~ .trigger {
    transform: translateX(0);
  }
  .site-nav .nav-trigger:checked ~ label.nav-scrim {
    opacity: 1;
    pointer-events: auto;
  }
  /* Full-width, 48px-ish rows: comfortable tap targets with the active page
     marked. */
  .site-nav .trigger .page-link {
    display: block;
    margin: 0;
    padding: 0.85rem 1.5rem;
    line-height: 1.4;
    color: var(--text);
  }
  .site-nav .trigger .page-link + .page-link {
    border-top: 1px solid var(--border);
  }
  .site-nav .trigger .page-link:hover {
    background: var(--code-bg);
    color: var(--text);
  }
  .site-nav .trigger .page-link[aria-current=page] {
    color: var(--link);
    border-left: 3px solid var(--accent);
    padding-left: calc(1.5rem - 3px);
  }
}
@media screen and (max-width: 37.5em) and (prefers-reduced-motion: reduce) {
  .site-nav .trigger, .site-nav label.nav-scrim {
    transition: none;
  }
}
/* The active page is also marked on desktop, where the links sit inline. */
.page-link[aria-current=page] {
  color: var(--link);
}

/* Locked by nav.js while the drawer is open. */
html.nav-open {
  overflow: hidden;
}

/* Minima 2.x sizes .post-title from its own scale; pin it to 30px (1.875rem).
   line-height 1.1 (not 1) leaves room for descenders and multi-line titles,
   which happen at high zoom on a narrow screen. */
.post-title {
  font-size: 1.875rem;
  line-height: 1.1;
}

@media screen and (max-width: 50em) {
  .post-title {
    font-size: 1.75rem;
  }
}
/* Minima sizes in-content headings from its own scale (h2 = 2rem = 32px),
   which ends up larger than the 30px .post-title. Cap them so no section
   heading outsizes the page title. */
.post-content h2 {
  font-size: 1.5rem;
}
.post-content h3 {
  font-size: 1.25rem;
}
.post-content h4 {
  font-size: 1.0625rem;
}
.post-content {
  /* A wide table (or long unbroken string) must never stretch the page wider
     than the viewport — on a phone that forces horizontal scroll on the whole
     document and drags the header sideways. Keep the table at its natural
     width but let it scroll inside its own box, and break long words/URLs. */
}
.post-content table {
  display: block;
  width: max-content;
  max-width: 100%;
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
}
.post-content {
  overflow-wrap: break-word;
}

/* Long reference notes (front matter `class: long-note`): dozens of ###
   entries under a handful of ## sections. Give each level clear separation
   so the hierarchy reads at a glance, and style the collapsed variants. */
.post-content.long-note h2 {
  margin-top: 3.5rem;
  padding-top: 1rem;
  border-top: 1px solid var(--border);
}
.post-content.long-note h3 {
  margin-top: 2.5rem;
}
.post-content.long-note h4 {
  margin-top: 1.75rem;
}
.post-content.long-note h5 {
  font-size: 1rem;
  margin-top: 1.25rem;
}
.post-content.long-note h6 {
  font-size: 0.95rem;
  margin-top: 1rem;
}

.post-content details {
  margin: 0.5rem 0;
  padding: 0.35rem 0.9rem;
  border-left: 3px solid var(--border);
}

.post-content summary {
  cursor: pointer;
  font-weight: 600;
}

.post-content details[open] > summary {
  margin-bottom: 0.75rem;
}

.post-content details[open] {
  border-left-color: var(--accent);
}

.post-meta {
  font-size: 0.85rem;
}

/* Poems (front matter `class: poem`, set by default for the poetry
   collection): each stanza is one Markdown paragraph, and pre-line turns the
   single newlines inside it into visible line breaks without trailing-space
   hacks in the source. */
.post-content.poem p {
  white-space: pre-line;
}

/* ---- Dated "Updates" list on the home page ---- */
.update-list {
  margin-left: 0;
  list-style: none;
}
.update-list > li {
  font-size: 0.975rem;
  margin-bottom: 6px;
}

.update-list-heading {
  font-style: italic;
  color: #828282;
  margin-bottom: 10px;
}

/* Fixed width keeps the dates in a column beside their text. */
.update-meta {
  font-size: 0.85rem;
  color: #828282;
  display: inline-block;
  width: 5.625rem;
}

/* ---- Float grid for side-by-side images ---- */
.column {
  float: left;
  width: 50%;
  margin-bottom: 15px;
}

.column-left {
  float: left;
  width: 49%;
  padding-right: 1%;
  margin-bottom: 15px;
}

.column-right {
  float: left;
  width: 49%;
  padding-left: 1%;
  margin-bottom: 15px;
}

.column-mid {
  float: left;
  width: 75%;
  padding-left: 12.5%;
  margin-bottom: 15px;
}

.row:after {
  content: "";
  display: table;
  clear: both;
}

@media screen and (max-width: 37.5em) {
  .column, .column-mid, .column-left, .column-right {
    width: 100%;
    padding: 0;
  }
}
.imageholder {
  display: inline-block;
}

/* ---- Reading progress bar ----
   Scroll-driven, so it runs off the main thread with no scroll listener.
   Chrome/Edge 115+ and Safari 18+ support it; elsewhere the bar stays hidden,
   which is a fine no-op. Suppressed under reduced-motion. */
.reading-progress {
  position: fixed;
  top: 0;
  left: 0;
  height: 3px;
  width: 100%;
  transform: scaleX(0);
  transform-origin: 0 50%;
  background: var(--accent);
  z-index: 100;
  display: none;
}

@supports (animation-timeline: scroll()) {
  @media (prefers-reduced-motion: no-preference) {
    .reading-progress {
      display: block;
      animation: reading-progress-grow linear;
      animation-timeline: scroll(root block);
    }
  }
}
@keyframes reading-progress-grow {
  from {
    transform: scaleX(0);
  }
  to {
    transform: scaleX(1);
  }
}

/*# sourceMappingURL=main.css.map */