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

:root {
    --bg: #f7f8fa;
    --surface: #ffffff;
    --text: #1b1f27;
    --text-soft: #454c59;
    --muted: #6b7280;
    --line: #e3e6ec;
    --accent: #0e9488;
    --accent-strong: #0b7e73;
    --max-width: 42rem;
}

@media (prefers-color-scheme: dark) {
    :root {
        --bg: #0e1116;
        --surface: #151a22;
        --text: #e8edf5;
        --text-soft: #c4ccda;
        --muted: #8b96a8;
        --line: #262e3a;
        --accent: #2dd4bf;
        --accent-strong: #5eead4;
    }
}

html { -webkit-text-size-adjust: 100%; }

body {
    background: var(--bg);
    color: var(--text);
    font: 1.0625rem/1.65 -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
    text-rendering: optimizeLegibility;
}

a { color: var(--accent-strong); text-decoration-thickness: 1px; text-underline-offset: 2px; }
a:hover, a:focus { color: var(--accent); }

/* Keyboard users get the same visible ring on every theme: themes recolour
   --accent, they never have to restate this rule. */
:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

.skip-link {
    position: absolute;
    left: -999px;
    top: 0;
    background: var(--accent);
    color: #04211d;
    padding: .6rem 1rem;
    border-radius: 0 0 .4rem 0;
    z-index: 10;
}
.skip-link:focus { left: 0; }

.site-header {
    max-width: var(--max-width);
    margin: 0 auto;
    padding: 2rem 1.25rem 1rem;
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    justify-content: space-between;
    gap: .75rem;
    border-bottom: 1px solid var(--line);
}
.site-brand a { color: var(--text); text-decoration: none; font-size: 1.375rem; font-weight: 700; }
.site-nav a { color: var(--muted); text-decoration: none; margin-left: 1rem; }
.site-nav a:first-child { margin-left: 0; }
.site-nav a:hover, .site-nav a:focus { color: var(--accent-strong); }

main {
    max-width: var(--max-width);
    margin: 0 auto;
    padding: 2rem 1.25rem 3rem;
}

.site-description { color: var(--text-soft); margin-bottom: 2rem; }

.post-list { list-style: none; }
.post-summary {
    padding: 1.5rem 0;
    border-bottom: 1px solid var(--line);
}
.post-summary:first-child { padding-top: 0; }
.post-summary h2 { font-size: 1.25rem; line-height: 1.4; margin-bottom: .35rem; }
.post-summary h2 a { text-decoration: none; color: var(--text); }
.post-summary h2 a:hover, .post-summary h2 a:focus { color: var(--accent-strong); }

.post-meta { color: var(--muted); font-size: .875rem; margin-bottom: .5rem; }
.post-meta a { color: var(--muted); }
.post-meta a:hover, .post-meta a:focus { color: var(--accent-strong); }

.post-excerpt { color: var(--text-soft); }
.empty { color: var(--muted); }

article h1 { font-size: 1.75rem; line-height: 1.3; margin-bottom: .5rem; }

.post-body { margin-top: 1.5rem; }
.post-body p { margin: 0 0 1.1rem; }
.post-body a { word-break: break-word; }
.post-body img { max-width: 100%; height: auto; border-radius: .4rem; }

/* The reset above zeroes every margin, so each block the post body can
   contain has to ask for its own spacing back. Post HTML comes from the
   fediverse and can hold anything, so this covers the whole set rather than
   the tags a given post happens to use. */
.post-body h2, .post-body h3, .post-body h4 { margin: 1.75rem 0 .6rem; line-height: 1.3; }
.post-body > :first-child { margin-top: 0; }
.post-body ul, .post-body ol { margin: 0 0 1.1rem; padding-left: 1.5rem; }
.post-body li { margin-bottom: .3rem; }
.post-body hr { margin: 1.75rem 0; border: 0; border-top: 1px solid var(--line); }
.post-body pre {
    overflow-x: auto;
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: .4rem;
    padding: .9rem;
    margin: 0 0 1.1rem;
}
.post-body blockquote {
    margin: 0 0 1.1rem;
    padding-left: 1rem;
    border-left: 3px solid var(--line);
    color: var(--text-soft);
}

