/* ==========================================================================
   BLOG — the field log (index) and the post reading column
   On the quiet-page shell (pages.css). The index is a surveyor's log:
   a margin rail with a tick and dotted leader per entry, labelled year
   rules, mono kickers carrying real data (log number, date, tags, reading
   time), optional cover plates. Entries rest slightly dim under JS on fine
   pointers and brighten near the cursor — the hero's grammar, nothing
   moves, light only reveals. Sorting/filtering is blog.js; without JS the
   controls stay hidden and the newest-first log simply shows.
   ========================================================================== */

/* --------------------------------------------------------------------------
   Shared column head + return furniture (mirrors listing.css deliberately —
   each page owns its copy; both consume the main.css theme tokens)
   -------------------------------------------------------------------------- */

.log,
.post {
  margin: 0 auto;
  padding: 104px clamp(20px, 5vw, 36px) 72px;
}

.log { max-width: 820px; }
.post { max-width: 720px; }

.log-head { margin: 26px 0 30px; }

.log-head .kicker { color: var(--label); }

.log-head h1 {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: var(--fs-display-page);
  line-height: 1.05;
  letter-spacing: var(--ls-display);
  color: var(--paper);
  margin-top: 10px;
}

.entry-no { color: var(--tan); }

.listing-return {
  margin-top: 44px;
  text-align: center;
}

.return-link {
  display: inline-block;
  font-family: var(--font-mono);
  font-size: var(--fs-ui);
  letter-spacing: var(--ls-label);
  text-transform: var(--tt-label);
  text-decoration: none;
  color: var(--fir);
  transition: color 140ms ease;
}

.return-link:hover { color: var(--flag); }

/* --------------------------------------------------------------------------
   Sort + tag controls — an instrument strip between two hairlines.
   Server-rendered [hidden]; blog.js unhides them.
   -------------------------------------------------------------------------- */

/* display:flex would outrank the UA's [hidden] rule — restate it, or the
   controls (dead without JS) would show to no-JS visitors */
.log-controls[hidden] { display: none; }

.log-controls {
  display: flex;
  flex-wrap: wrap;
  gap: 8px 30px;
  align-items: center;
  margin: 0 0 30px;
  padding: 11px 2px;
  border-top: 1px solid rgba(var(--tan-rgb), 0.25);
  border-bottom: 1px solid rgba(var(--tan-rgb), 0.25);
}

.ctl-group {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 4px 6px;
}

.ctl-label {
  font-family: var(--font-mono);
  font-size: var(--fs-furniture);
  letter-spacing: var(--ls-kicker);
  text-transform: var(--tt-label);
  color: var(--fir);
  margin-right: 8px;
}

.ctl {
  font-family: var(--font-mono);
  font-size: var(--fs-furniture);
  letter-spacing: var(--ls-label);
  text-transform: var(--tt-label);
  color: var(--fir);
  background: none;
  border: 1px solid transparent;
  padding: 3px 8px;
  cursor: pointer;
  transition: color 140ms ease, border-color 140ms ease;
}

.ctl:hover { color: var(--flag); }

.ctl[aria-pressed="true"] {
  color: var(--paper);
  background: rgba(var(--strata-rgb), 0.88);
  border-color: rgba(var(--tan-rgb), 0.45);
}

/* --------------------------------------------------------------------------
   The log: rail, ticks, leaders, year rules, entries
   -------------------------------------------------------------------------- */

.log-entries {
  list-style: none;
  position: relative;
  margin: 0;
  padding: 0 0 0 64px;
}

/* the rail — one continuous vertical rule down the margin */
.log-entries::before {
  content: "";
  position: absolute;
  left: 18px;
  top: 4px;
  bottom: 4px;
  border-left: 1px solid rgba(var(--tan-rgb), 0.32);
}

.log-year {
  display: flex;
  align-items: center;
  gap: 14px;
  margin: 34px 0 8px -64px;
}

.log-year:first-child { margin-top: 0; }

