/* One warm greige family, three steps of the same ramp. The masthead is the
   deepest step so the top has weight without flipping to black; everything
   lightens downward. Text stays dark on all three - no reversed-out type.
     masthead #cdc7b8  ->  rail #ebe8e0  ->  paper #faf9f6
   Layout is a centred two-column shell - archive left, rail right. */

:root {
  --paper: #faf9f6;
  --surface: #ebe8e0;
  --masthead: #cdc7b8;
  --ink: #1c1b19;

  --ink-soft: #43403a;
  --ink-muted: #6b675f;
  /* One step lighter than --ink-soft, for the header pieces that support the
     name rather than compete with it. Holds 4.6:1 on the masthead, which is
     the floor for text this size; --ink-muted is the next step down and
     measures 3.4, which is why it is not used here. */
  --ink-quiet: #54514a;
  --rule: #dcd8ce;
  --edge: #c4bdad;
  --masthead-fade: #f2efe8;

  --on-ink: #f6f4ef;
  --on-ink-dim: rgba(246, 244, 239, 0.68);

  --shell-w: 76rem;
  --rail-w: 15rem;
  --gutter: 4rem;
}

* { box-sizing: border-box; }

/* Everything below is in rem, so this one number scales the whole page. */
html {
  font-size: 94%;
  -webkit-text-size-adjust: 100%;
}

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink-soft);
  font-family: 'Source Serif 4', Charter, Georgia, serif;
  font-size: 1.125rem;
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
}

.bounds {
  max-width: var(--shell-w);
  margin: 0 auto;
  padding: 0 2rem;
}

.shell {
  display: grid;
  grid-template-columns: minmax(0, 1fr) var(--rail-w);
  gap: var(--gutter);
  align-items: start;
}

/* No hue to lean on, so links earn their affordance with rule + weight. */
a { color: var(--ink); text-decoration: none; }
a:hover { text-decoration: underline; text-underline-offset: 2px; }

.mono, .meta, .tag, nav.links, .entry-date, .section-label, .back, footer,
.recent, .rail-label, .rail li {
  font-family: 'IBM Plex Mono', ui-monospace, SFMono-Regular, Menlo, monospace;
}

.fancy {
  font-family: 'Bodoni Moda', Didot, 'Playfair Display', Georgia, serif;
  font-optical-sizing: auto;
}

/* ---------------------------------------------------------- nav bar */

/* A thin dark strip carries the nav, the way a masthead rule would. */
header.site { background: var(--ink); }
header.site .bounds {
  display: flex;
  justify-content: flex-end;
  padding-top: 0.8125rem;
  padding-bottom: 0.8125rem;
}
nav.links {
  display: flex;
  gap: 1.75rem;
  font-size: 0.75rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}
nav.links a { color: var(--on-ink-dim); }
nav.links a:hover { color: var(--on-ink); text-decoration: none; }

/* Below it, the name and opening prose sit on the deepest step of the greige
   ramp, fading to nearly paper at the foot so there is no seam to notice. */
.masthead {
  background: linear-gradient(
    to bottom,
    var(--masthead) 0%,
    var(--masthead) 52%,
    var(--masthead-fade) 100%
  );
  color: var(--ink-soft);
  margin-bottom: 4rem;
}

/* The taller band earns 5rem beneath it. A short one does not, or the inner
   pages open on a stretch of empty paper. */
.masthead:has(.compact) { margin-bottom: 4rem; }

/* ---------------------------------------------------------- nameplate */

/* Cut to the text, and even top and bottom so the block sits centred in the
   band rather than hung from the nav strip. The old 4.5/5 was set against a
   four-word lede; with a full line under the credential the band grew tall
   enough to push the first post off the opening screen. Both bands run the
   same padding so the strip above the name does not change height between
   the front page and a post. */
.nameplate { padding-top: 2.5rem; padding-bottom: 2.5rem; }
.nameplate .fancy {
  margin: 0;
  font-size: 3.25rem;
  font-weight: 400;
  line-height: 1.02;
  letter-spacing: -0.02em;
  color: var(--ink-quiet);
}

/* Inner pages carry the same band, just shorter. At 0.625rem the name sat 3px
   under the nav strip and read as stuck to it, while the front page gives it
   68px; that difference was the jolt on moving between them. The band cannot
   match the front page's height and should not, but the name needs its own
   air on both. */
.nameplate.compact { padding-top: 2.5rem; padding-bottom: 2.5rem; }
.nameplate.compact .fancy { font-size: 1.625rem; }
.nameplate.compact a.fancy { color: var(--ink-soft); }
.nameplate.compact a.fancy:hover { text-decoration: none; color: var(--ink); }

