/* nocduro — barren but powerful.
   System: Space Grotesk (titles/body), system monospace (meta/code),
   paper #f5f4f0, ink #141414, laser red #e8320f, signal amber #f5a300.

   Layout: one 600px text column (.wrap) with a 150px gutter on each side when
   the viewport has room (≥ 1040px): 150 + 600 + 150 = 900, so every media
   figure spans exactly the 900px image variant (config.toml widths). Red
   markers (years, section numbers) hang in the left gutter; the right gutter
   is empty. Site footer (.full-width) spans left gutter + column. Below 1040px
   there are no gutters and markers stack above their content. */

/* Space Grotesk (OFL, see fonts/OFL.txt), variable weight 300–700, self-hosted */
@font-face {
  font-family: "Space Grotesk";
  font-style: normal;
  font-weight: 300 700;
  font-display: swap;
  src: url(/fonts/space-grotesk-latin.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: "Space Grotesk";
  font-style: normal;
  font-weight: 300 700;
  font-display: swap;
  src: url(/fonts/space-grotesk-latin-ext.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 {
  --paper: #f5f4f0;
  --ink: #141414;
  --red: #e8320f;
  --amber: #f5a300;
  --chip: #e9e7e1;
  --mono: ui-monospace, Menlo, Consolas, monospace;
  --sans: "Space Grotesk", system-ui, sans-serif;
  --col: 118px;   /* red marker column */
  --gap: 32px;    /* col + gap = 150px gutter */
  --lead: calc(var(--col) + var(--gap));   /* gutter width */
  --measure: 640px;
}

* { box-sizing: border-box; }

/* reserve scrollbar space so short pages don't shift the layout */
html { background: var(--paper); scrollbar-gutter: stable; }
body {
  margin: 0;
  font: 400 16px/1.65 var(--sans);
  color: var(--ink);
  background: var(--paper);
}

a { color: var(--ink); text-decoration: none; }
a:hover { color: var(--red); }

/* content-box so the padding doesn't eat into the 600px */
.wrap { max-width: 600px; box-sizing: content-box; margin: 0 auto; padding: 0 24px; }
@media (min-width: 900px) { .wrap { padding: 0 64px; } }

/* ---------- the gutter ----------
   Needs 600 + 2×64 padding + a gutter on each side to stay centred:
   600 + 128 + 2×150 = 1028 → 1040. Below that, markers go above. */
.marked { display: grid; grid-template-columns: 1fr; gap: 8px; }
.marked > .marker, .marked > .year {
  font-weight: 700; font-size: 15px; color: var(--red);
  line-height: 1.25; padding-top: 3px; font-variant-numeric: tabular-nums;
}
/* section numbers link to their heading */
.marked > .marker a { color: inherit; text-decoration: none; }
.marked > .marker a:hover { text-decoration: underline; text-decoration-thickness: 2px; text-underline-offset: 3px; }
@media (min-width: 1040px) {
  .marked {
    grid-template-columns: var(--col) 1fr; gap: var(--gap);
    margin-left: calc(-1 * var(--lead));
  }
  .full-width { margin-left: calc(-1 * var(--lead)); }
}

/* ---------- header ---------- */
.site-header {
  display: flex; justify-content: space-between; align-items: baseline;
  padding-top: 52px;
}
.site-title { font-weight: 700; font-size: 20px; }
/* the dot: an ember — amber core, laser-red rim (nocte adūrō, "I burn by night") */
.site-title .dot {
  display: inline-block; width: 9px; height: 9px; border-radius: 50%;
  margin-left: 1px; vertical-align: 0;
  background: radial-gradient(circle at 40% 40%, var(--amber) 0, var(--amber) 25%, var(--red) 75%);
}
.site-nav { display: flex; gap: 28px; font-size: 14px; font-weight: 500; }

/* ---------- home: intro + year-grouped list ---------- */
.intro {
  padding: 84px 0 24px;
  font: 400 13px/1.7 var(--mono);
  max-width: 460px;
}
.intro .red { color: var(--red); }

.year-group { padding: 26px 0; }
.year-group > .entries { display: flex; flex-direction: column; gap: 26px; }
.entry-title {
  font-weight: 600; font-size: 22px; line-height: 1.2; letter-spacing: -.01em;
  display: block;
}
.entry-meta { margin-top: 6px; font: 400 12px var(--mono); }
.entry-meta .tag, .post-meta .tag { color: var(--red); }
/* drafts (only built with --drafts) */
.draft-badge {
  display: inline-block; background: var(--red); color: #fff;
  font: 700 11px/1 var(--mono); letter-spacing: .1em;
  padding: 4px 7px 3px; vertical-align: 2px; margin-right: 6px;
}

/* ---------- post page ---------- */
.post-head { padding-top: 76px; }
.post-meta { font: 400 12px var(--mono); margin-bottom: 14px; }
.post-title {
  margin: 0; font-weight: 700; font-size: 44px; line-height: 1.08;
  letter-spacing: -.02em; max-width: 620px; text-wrap: balance;
}
.post-lede { margin-top: 18px; font-size: 16px; max-width: 560px; }
@media (max-width: 640px) { .post-title { font-size: 32px; } }

/* section = red marker + content; the generator splits content at every h2 */
.section { padding-top: 44px; }
.section-body { min-width: 0; }
.section h2 {
  margin: 0 0 14px; font-weight: 600; font-size: 26px; line-height: 1.2; letter-spacing: -.01em;
}
.section h3 { margin: 28px 0 10px; font-weight: 600; font-size: 19px; }
.section h4 { margin: 22px 0 8px; font-weight: 600; font-size: 16px; }
.section p { margin: 0 0 16px; max-width: var(--measure); }
.section ul, .section ol { margin: 0 0 16px; padding-left: 20px; max-width: var(--measure); }
/* long unbroken tokens (URL link text, inline code) may break mid-word
   rather than widen the page on phones */
.section p, .section li, .section h2, .section h3, .section h4,
.figure figcaption, .post-lede { overflow-wrap: break-word; }
.section li { line-height: 1.8; }
.section blockquote {
  margin: 0 0 16px; padding-left: 18px; border-left: 2px solid var(--red);
  max-width: var(--measure);
}
/* an image inline in prose never overflows the column */
.section img { max-width: 100%; height: auto; }
.section hr { border: 0; border-top: 2px solid var(--ink); margin: 32px 0; width: var(--col); }

/* body links: red underline, red on hover */
.section a, .post-lede a {
  text-decoration: underline;
  text-decoration-color: var(--red);
  text-decoration-thickness: 2px;
  text-underline-offset: 2px;
}
.section a:hover { color: var(--red); }

/* ---------- tables ---------- */
.section table {
  border-collapse: collapse; margin: 0 0 18px; font-size: 14px;
  display: block; overflow-x: auto; max-width: 100%;
}
.section th, .section td { text-align: left; padding: 6px 14px 6px 0; vertical-align: top; }
.section th { font: 700 12px var(--mono); letter-spacing: .06em; text-transform: uppercase; border-bottom: 2px solid var(--ink); }
.section td { border-bottom: 1px solid var(--chip); }

/* ---------- figures ---------- */
/* figures fill the content column; `full` (and the hero) span gutter + column */
.figure { margin: 36px 0 32px; }
.figure img, .figure video { width: 100%; height: auto; display: block; }
.figure a { display: block; }
.figure a.lb { cursor: zoom-in; }
.figure.left, .figure.right { margin: 0 0 16px; max-width: 50%; }
.figure.left { float: left; margin-right: var(--gap); }
.figure.right { float: right; margin-left: var(--gap); }
/* captions: a step smaller than body, muted, left edge on the text column */
.figure figcaption {
  padding: 12px 0 0;
  font: 400 14px/1.55 var(--mono);
  color: #4a4944;
}
.figure figcaption p { margin: 0; }
.hero .figure { margin-top: 36px; }
/* phones: photos edge to edge */
@media (max-width: 640px) {
  .figure { margin-left: -24px; margin-right: -24px; }
  .figure figcaption { padding-left: 24px; padding-right: 24px; }
}
/* wide screens: every figure spans left gutter + column + right gutter;
   captions stay aligned with the column text */
@media (min-width: 1040px) {
  .figure { margin-left: calc(-1 * var(--lead)); margin-right: calc(-1 * var(--lead)); }
  .figure.left, .figure.right { margin-left: 0; margin-right: 0; }
  .figure.left { margin-right: var(--gap); }
  .figure.right { margin-left: var(--gap); }
  .figure figcaption { padding-left: var(--lead); padding-right: var(--lead); }
}

.gallery-grid { display: grid; gap: 4px; }
.gallery-grid img { height: 100%; object-fit: cover; }
.gallery.cols-2 .gallery-grid { grid-template-columns: 1fr 1fr; }
.gallery.cols-3 .gallery-grid { grid-template-columns: repeat(3, 1fr); }
@media (max-width: 640px) { .gallery.cols-3 .gallery-grid { grid-template-columns: 1fr 1fr; } }

.embed-frame { position: relative; aspect-ratio: 16 / 9; background: var(--ink); }
.embed-frame iframe { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; }

/* ---------- code ---------- */
code {
  font: 400 14px var(--mono);
  background: var(--chip);
  padding: 2px 6px;
}
pre {
  margin: 0 0 18px;
  background: var(--chip);
  color: var(--ink);
  padding: 20px 0;
  font: 400 13px/1.7 var(--mono);
  overflow: auto;
}
pre code { background: none; padding: 0; font-size: inherit; display: block; }
pre .line { display: block; padding: 0 24px; }
pre .line.hl { background: #ddd9cf; box-shadow: inset 3px 0 var(--red); }

/* filename tab, from ```lang title=src/parser.rs */
figure.code { margin: 0 0 18px; }
.code-tab {
  display: inline-block;
  background: var(--ink); color: var(--paper);
  font: 400 12px var(--mono);
  padding: 7px 14px;
}
.code-tab + pre { border-top: 2px solid var(--ink); }

/* wide screens: code blocks and tables start on the column edge like prose
   but extend into the (empty) right gutter for long lines */
@media (min-width: 1040px) {
  pre, .section table { margin-right: calc(-1 * var(--lead)); }
  .section table { max-width: calc(100% + var(--lead)); }
}
/* phones: edge to edge like figures */
@media (max-width: 640px) {
  pre { margin-left: -24px; margin-right: -24px; }
}

/* ---------- GitHub alerts: > [!NOTE] etc. ---------- */
.alert {
  border: 2px solid var(--red);
  padding: 14px 20px 0;
  font-size: 15px; line-height: 1.6;
  max-width: var(--measure);
  margin: 0 0 18px;
}
.alert-title {
  font: 700 12px var(--mono); color: var(--red); letter-spacing: .08em;
  text-transform: uppercase; margin: 0 0 6px;
}
.alert-tip, .alert-important { border-color: var(--amber); }
.alert-archived { margin-top: 28px; border-color: var(--ink); }
.alert-archived .alert-title { color: var(--ink); }
.alert-archived a { text-decoration: underline; text-decoration-color: var(--red); text-decoration-thickness: 2px; text-underline-offset: 2px; }
.archive-link { font: 400 13px var(--mono); }
.alert-tip .alert-title, .alert-important .alert-title { color: var(--amber); }

/* ---------- asides: <details> in post markdown ----------
   Closed: a mono summary line with a red triangle. On wide screens the
   triangle hangs in the left gutter like a section marker. Open: an amber
   left border marks the extent (red would read as a blockquote). */
.section details { margin: 0 0 16px; max-width: var(--measure); }
.section summary {
  cursor: pointer; list-style: none; position: relative;
  font: 400 13px/1.7 var(--mono);
}
.section summary::-webkit-details-marker { display: none; }
.section summary::before {
  content: "\25B8"; /* ▸ */
  color: var(--red); font-weight: 700; margin-right: 10px;
}
.section details[open] > summary::before { content: "\25BE"; } /* ▾ */
.section summary:hover { color: var(--red); }
.section details[open] {
  border-left: 2px solid var(--amber);
  padding-left: 18px; margin-left: -20px; /* border+padding = 20px: text stays on the column edge */
}
.section details[open] > summary { margin-bottom: 14px; }
@media (min-width: 1040px) {
  .section summary::before {
    position: absolute; left: calc(-1 * var(--lead));
    margin-right: 0; font-size: 15px;
  }
}

/* ---------- table of contents ---------- */
.toc { padding-top: 36px; }
.toc nav { display: flex; flex-direction: column; gap: 8px; font: 400 13px var(--mono); }

/* ---------- prev/next ---------- */
.post-nav { padding-top: 52px; }
.post-nav .links {
  display: flex; justify-content: space-between; gap: 24px;
  font: 400 13px var(--mono);
}

/* ---------- footer ---------- */
.site-footer {
  padding: 52px 0 40px;
  font: 400 12px var(--mono);
  display: flex; justify-content: space-between;
}

/* ---------- lightbox (lightbox.js) ----------
   Ink backdrop; the image fits the viewport, or — zoomed — sits at its natural
   size inside a scrolling box whose scroll position follows the mouse. */
body.lb-open { overflow: hidden; }
.lb-box {
  display: none; position: fixed; inset: 0; z-index: 100;
  background: var(--ink); color: var(--paper);
  overflow: hidden; outline: none;
  -webkit-user-select: none; user-select: none;
  opacity: 0; transition: opacity .2s;
  touch-action: none;   /* pinch/swipe/pan are ours, not the browser's */
}
.lb-box.on { display: block; }
.lb-box.in { opacity: 1; }
.lb-box.drag { transition: none; }   /* finger is driving the opacity */
/* frames are positioned and sized by lightbox.js; the view is a transform */
.lb-stage { position: absolute; inset: 0; will-change: transform; }
.lb-stage.anim { transition: transform .25s cubic-bezier(.2, .7, .2, 1); }
.lb-frame { position: absolute; transform-origin: 0 0; will-change: transform; contain: strict; }
.lb-frame.anim { transition: transform .25s cubic-bezier(.2, .7, .2, 1); }
/* each image keeps its own layer, so a fade never re-rasters the big one */
.lb-img { position: absolute; inset: 0; width: 100%; height: 100%; display: block; will-change: opacity; }
.lb-hi { opacity: 0; z-index: 1; }
.lb-hi.ready { opacity: .01; }   /* rastered while still, before the fade (lightbox.js) */
.lb-hi.in { opacity: 1; }   /* hard cut; for a crossfade add `transition: opacity .3s` and set FADE_MS to match */
.lb-box.zoomable .lb-frame { cursor: zoom-in; }
.lb-box.zoomed .lb-frame { cursor: zoom-out; }
.lb-box.loading .lb-frame { cursor: progress; }
.lb-bar { transition: opacity .2s; }
.lb-box.bar-hidden .lb-bar { opacity: 0; pointer-events: none; }
@media (prefers-reduced-motion: reduce) {
  .lb-box, .lb-stage.anim, .lb-frame.anim, .lb-bar { transition: none; }
}
.lb-bar {
  position: fixed; left: 0; right: 0; bottom: 0;
  display: flex; gap: 20px; align-items: baseline;
  padding: 12px 16px;
  font: 400 12px/1.4 var(--mono);
  background: linear-gradient(transparent, rgba(20, 20, 20, .85));
  pointer-events: none;
}
.lb-bar > * { pointer-events: auto; }
.lb-caption { flex: 1; min-width: 0; color: #c8c6c0; }
/* loading note in its own corner, so it never squeezes the caption */
.lb-status {
  position: fixed; top: 12px; left: 16px;
  font: 400 12px/1.4 var(--mono); color: var(--amber);
  pointer-events: none;
}
.lb-nav { display: flex; gap: 10px; align-items: baseline; }
.lb-count { color: #c8c6c0; font-variant-numeric: tabular-nums; }
.lb-prev, .lb-next {
  color: var(--paper); background: none; border: 0; padding: 0 4px;
  font: inherit; cursor: pointer;
}
.lb-prev:hover, .lb-next:hover { color: var(--amber); }
.lb-prev:disabled, .lb-next:disabled { color: #5a5954; cursor: default; }
.lb-orig, .lb-close {
  color: var(--paper); text-decoration: underline; text-underline-offset: 2px;
  background: none; border: 0; padding: 0; font: inherit; cursor: pointer;
}
.lb-orig:hover, .lb-close:hover { color: var(--amber); }

/* ---------- syntax highlighting ----------
   syntect emits `hl-` prefixed scope classes. GitHub-light-ish palette on the
   paper chip. `nocduro css-theme <name>` prints a full palette if ever wanted. */
pre .hl-comment { color: #6e7781; font-style: italic; }
pre .hl-keyword, pre .hl-storage { color: #cf222e; }
pre .hl-string { color: #0a3069; }
pre .hl-constant { color: #0550ae; }
pre .hl-entity.hl-name.hl-function, pre .hl-support.hl-function, pre .hl-support.hl-macro { color: #8250df; }
pre .hl-entity.hl-name.hl-type, pre .hl-support.hl-type, pre .hl-storage.hl-type { color: #953800; }