.log-year span {
  /* positioned + benthic backing: the rail (an absolutely-positioned rule,
     so it paints above static text) crosses right through this label —
     knock the linework out behind it, About-caption style */
  position: relative;
  background: var(--benthic);
  padding: 3px 0;
  font-family: var(--font-mono);
  font-size: var(--fs-ui);
  letter-spacing: 0.2em;
  color: var(--label);
}

.log-year::after {
  content: "";
  flex: 1;
  border-top: 1px solid rgba(var(--tan-rgb), 0.28);
}

.log-entry {
  position: relative;
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 18px;
  padding: 18px 0 24px;
}

/* tick crossing the rail, at the kicker line's height */
.log-entry::before {
  content: "";
  position: absolute;
  left: -50px;
  top: 25px;
  width: 9px;
  border-top: 1px solid var(--tan);
}

/* dotted leader from the rail to the entry */
.log-entry::after {
  content: "";
  position: absolute;
  left: -41px;
  top: 25px;
  width: 34px;
  border-top: 1px dotted rgba(var(--tan-rgb), 0.5);
}

.log-title {
  font-family: var(--font-mono);
  font-size: var(--fs-pull);
  font-weight: 400;
  letter-spacing: var(--ls-meta);
  text-transform: var(--tt-label);
  margin: 10px 0 0;
}

.log-title a {
  color: var(--paper);
  text-decoration: none;
  transition: color 140ms ease;
}

.log-title a:hover,
.log-title a:focus-visible { color: var(--flag); }

.log-summary {
  margin-top: 10px;
  font-size: var(--fs-prose);
  line-height: var(--lh-prose);
  color: var(--paper);
  opacity: 0.92;
  max-width: 58ch;
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  line-clamp: 2;
  overflow: hidden;
}

.log-cover {
  position: relative;
  display: block;
  align-self: start;
  margin-top: 4px;
}

.log-cover img {
  display: block;
  width: 132px;
  height: 132px;
  object-fit: cover;
  border: 1px solid rgba(var(--tan-rgb), 0.45);
}

.log-cover::before {
  content: "";
  position: absolute;
  inset: 4px;
  border: 1px solid rgba(var(--tan-rgb), 0.18);
  pointer-events: none;
}

/* Resting dim: only where a hover can undo it, and only with JS present.
   Ticks and rail stay steady — light moves, geometry doesn't. */
@media (hover: hover) and (pointer: fine) {
  html.js .log-entry .log-body,
  html.js .log-entry .log-cover {
    opacity: 0.76;
    transition: opacity 160ms ease;
  }

  html.js .log-entry:hover .log-body,
  html.js .log-entry:focus-within .log-body,
  html.js .log-entry:hover .log-cover,
  html.js .log-entry:focus-within .log-cover { opacity: 1; }
}

/* Tag filter: non-matching entries recede but keep their place on the rail */
.log-entry.dim { opacity: 0.22; }

/* The ambient pool blog.js floats under the cursor (fine pointers only).
   It paints as the TOPMOST layer, a wash of light over everything (the
   hero/reveal.js lamp grammar): any layer sitting above the glow with a
   fill — the year labels' opaque rail knockout, the plate mark's and back
   button's translucent backings — shows up as a dark rectangle when the
   glow passes it. Above everything, nothing can silhouette; at these
   alphas (≤5%) the tint over text and hairlines is imperceptible. */
.log-pool {
  position: fixed;
  left: -420px;
  top: -420px;
  width: 840px;
  height: 840px;
  border-radius: 50%;
  pointer-events: none;
  z-index: 80;
  opacity: 0;
  transition: opacity 300ms ease;
  will-change: transform;
  background: radial-gradient(circle,
    rgba(var(--flag-rgb), 0.05) 0%,
    rgba(var(--tan-rgb), 0.03) 45%,
    rgba(var(--tan-rgb), 0) 70%);
}

/* --------------------------------------------------------------------------
   Post page: header
   -------------------------------------------------------------------------- */

.post-head { margin: 26px 0 0; }

.post-head .kicker { color: var(--label); }

.post-head h1 {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: var(--fs-display-post);
  line-height: 1.08;
  letter-spacing: var(--ls-display);
  color: var(--paper);
  margin-top: 12px;
}

.post-tags {
  list-style: none;
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin: 16px 0 0;
  padding: 0;
}