/* One line, directly under the name. Distributing these to the far edges of a
   1000px block left them orphaned - nothing bound them to the name. Proximity
   in a single left-aligned column does that job instead.
   --ink tones only; --ink-muted fails contrast against the masthead. */
.credential {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.5rem 0.6875rem;
  max-width: 44rem;
  margin: 1.5rem 0 0;
  font-family: 'IBM Plex Mono', ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 0.6875rem;
  letter-spacing: 0.09em;
  text-transform: uppercase;
}
.credential .role { color: var(--ink-quiet); }
.credential .domains { color: var(--ink-quiet); }

/* Drawn, not typed. A literal "|" is a full-height ASCII stroke whose height
   and baseline are whatever the font decides, and in a mono line it reads as
   stray code. A rule gives a category boundary that is visibly a different
   kind of mark from the middots separating items within a category.
   Uses --ink-muted, not --edge: --edge is a mid-tone and all but disappears
   against the masthead, which is also a mid-tone. */
.credential .sep {
  align-self: center;
  width: 1px;
  height: 1.25em;
  background: var(--ink-muted);
}

/* A single line stating what the site is, inside the masthead. Sized above
   body copy and kept close to the credential: at paragraph size with 2.5rem
   of space above it, one short phrase floated in the band and read as a
   leftover rather than a statement. */
.nameplate .lede {
  margin: 1.5rem 0 0;
  max-width: 30rem;
  font-size: 1.1875rem;
  line-height: 1.5;
  color: var(--ink-quiet);
}

/* ---------------------------------------------------------- section headers */

/* A rule with a label sitting on it - no fill, so the reading column stays
   paper and the tint reads as the rail only. */
.section-label {
  display: block;
  font-size: 0.6875rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-soft);
  border-top: 1px solid var(--edge);
  padding-top: 0.75rem;
  margin-bottom: 2.5rem;
}

section.listing { margin-bottom: 5rem; }
section.listing:last-child { margin-bottom: 0; }

/* The first section follows the lede, so it needs no rule above it. */
main .listing:first-of-type .section-label {
  border-top: 0;
  padding-top: 0;
}

/* ---------------------------------------------------------- entries */

.entry {
  display: grid;
  grid-template-columns: 6.5rem minmax(0, 1fr);
  gap: 1.75rem;
  margin-bottom: 3.5rem;
}
.entry:last-child { margin-bottom: 0; }

.entry-date {
  font-size: 0.6875rem;
  color: var(--ink-muted);
  padding-top: 0.45rem;
  white-space: nowrap;
}

.entry-title {
  font-size: 1.1875rem;
  font-weight: 600;
  margin: 0 0 0.5rem;
  line-height: 1.4;
  letter-spacing: -0.01em;
}
.entry-title a { color: var(--ink); }
.entry-title a:hover { text-decoration: underline; text-underline-offset: 3px; }
.entry-title a::after {
  content: ' \2192';
  opacity: 0;
  transition: opacity 0.12s ease;
}
.entry-title a:hover::after { opacity: 1; }

/* The column is wider than the ideal measure, so cap the running text. */
.entry .dek { margin: 0; color: var(--ink-soft); font-size: 1rem; max-width: 38rem; }
.entry-title { max-width: 40rem; }

/* Separated by a middot rather than hash-prefixed - the hash reads as social
   media convention, which is the wrong register for this writing. */
.entry .tags { margin-top: 0.875rem; display: flex; gap: 0.5rem; flex-wrap: wrap; }
.tag { font-size: 0.6875rem; color: var(--ink-muted); }
.tag + .tag::before { content: '\00b7'; margin-right: 0.5rem; opacity: 0.6; }

.start .entry-title { font-size: 1.375rem; }
.start .entry .dek { font-size: 1.0625rem; }

/* ---------------------------------------------------------- rail */

/* A tinted panel, deliberately unlike the reading column so the eye registers
   it as an aside instead of continuing to read across. */
.rail {
  background: var(--surface);
  padding: 1.75rem 1.75rem 2rem;
}
.rail-label {
  display: block;
  font-size: 0.625rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink-muted);
  padding-bottom: 0.625rem;
  border-bottom: 1px solid var(--rule);
  margin-bottom: 1rem;
}
.rail ul { list-style: none; margin: 0; padding: 0; }
.rail li { margin-bottom: 1.0625rem; line-height: 1.5; font-size: 0.75rem; }
.rail li:last-child { margin-bottom: 0; }
.rail a { color: var(--ink-soft); display: block; }
.rail a:hover { color: var(--ink); text-decoration: underline; text-underline-offset: 2px; }
.rail a.here { color: var(--ink); font-weight: 500; }