.post-media {
    display: grid;
    /* auto-fit, not auto-fill: empty tracks collapse, so a post with one
       attachment gets one full-measure figure instead of a 14rem thumbnail
       stranded at the left edge. */
    grid-template-columns: repeat(auto-fit, minmax(min(14rem, 100%), 1fr));
    gap: 1rem;
    margin-top: 1.5rem;
}
.post-media-item { border-radius: .4rem; overflow: hidden; background: var(--surface); }
.post-media-item img,
.post-media-item video { display: block; width: 100%; height: auto; border-radius: .4rem; }
.post-media-item audio { width: 100%; }
.post-media-item figcaption {
    padding: .5rem .1rem 0;
    color: var(--muted);
    font-size: .8125rem;
}
.post-media-cw {
    margin-top: 1.5rem;
    border: 1px solid var(--line);
    border-radius: .4rem;
    padding: .75rem 1rem;
}
.post-media-cw summary { cursor: pointer; font-weight: 600; color: var(--text-soft); }
.post-media-cw .post-media { margin-top: 1rem; }

.fediverse-thread-link { margin-top: 1.5rem; font-size: .9375rem; }

.post-replies { margin-top: 2.5rem; border-top: 1px solid var(--line); padding-top: 1rem; }
.reply-list { padding-left: 1.5rem; }
.blog-reply { margin: 1rem 0; }
.blog-reply header { color: var(--muted); font-size: .9rem; }

.post-pager {
    display: flex;
    justify-content: space-between;
    gap: 1rem;
    margin-top: 2.5rem;
    padding-top: 1.5rem;
    border-top: 1px solid var(--line);
    font-size: .9375rem;
}
.post-pager a { text-decoration: none; }

.back-link { margin-top: 2rem; font-size: .9375rem; }

.site-footer {
    max-width: var(--max-width);
    margin: 0 auto;
    padding: 1.5rem 1.25rem 2.5rem;
    color: var(--muted);
    font-size: .8125rem;
}

.archive-year {
    font-size: 1.1rem;
    margin: 2rem 0 .5rem;
    padding-bottom: .35rem;
    border-bottom: 1px solid var(--line);
}
.archive-year:first-of-type { margin-top: 0; }
.archive-entry {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: .6rem;
    padding: .6rem 0;
    border-bottom: none;
}
.archive-entry time { color: var(--muted); font-size: .8125rem; flex: 0 0 auto; }
.archive-entry a { text-decoration: none; color: var(--text); }
.archive-entry a:hover, .archive-entry a:focus { color: var(--accent-strong); }

.tag-list { list-style: none; }
.tag-list li {
    display: flex;
    justify-content: space-between;
    padding: .6rem 0;
    border-bottom: 1px solid var(--line);
}
.tag-list a { text-decoration: none; color: var(--text); }
.tag-list a:hover, .tag-list a:focus { color: var(--accent-strong); }
.tag-count { color: var(--muted); font-size: .875rem; }

@media (max-width: 30rem) {
    .site-header { padding-top: 1.5rem; }
    article h1 { font-size: 1.5rem; }
}

@media (prefers-reduced-motion: reduce) {
    *, *::before, *::after {
        animation-duration: .01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: .01ms !important;
        scroll-behavior: auto !important;
    }
}

/* On paper the navigation leads nowhere, so it goes; link targets inside the
   post do not survive the trip either, so they are spelled out. */