.draft-mark { color: var(--flag); }

.post-rule { margin: 26px 0 32px; }

/* --------------------------------------------------------------------------
   Post body typography
   -------------------------------------------------------------------------- */

.post-body {
  counter-reset: fig;
}

.post-body::after {
  content: "";
  display: block;
  clear: both;
}

.post-body p {
  font-size: var(--fs-body);
  line-height: var(--lh-reading);
  color: var(--paper);
  margin: 0 0 18px;
}

.post-body a {
  color: inherit;
  text-decoration: underline;
  text-decoration-color: rgba(var(--tan-rgb), 0.6);
  text-underline-offset: 3px;
  transition: color 140ms ease;
}

.post-body a:hover { color: var(--flag); }

/* A link that resolved to nothing: visibly dangling, deliberately inert */
.post-body .unresolved {
  color: var(--fir);
  border-bottom: 1px dotted rgba(var(--fir-rgb), 0.7);
  cursor: help;
}

.post-body h2 {
  font-family: var(--font-mono);
  font-size: var(--fs-prose);
  font-weight: 400;
  letter-spacing: var(--ls-wide);
  text-transform: var(--tt-label);
  color: var(--paper);
  clear: both;
  margin: 36px 0 14px;
  padding-top: 18px;
  border-top: 1px solid rgba(var(--tan-rgb), 0.2);
}

.post-body h3 {
  font-family: var(--font-mono);
  font-size: var(--fs-small);
  font-weight: 400;
  letter-spacing: var(--ls-label);
  text-transform: var(--tt-label);
  color: var(--label);
  clear: both;
  margin: 28px 0 10px;
}

.post-body ul,
.post-body ol {
  margin: 0 0 18px;
  padding-left: 24px;
}

.post-body li {
  font-size: var(--fs-body);
  line-height: 1.7;
  color: var(--paper);
  margin-bottom: 6px;
}

.post-body li::marker { color: var(--tan); }

.post-body blockquote {
  border-left: 2px solid rgba(var(--tan-rgb), 0.5);
  margin: 0 0 18px;
  padding: 2px 0 2px 18px;
}

.post-body blockquote p { opacity: 0.9; }

.post-body code {
  font-family: var(--font-mono);
  font-size: 0.88em;
  color: var(--paper);
  background: rgba(var(--strata-rgb), 0.9);
  border: 1px solid rgba(var(--tan-rgb), 0.25);
  padding: 1px 5px;
}

.post-body pre {
  background: rgba(10, 16, 14, 0.92);
  border: 1px solid rgba(var(--tan-rgb), 0.3);
  padding: 16px 18px;
  margin: 0 0 20px;
  overflow-x: auto;
}

.post-body pre code {
  background: none;
  border: 0;
  padding: 0;
  font-size: var(--fs-small);
  line-height: 1.6;
}

.post-body hr {
  border: 0;
  border-top: 1px solid rgba(var(--tan-rgb), 0.25);
  margin: 28px 0;
}

.table-scroll {
  overflow-x: auto;
  margin: 0 0 20px;
}

.post-body table {
  border-collapse: collapse;
  font-size: var(--fs-note);
}

.post-body th {
  font-family: var(--font-mono);
  font-size: var(--fs-ui);
  font-weight: 400;
  letter-spacing: var(--ls-snug);
  text-transform: var(--tt-label);
  color: var(--label);
  text-align: left;
}

.post-body th,
.post-body td {
  border: 1px solid rgba(var(--tan-rgb), 0.25);
  padding: 8px 12px;
  color: var(--paper);
}

/* --------------------------------------------------------------------------
   Figures — the image variant menu (blog.py builds the <figure>s)
   default: framed plate between hairline rules, mono caption, Fig. counter
   -------------------------------------------------------------------------- */

.fig {
  margin: 28px 0;
  padding: 14px 0;
  border-top: 1px solid rgba(var(--tan-rgb), 0.22);
  border-bottom: 1px solid rgba(var(--tan-rgb), 0.22);
}

.fig img {
  display: block;
  width: 100%;
  height: auto;
  border: 1px solid rgba(var(--tan-rgb), 0.4);
}