/* Carries the divider the feed link used to draw, so the rail still closes
   on a rule rather than trailing off. */
.rail-fresh {
  display: block;
  margin-top: 1.25rem;
  padding-top: 0.875rem;
  border-top: 1px solid var(--rule);
  font-family: 'IBM Plex Mono', ui-monospace, monospace;
  font-size: 0.625rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink-muted);
}

/* ---------------------------------------------------------- article */

article.post h1 {
  font-size: 2rem;
  font-weight: 600;
  line-height: 1.2;
  letter-spacing: -0.02em;
  margin: 0 0 0.875rem;
  color: var(--ink);
}
article.post > .meta {
  display: flex;
  gap: 0.75rem;
  flex-wrap: wrap;
  align-items: center;
  font-size: 0.6875rem;
  color: var(--ink-muted);
  margin-bottom: 3.5rem;
}

.prose { max-width: 40rem; }
.prose > *:first-child { margin-top: 0; }

/* A gap slightly wider than a line, so single-sentence paragraphs read as
   separate beats instead of one block. Long-form posts lean on this. */
.prose p { margin: 0 0 1.625rem; line-height: 1.75; }

/* A paragraph that is nothing but bold text is a pull-line: the one sentence
   the post turns on. Given size and air rather than a box or a rule, so it
   lands without turning into furniture. */
.prose p:has(> strong:only-child) {
  font-size: 1.3125rem;
  line-height: 1.5;
  letter-spacing: -0.01em;
  color: var(--ink);
  margin: 3.25rem 0;
}
.prose p > strong:only-child { font-weight: 600; }

.prose h2, .prose h3 { color: var(--ink); font-weight: 600; }
.prose h2 { font-size: 1.5rem; line-height: 1.3; letter-spacing: -0.015em; margin: 4rem 0 1.25rem; }
.prose h3 { font-size: 1.125rem; margin: 2.5rem 0 0.75rem; }
.prose ul, .prose ol { padding-left: 1.25rem; }
.prose li { margin-bottom: 0.375rem; }
.prose a { text-decoration: underline; text-underline-offset: 2px; }

.prose blockquote {
  margin: 1.75rem 0;
  padding: 0.25rem 0 0.25rem 1.25rem;
  border-left: 2px solid var(--edge);
  color: var(--ink-soft);
  font-style: italic;
}

.prose code {
  font-family: 'IBM Plex Mono', ui-monospace, monospace;
  font-size: 0.85em;
  background: var(--surface);
  padding: 0.1em 0.35em;
  border-radius: 2px;
}
.prose pre {
  font-family: 'IBM Plex Mono', ui-monospace, monospace;
  background: var(--surface);
  padding: 1rem 1.125rem;
  overflow-x: auto;
  font-size: 0.8125rem;
  line-height: 1.6;
}
.prose pre code { background: none; padding: 0; font-size: inherit; }
.prose hr { border: 0; border-top: 1px solid var(--rule); margin: 2.5rem 0; }
.prose img { max-width: 100%; height: auto; }
.prose table { border-collapse: collapse; width: 100%; font-size: 0.9375rem; }
.prose th, .prose td {
  text-align: left;
  padding: 0.5rem 0.75rem 0.5rem 0;
  border-bottom: 1px solid var(--rule);
}

.back { font-size: 0.6875rem; color: var(--ink-muted); display: inline-block; margin-bottom: 3rem; }
.back:hover { color: var(--ink); }

/* ---------------------------------------------------------- footer */

footer {
  border-top: 1px solid var(--rule);
  margin-top: 7rem;
  padding: 3rem 0 5rem;
  font-size: 0.75rem;
  line-height: 1.7;
  color: var(--ink-muted);
}
footer p { margin: 0 0 0.625rem; max-width: 38rem; }
footer a { text-decoration: underline; text-underline-offset: 2px; }
footer .fine { font-size: 0.6875rem; margin-bottom: 0; }

/* ---------------------------------------------------------- responsive */

@media (max-width: 56rem) {
  .shell { grid-template-columns: minmax(0, 1fr); gap: 3rem; }
}

@media (max-width: 34rem) {
  .bounds { padding: 0 1.25rem; }
  .nameplate { padding-top: 2rem; }
  .nameplate .fancy { font-size: 2.125rem; }
  /* Role and domains each take their own line here, so the dash would be left
     dangling at the end of the first one. */
  .credential .sep { display: none; }
  .credential { gap: 0.3125rem 0.6875rem; }
  .entry { grid-template-columns: minmax(0, 1fr); gap: 0.25rem; }
  .entry-date { padding-top: 0; }
  article.post h1 { font-size: 1.625rem; }
}