@media print {
    body { background: #fff; color: #000; font-size: 11pt; }
    .skip-link, .site-nav, .post-pager, .back-link, .fediverse-thread-link { display: none; }
    a { color: #000; }
    .post-body a[href^="http"]::after { content: " (" attr(href) ")"; font-size: .85em; word-break: break-all; }
    .post-body pre, .post-media-item { break-inside: avoid; }
}


/* theme: ledger */
/* Ledger - technical notes and devlogs.
 *
 * The generator stamps every post with an ISO-style timestamp. Here that
 * timestamp is the alignment device: metadata, headings and navigation are
 * monospaced and sit on one column, prose is sans and sits on another, and
 * a long command line scrolls inside its block rather than wrapping, because
 * a wrapped command line is a bug report waiting to happen.
 *
 * System faces only - no web font is fetched, so an offline copy of the site
 * looks the same as the served one. */

:root {
    --bg: #f4f5f7;
    --surface: #ffffff;
    --text: #12161c;
    --text-soft: #39424e;
    --muted: #59636f;
    --line: #dde1e7;
    --accent: #1b4fd8;
    --accent-strong: #163fae;
    --max-width: 40rem;
    --font-mono: ui-monospace, SFMono-Regular, "SF Mono", "JetBrains Mono", Menlo, Consolas, monospace;
    --font-body: system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
}

@media (prefers-color-scheme: dark) {
    :root {
        --bg: #0f1319;
        --surface: #161b23;
        --text: #dce2ea;
        --text-soft: #b4becb;
        --muted: #8792a0;
        --line: #232b35;
        --accent: #88abff;
        --accent-strong: #a9c4ff;
    }
}

body {
    font-family: var(--font-body);
    font-size: 1rem;
    line-height: 1.6;
}

.site-brand a, .site-nav a, .post-meta, .post-summary h2, article h1,
.archive-year, .archive-entry, .tag-list, .post-pager, .back-link,
.site-footer, .blog-reply header, .post-media-item figcaption {
    font-family: var(--font-mono);
}

.site-header {
    padding-top: 1.5rem;
    border-bottom: 1px solid var(--text);
}
.site-brand a { font-size: 1.125rem; font-weight: 600; letter-spacing: -.02em; }
.site-brand a::before { content: "$ "; color: var(--muted); }
.site-nav { font-size: .8125rem; }
.site-nav a { text-transform: lowercase; }
.site-nav a::before { content: "/"; color: var(--line); margin-right: .15rem; }

.site-description { border-left: 2px solid var(--accent); padding-left: .9rem; }

.post-summary { padding: 1.25rem 0; }
.post-summary h2 { font-size: 1.0625rem; font-weight: 600; letter-spacing: -.01em; }
.post-meta { font-size: .8125rem; font-variant-numeric: tabular-nums; }
.post-meta time { color: var(--accent-strong); }
.post-meta a { text-decoration: none; }
.post-meta a:hover, .post-meta a:focus { text-decoration: underline; }

article h1 { font-size: 1.5rem; font-weight: 600; letter-spacing: -.02em; }

.post-body h2, .post-body h3 { font-family: var(--font-mono); letter-spacing: -.01em; margin: 1.75rem 0 .6rem; }
.post-body code { font-family: var(--font-mono); font-size: .9375em; background: var(--surface); border: 1px solid var(--line); padding: 0 .2rem; }
.post-body pre {
    border-radius: 0;
    border: 1px solid var(--line);
    border-left: 3px solid var(--accent);
    font-size: .875rem;
    line-height: 1.5;
}
.post-body pre code { background: none; border: none; padding: 0; }
.post-body blockquote { border-left: 3px solid var(--line); }
.post-media-item, .post-media-item img, .post-media-item video, .post-body img { border-radius: 0; }
.post-media-cw { border-radius: 0; }

/* The archive is the actual ledger: one fixed timestamp column, entries
   aligned against it. */
.archive-year {
    font-size: .875rem;
    letter-spacing: .1em;
    border-bottom: 1px solid var(--text);
}
.archive-entry { font-size: .9375rem; gap: 1rem; }
.archive-entry time { flex: 0 0 10.5rem; font-variant-numeric: tabular-nums; color: var(--accent-strong); }

.tag-list li { border-bottom: 1px dashed var(--line); font-size: .9375rem; }
.tag-count { font-variant-numeric: tabular-nums; }

.post-pager { font-size: .8125rem; border-top: 1px solid var(--text); }
.site-footer { font-size: .75rem; }