.fig:not(.fig-plain) { counter-increment: fig; }

.fig figcaption {
  font-family: var(--font-mono);
  font-size: var(--fs-ui);
  letter-spacing: var(--ls-tight);
  line-height: 1.5;
  color: var(--fir);
  margin-top: 10px;
}

.fig figcaption::before {
  content: "Fig. " counter(fig, decimal-leading-zero) " · ";
  color: var(--label);
}

/* wide: breaks out of the reading column */
.fig-wide {
  width: min(920px, calc(100vw - 2 * var(--frame-inset) - 48px));
  position: relative;
  left: 50%;
  transform: translateX(-50%);
}

/* full: edge to edge inside the neatline */
.fig-full {
  width: calc(100vw - 2 * var(--frame-inset) - 28px);
  position: relative;
  left: 50%;
  transform: translateX(-50%);
  padding: 0;
  border-top: 0;
  border-bottom: 0;
}

/* left / right: small floated plate, text wraps around it */
.fig-left,
.fig-right {
  width: min(46%, 300px);
  padding: 0;
  border-top: 0;
  border-bottom: 0;
}

.fig-left {
  float: left;
  margin: 6px 24px 14px 0;
}

.fig-right {
  float: right;
  margin: 6px 0 14px 24px;
}

/* pair: two consecutive .pair figures share a row */
.fig-pair {
  display: inline-block;
  vertical-align: top;
  width: calc(50% - 8px);
}

/* one figure that itself holds two images (adjacent-line authoring) */
.fig-pair:has(img + img) {
  display: block;
  width: 100%;
}

.fig-pair:has(img + img) img {
  display: inline-block;
  vertical-align: top;
  width: calc(50% - 8px);
}

/* plain: no frame furniture at all */
.fig-plain {
  padding: 0;
  border-top: 0;
  border-bottom: 0;
}

.fig-plain img { border: 0; }

/* --------------------------------------------------------------------------
   Post footer: adjacent posts
   -------------------------------------------------------------------------- */

.post-foot { margin-top: 44px; }

.post-adjacent {
  display: flex;
  justify-content: space-between;
  gap: 20px;
  padding-top: 18px;
  border-top: 1px solid rgba(var(--tan-rgb), 0.25);
}

.adj {
  text-decoration: none;
  max-width: 46%;
}

.adj-newer {
  margin-left: auto;
  text-align: right;
}

.adj-title {
  display: block;
  margin-top: 6px;
  font-family: var(--font-mono);
  font-size: var(--fs-small);
  letter-spacing: var(--ls-meta);
  text-transform: var(--tt-label);
  color: var(--paper);
  transition: color 140ms ease;
}

.adj:hover .adj-title,
.adj:focus-visible .adj-title { color: var(--flag); }

/* --------------------------------------------------------------------------
   Mobile
   -------------------------------------------------------------------------- */

@media (max-width: 640px) {
  .log-entries { padding-left: 30px; }
  .log-entries::before { left: 8px; }
  .log-year { margin-left: -30px; }
  .log-entry::before { left: -26px; width: 7px; }
  .log-entry::after { left: -19px; width: 14px; }
  .log-cover img { width: 96px; height: 96px; }
}

@media (max-width: 480px) {
  .log-title { font-size: var(--fs-prose); }
  .log-cover { margin-top: 26px; }
  .log-cover img { width: 84px; height: 84px; }
  .post-body p, .post-body li { font-size: var(--fs-prose); }
}

@media (max-width: 560px) {
  .fig-left,
  .fig-right {
    float: none;
    width: 100%;
    margin: 28px 0;
  }

  .fig-pair {
    display: block;
    width: 100%;
  }

  .fig-pair:has(img + img) img {
    display: block;
    width: 100%;
  }

  .fig-pair:has(img + img) img + img { margin-top: 10px; }
}

@media (prefers-reduced-motion: reduce) {
  html.js .log-entry .log-body,
  html.js .log-entry .log-cover { opacity: 1; transition: none; }

  .ctl,
  .return-link,
  .log-title a,
  .post-body a,
  .adj-title,
  .log-pool { transition: none; }
}
