/* minimal manual -- a skin for blog.sh, of the minimal family.

   The page is a handbook. Minimal stands underneath, whole. This file turns
   a post into a page of a manual -- its sections numbered, its contents
   standing beside the text and staying there, a note set apart from the
   text, the way to the next page said large at the foot -- and a listing
   into a table of contents: a title, a line of what it is about, and which
   part of which series it is.

   The palette is the site's, the faces the engine's, as in minimal.

   Built from minimal.css by src/build.rb; change the layer, not this file. */

/* The palette is the site's own: `colors:` in config/site.yml, which the
   engine writes into colors.css as --bg, --text, --meta-text, --border and
   --accent, for the day and for the night. This file sets none of the five.
   It gives them the names it thinks in -- paper, ink, muted, line -- and
   points the engine's OTHER names at those, so a card, the menu, the footer
   and a pill all stand on the page's own ground instead of on tints of their
   own. The selectors are the ones colors.css uses, at the same weight:
   loaded later, these win.

   So a site chooses the look by its colours alone. sean.cz says a
   yellow-orange paper (#FFF7EB, #FFA826 over white at nine parts in a
   hundred) under an ink of #1E1D1C, black under a warm #E6DCCB by night;
   a site that says nothing gets the engine's blue on its cool grey. */
:root,
:root[data-theme="light"] {
  --paper: var(--bg);
  --ink: var(--text);
  --muted: var(--meta-text);
  /* A hairline is the ink at eighteen parts in a hundred, so it darkens
     whatever it crosses -- the paper or a plate -- by the same step. Over
     the paper it comes out as the site's own --border. */
  --line: color-mix(in srgb, var(--text) 18%, transparent);
  /* A plate is the ink laid over the paper very thin. */
  --plate: color-mix(in srgb, var(--text) 3%, transparent);
  --on-ink: var(--bg);
  --on-accent: #ffffff;

  --card-bg: var(--paper);
  --footer-bg: var(--paper);
  --nav-bg: var(--paper);
  --nav-text: var(--muted);
  --nav-border: var(--line);
  --pill-bg: var(--plate);
  --search-bg: var(--plate);
  --hover-invert: var(--ink);
  --badge-hover-text: var(--on-ink);
  --lang-switch-bg: transparent;
  --lang-switch-text: var(--on-ink);
  --lang-switch-dim: var(--muted);

  --display: "JetBrains Mono", "SF Mono", Menlo, Consolas, monospace;
  --ui: "Open Sans", -apple-system, "Segoe UI", Arial, sans-serif;
  --mono: "JetBrains Mono", "SF Mono", Menlo, Consolas, monospace;
  --corner: 14px;
}

/* By night colors.css says the engine's other names again, later than the
   block above reaches, so they are pointed at the palette once more -- and
   the plate is laid a little thicker, because on a dark ground the day's
   weight left pills and plates looking like loose words. Written twice, as
   colors.css writes its own. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --line: color-mix(in srgb, var(--text) 26%, transparent);
    --plate: color-mix(in srgb, var(--text) 6%, transparent);
    --card-bg: var(--paper);
    --footer-bg: var(--paper);
    --nav-bg: var(--paper);
    --nav-text: var(--muted);
    --nav-border: var(--line);
    --pill-bg: var(--plate);
    --search-bg: var(--plate);
    --hover-invert: var(--ink);
    --badge-hover-text: var(--on-ink);
  }
}
:root[data-theme="dark"] {
  --line: color-mix(in srgb, var(--text) 26%, transparent);
  --plate: color-mix(in srgb, var(--text) 6%, transparent);
  --card-bg: var(--paper);
  --footer-bg: var(--paper);
  --nav-bg: var(--paper);
  --nav-text: var(--muted);
  --nav-border: var(--line);
  --pill-bg: var(--plate);
  --search-bg: var(--plate);
  --hover-invert: var(--ink);
  --badge-hover-text: var(--on-ink);
}

body {
  font-family: var(--ui);
  font-size: 16px;
  line-height: 1.55;
  background: var(--paper);
  color: var(--ink);
}

h1, h2, h3 { color: var(--ink); text-wrap: balance; }
b, strong { color: inherit; }
a { color: var(--ink); text-decoration-color: var(--accent); text-underline-offset: 3px; text-decoration-thickness: 1.5px; }
a:hover { color: var(--ink); text-decoration-thickness: 2.5px; }

/* The page: no frame, a wider measure, a gutter of its own. */
.wrap {
  max-width: 1080px;
  margin: 0 auto;
  padding: 28px 20px 56px;
  border: 0;
  border-radius: 0;
}

/* ------------------------------------------------------------------ head */

/* The banner is a row now: the site's mark, its name and claim, and at the
   far end the reader's own two switches. The picture is not shown; the
   link that carried it is stretched over the row, so the mark and the name
   are still the way home. */
.banner-wrap {
  display: flex;
  align-items: center;
  gap: 14px;
  min-height: 52px;
  margin-bottom: 22px;
}
.banner { display: none; }
.banner-link { position: absolute; inset: 0; z-index: 1; }
.banner-link:focus-visible { outline-offset: 2px; }

.banner-wrap:has(.banner-title)::before,
.banner-wrap::before {
  content: "";
  position: static;
  flex: none;
  width: 52px;
  height: 52px;
  border-radius: 50%;
  /* The picture is a square, and a square exactly as wide as the circle
     shows its straight sides in it, with the ground behind them. So it is
     drawn 4px wider than the circle, which then cuts into it all the way
     round, and the mark has no rim and no ground of its own. */
  border: 0;
  background: url("/assets/images/favicon.png") center / calc(100% + 4px) no-repeat;
}
.banner-wrap:has(.banner-claim)::after { content: none; }

.banner-overlay {
  position: static;
  padding: 0;
  gap: 2px;
  min-width: 0;
}
.banner-title,
.banner-claim { text-shadow: none; max-width: none; }
.banner-title {
  font-family: var(--display);
  font-size: 34px;
  font-weight: 500;
  line-height: 1.05;
  letter-spacing: -0.01em;
  text-transform: lowercase;
  color: var(--ink);
}
.banner-claim {
  align-self: flex-start;
  margin-top: 0;
  font-family: var(--ui);
  font-size: 15px;
  line-height: 1.35;
  text-align: left;
  color: var(--muted);
}

/* The two switches: a key for light and dark, a pill for the language. */
.banner-tools {
  position: relative;
  top: auto;
  right: auto;
  margin-left: auto;
  align-items: center;
  gap: 6px;
  flex: none;
}
#theme-toggle {
  position: relative;
  top: auto;
  right: auto;
  margin-left: auto;
  flex: none;
  min-width: 0;
  height: 28px;
  padding: 0 8px;
  background: none;
  border: 1px solid var(--line);
  border-radius: 8px;
  color: var(--muted);
  font-family: var(--ui);
  font-weight: 600;
  font-size: 13px;
}
.banner-tools #theme-toggle { margin-left: 0; }
#theme-toggle:hover { background: none; border-color: var(--ink); color: var(--ink); }
#theme-toggle:focus-visible { outline-color: var(--accent); outline-offset: 2px; }

.lang-switch {
  gap: 4px;
  padding: 2px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: none;
  font-family: var(--mono);
  font-size: 12px;
  letter-spacing: 0.05em;
  text-transform: lowercase;
}
.lang-switch__item { padding: 3px 9px; border-radius: 999px; color: var(--muted); }
.lang-switch__item.is-current { background: var(--ink); color: var(--on-ink); }
.lang-switch__item + .lang-switch__item::before { content: none; }
a.lang-switch:hover { background: none; border-color: var(--ink); }
a.lang-switch:hover .lang-switch__item { color: var(--ink); }
a.lang-switch:hover .lang-switch__item.is-current { color: var(--on-ink); }
a.lang-switch:focus-visible { outline-color: var(--accent); outline-offset: 2px; }

/* ------------------------------------------------------------------ menu */

/* The menu is a row of filters: an outline at rest, filled with ink when
   it is the listing you are in. */
.wrap > nav {
  min-height: 0;
  padding: 10px 0;
  margin-bottom: 18px;
  border: 0;
  background: var(--paper);
  align-items: center;
  gap: 10px 14px;
}
html { scroll-padding-top: 64px; }

nav ul { gap: 6px; }
nav li {
  margin-left: 0;
  height: auto;
  line-height: 1.3;
  font-size: 12px;
  text-transform: lowercase;
}
.wrap > nav a {
  height: auto;
  margin-top: 0;
  padding: 5px 11px;
  border: 1px solid var(--line);
  border-radius: 999px;
  font-family: var(--mono);
  letter-spacing: 0.05em;
  color: var(--muted);
  white-space: nowrap;
  box-sizing: border-box;
}
.wrap > nav a:hover { color: var(--ink); border-color: var(--ink); }
.wrap > nav a[aria-current="page"],
.wrap > nav li:first-child a[aria-current="page"] {
  background: var(--ink);
  border-color: var(--ink);
  color: var(--on-ink);
  font-weight: 700;
  padding: 5px 11px;
  margin: 0;
}
.wrap > nav a[aria-current="page"]:hover { background: var(--ink); color: var(--on-ink); border-color: var(--ink); }
.wrap > nav a:focus-visible,
.wrap > nav a[aria-current="page"]:focus-visible { outline-color: var(--accent); outline-offset: 2px; }

.nav-toggle { display: none; }

.search-form input[type="search"] {
  width: 240px;
  height: 36px;
  padding: 0 38px 0 14px;
  background: var(--plate);
  border: 1px solid var(--line);
  border-radius: 999px;
  color: var(--ink);
  font-family: var(--mono);
  font-size: 13px;
}
.search-form input[type="search"]::placeholder { color: var(--muted); text-transform: lowercase; }
.search-form input[type="search"]:focus { outline: none; border-color: var(--ink); }
.search-form button { top: 3px; right: 4px; width: 30px; height: 30px; color: var(--muted); }
.search-form button:hover { color: var(--ink); }

/* The engine folds the menu behind a button on a phone. Seven short pills
   wrap into two rows instead, so nothing is hidden -- and a bar three rows
   tall has no business following the reader down the page. */
@media (max-width: 700px) {
  .wrap > nav { position: static; padding: 0; }
  .nav-toggle { display: none; }
  nav ul,
  nav.nav-open ul { display: flex; flex-direction: row; flex-wrap: wrap; width: 100%; order: 0; margin-top: 0; }
  nav li { line-height: 1.3; }
  .wrap > nav a,
  .wrap > nav li:last-child a { padding: 7px 12px; border: 1px solid var(--line); }
  .wrap > nav a:hover { border-color: var(--ink); }
  .wrap > nav a[aria-current="page"],
  .wrap > nav li:first-child a[aria-current="page"] { padding: 7px 12px; margin: 0; border-color: var(--ink); }
  .search-form { flex: 1 1 100%; }
  .search-form input[type="search"] { width: 100%; height: 40px; }
  .search-form button { top: 5px; width: 30px; height: 30px; }
  html { scroll-padding-top: 12px; }
}

/* ---------------------------------------------------------------- layout */

.layout, .layout main, .layout aside { background: none; }
.layout {
  grid-template-columns: minmax(0, 1fr) 300px;
  gap: 48px;
  padding: 0;
  align-items: start;
}
.layout--no-aside { grid-template-columns: minmax(0, 1fr); }
@media (max-width: 860px) {
  .layout { grid-template-columns: minmax(0, 1fr); gap: 36px; }
}

.card { background: none; padding: 0; border-radius: 0; }

/* ------------------------------------------------------------ a listing */

/* What a listing is called: the kind of page in the terminal face, and --
   where there is one -- the thing itself beside it in the plain one. */
.listing-heading {
  font-family: var(--display);
  font-size: 29px;
  font-weight: 500;
  line-height: 1.2;
  letter-spacing: -0.01em;
  text-transform: lowercase;
  color: var(--ink);
  margin-bottom: 14px;
}
.listing-heading__icon { display: none; }
.listing-heading--tag .listing-heading__kind,
.listing-heading--search.has-query .listing-heading__kind,
.listing-heading--series .listing-heading__kind {
  position: static;
  width: auto;
  height: auto;
  margin: 0 10px 0 0;
  overflow: visible;
  clip: auto;
  clip-path: none;
  white-space: normal;
}
.listing-heading__kind ~ .listing-heading__value {
  font-family: var(--ui);
  font-size: 21px;
  font-weight: 600;
  letter-spacing: 0;
  text-transform: none;
}
.listing-heading__link:hover,
.listing-heading__link:focus-visible { color: var(--ink); text-decoration-color: var(--accent); }

/* A post in a listing is an open row: the date in the margin, a hairline
   under it, and of the post only how it begins. */
main .post-list-item {
  margin: 0;
  padding: 20px 0;
  border-bottom: 1px solid var(--line);
}
main .post-list-item:first-of-type { border-top: 1px solid var(--line); }
.post-header { margin: 0; gap: 18px; }

.date-badge,
.date-badge:hover {
  width: 92px;
  padding: 5px 0 0;
  background: none;
  border-radius: 0;
  text-align: left;
  font-family: var(--mono);
  font-weight: 700;
  font-size: 12px;
  letter-spacing: 0.06em;
  line-height: 1.4;
  text-transform: lowercase;
  color: var(--muted);
  font-variant-numeric: tabular-nums;
}
.date-badge:hover { color: var(--ink); }
.date-badge svg { display: none; }
.date-badge a:focus-visible { outline-color: var(--accent); outline-offset: 2px; }
.date-badge .pin-mark,
.date-badge:hover .pin-mark {
  position: static;
  margin-top: 8px;
  width: 22px;
  height: 22px;
  background: var(--accent);
  color: var(--on-accent);
}
.date-badge .pin-mark svg { display: block; }

.post-list-item .post-body {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 7px 14px;
}
.post-list-item .post-body > * { order: 5; flex: 0 0 100%; }
.post-list-item .post-body::after { content: none; }
.post-list-item .post-body > h2 {
  order: 1;
  margin: 0;
  font-size: 21px;
  font-weight: 600;
  line-height: 1.25;
  letter-spacing: -0.005em;
}
.post-list-item h2 a { color: var(--ink); text-decoration: none; }
.post-list-item h2 a:hover { color: var(--ink); text-decoration: underline; text-decoration-color: var(--accent); text-underline-offset: 4px; text-decoration-thickness: 2px; }
.post-list-item .series-note { order: 2; margin: 0; }
/* The text of a row runs to the right edge of its column, where its
   pictures and the row of facts under it end. It is held to no measure in
   characters: the column is the measure, here and in every skin built on
   this file, whatever width or size of type that skin gives it. */
.post-list-item .content { order: 3; max-width: none; }
.post-list-item .content > * { max-width: none; }
/* A row that opens with a block of code: the code scrolls inside itself
   and the row keeps its column. */
.post-list-item .post-body { min-width: 0; max-width: 100%; }
.post-list-item .post-body > * { min-width: 0; }
.post-list-item .content > pre { max-width: 100%; overflow-x: auto; }
/* The reading time, the counts and the tags are one run of words: their
   two boxes are dissolved, so a tag that does not fit goes to the start of
   the next line instead of hanging under the first tag. */
.post-list-item .post-body > .post-meta,
.post-list-item .post-body > .tags { display: contents; }
.post-list-item .post-meta > *,
.post-list-item .tags > * { flex: 0 0 auto; }
.post-list-item .post-meta > .reading-time { order: 6; }
.post-list-item .post-meta > .post-stats { order: 7; }
.post-list-item .tags > * { order: 8; }
.post-list-item .read-more { display: none; }

/* Only the first block of the teaser, and of a paragraph three lines. */
.post-list-item .content > *:not(:first-child) { display: none; }
.post-list-item .content > :first-child { margin: 0; }
.post-list-item .content > p:first-child {
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
  opacity: 0.82;
}

/* The card that opens the front page leads with its picture
   (layout.lead_card): under the title, with the opening words after it.
   The engine puts the picture first in the card; this shows it whole
   across the column and lets the first paragraph follow. */
.post-list-item--lead .content { max-width: none; }
.post-list-item--lead .content > figure:first-child,
.post-list-item--lead .content > .photo-grid:first-child { margin: 4px 0 12px; }
.post-list-item--lead .content > figure:first-child img {
  width: 100%;
  max-height: 460px;
  object-fit: cover;
}
.post-list-item--lead .content > p:first-of-type {
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
  opacity: 0.82;
  margin: 0;
}

/* A picture that opens a post is shown, but a tall one does not get to
   push the next three posts off the screen. */
.post-list-item .content figure img { width: auto; max-width: 100%; max-height: 420px; }
.post-list-item .content .photo-grid img { width: 100%; max-height: 260px; }

/* What the engine says about a post: how long, how many, about what. */
.post-meta { gap: 12px; margin: 0; }
.post-meta,
.post-stats,
.post-stat.reading-time,
.meta {
  font-family: var(--mono);
  font-weight: 700;
  font-size: 12px;
  letter-spacing: 0.06em;
  text-transform: lowercase;
  color: var(--muted);
  font-variant-numeric: tabular-nums;
}
.post-stats { gap: 10px; }
.post-stats:empty { display: none; }
.post-stat { gap: 4px; }
.post-stat svg { width: 12px; height: 12px; }
.reading-time svg { margin-right: 4px; vertical-align: -0.1em; }
.post-meta .reading-time { order: -1; }

.post-list-item .tag-pill,
.post-list-item a.tag-pill:hover {
  padding: 0;
  margin: 0;
  border: 0;
  background: none;
  border-radius: 0;
  color: var(--muted);
}
.post-list-item a.tag-pill:hover { color: var(--ink); }

@media (max-width: 700px) {
  .post-list-item h2 { font-size: 20px; }
  .listing-heading { font-size: 25px; }
}
@media (max-width: 560px) {
  .post-list-item .post-header { flex-direction: column; gap: 4px; }
  .date-badge, .date-badge:hover { width: auto; padding: 0; }
  .date-badge .pin-mark { display: inline-flex; margin: 0 0 0 8px; vertical-align: middle; }
  .date-badge a { display: inline; }
}

/* Tags, wherever they are pills. */
.tag-pill {
  padding: 4px 11px;
  margin: 0 6px 6px 0;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: none;
  color: var(--muted);
  font-family: var(--mono);
  font-size: 12px;
  letter-spacing: 0.05em;
  line-height: 1.3;
  text-transform: lowercase;
}
a.tag-pill:hover { background: none; border-color: var(--ink); color: var(--ink); }

/* The way to the next page: the one filled thing on a listing. */
.pagination {
  margin-top: 18px;
  font-family: var(--mono);
  font-weight: 700;
  font-size: 12px;
  letter-spacing: 0.06em;
  text-transform: lowercase;
  color: var(--muted);
}
.pagination a {
  padding: 5px 11px;
  border: 1px solid var(--line);
  border-radius: 999px;
  color: var(--muted);
  font-weight: 400;
}
.pagination a:hover { color: var(--ink); border-color: var(--ink); }
.pagination:not(.back) a:last-child,
.pagination:not(.back) a:last-child:hover {
  padding: 9px 18px;
  background: var(--accent);
  border-color: var(--accent);
  color: var(--on-accent);
  font-size: 13px;
  font-weight: 700;
}
.pagination:not(.back) a:last-child:hover { opacity: 0.85; }

/* ----------------------------------------------------------------- a post */

/* The head of a post reads in three lines: when and of what series, what
   it is called, and what the engine knows about it. The first line is set
   over the body rather than woven into it: the date stands where a
   listing keeps its dates, the series beside it where a listing starts its
   titles -- so the body stays an ordinary block, and the contents of a
   long post can float beside its text. A post that opens with its picture
   keeps the engine's own shape. */
.card:not(.has-hero) > article > .post-header {
  display: block;
  position: relative;
  padding-top: 28px;
}
.card:not(.has-hero) > article > .post-header > .date-badge,
.card:not(.has-hero) > article > .post-header > .date-badge:hover {
  position: absolute;
  top: 0;
  left: 0;
  width: 92px;
  padding: 0;
}
.card:not(.has-hero) > article > .post-header > .date-badge .pin-mark { display: none; }
.card:not(.has-hero) > article > .post-header > .post-body > .series-note {
  position: absolute;
  top: 0;
  left: 110px;
  right: 0;
  line-height: 1.4;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.card:not(.has-hero) > article > .post-header > .post-body > .post-meta {
  margin: 8px 0 0;
  padding-bottom: 18px;
  border-bottom: 1px solid var(--line);
}

.post-body h1 {
  margin: 0;
  font-size: clamp(27px, 4.4vw, 36px);
  font-weight: 700;
  line-height: 1.15;
  letter-spacing: -0.015em;
}
@media (max-width: 700px) {
  .post-body h1 { font-size: clamp(25px, 7vw, 30px); }
}

.series-note {
  margin: 0;
  font-family: var(--mono);
  font-weight: 700;
  font-size: 12px;
  letter-spacing: 0.06em;
  text-transform: lowercase;
  color: var(--accent);
}
.series-note a,
.series-note a:hover { color: var(--accent); text-decoration: none; }
.series-note a:hover { text-decoration: underline; }

.content { font-size: 17.5px; line-height: 1.68; }
/* A bare address, or any word longer than the column, is broken rather
   than let to push the page wider than a phone. */
.content { overflow-wrap: break-word; }
.post-list-item .content { font-size: 16px; line-height: 1.55; }
.content > p,
.content > ul,
.content > ol,
.content > blockquote,
.content > dl { max-width: 65ch; }
.content > :first-child { margin-top: 10px; }
.content h1, .content h2, .content h3, .content h4, .content h5, .content h6 { color: var(--ink); font-weight: 600; letter-spacing: -0.005em; }
.content h1 { font-size: 1.45rem; }
.content h2 { font-size: 1.3rem; }
.content h3 { font-size: 1.1rem; }
.content a:hover { color: var(--ink); }

figure { margin: 1.2rem 0; }
.content figure img,
.content video,
.photo-grid img { border-radius: var(--corner); border: 1px solid var(--line); }
.photo-grid { gap: 10px; }
figcaption { font-family: var(--mono); font-size: 12px; letter-spacing: 0.04em; color: var(--muted); }

blockquote { border-left: 2px solid var(--accent); }
.content pre, .chrome-text pre { background: var(--plate); border: 1px solid var(--line); border-radius: var(--corner); }
.content code, .chrome-text code { background: var(--plate); border-radius: 5px; font-family: "SF Mono", Menlo, Consolas, monospace; }
.content pre code, .chrome-text pre code { background: none; }
.content th { background: var(--plate); }
.copy-code { border-radius: 8px; background: var(--paper); }
.embed-responsive, .embed-audio { border-radius: var(--corner); }
.draft-banner { border-radius: var(--corner); }
.draft-banner strong, .draft-banner a { color: var(--on-accent); }
.file-card { border-radius: var(--corner); background: var(--plate); }
.file-card:hover { border-color: var(--ink); background: var(--plate); }
.file-icon { border-radius: 8px; }
.lightbox-overlay img { border-radius: var(--corner); }

/* The contents of a long post: a plate a third of the column wide,
   floated to the right with the text beginning beside it, the way the
   engine floats it. Under 700px the engine stops floating it and so does
   this -- there it is a block above the text. */
.toc {
  margin: 14px 0 0;
  padding: 12px 14px;
  border: 1px solid var(--line);
  border-radius: var(--corner);
  background: var(--plate);
}
@media (min-width: 701px) {
  .toc { float: right; width: 34%; margin: 18px 0 14px 24px; }
}
.toc-heading { font-family: var(--mono); font-weight: 700; font-size: 12px; letter-spacing: 0.06em; text-transform: lowercase; color: var(--muted); }
.toc a { color: var(--ink); text-decoration: none; }
.toc a:hover { text-decoration: underline; text-decoration-color: var(--accent); }

.tags { margin-top: 22px; padding-top: 16px; border-top: 1px solid var(--line); }
.post-list-item .tags { padding-top: 0; border-top: 0; }

.series-nav { margin: 16px 0 0; font-size: 12px; }
.series-nav a,
.series-nav a:hover {
  display: inline-block;
  padding: 5px 11px;
  border: 1px solid var(--line);
  border-radius: 999px;
  font-family: var(--mono);
  letter-spacing: 0.05em;
  text-transform: lowercase;
  text-decoration: none;
  color: var(--muted);
}
.series-nav a:hover { color: var(--ink); border-color: var(--ink); }

/* Sharing: outlines, and the first of them -- the fediverse, where this
   site's own conversation is -- the one filled. */
.share { margin-top: 22px; padding-top: 16px; border-top: 1px solid var(--line); }
.share__heading { font-family: var(--mono); font-weight: 700; font-size: 12px; letter-spacing: 0.06em; text-transform: lowercase; color: var(--muted); opacity: 1; }
.share__links { gap: 6px; }
.share__link { border: 1px solid var(--line); border-radius: 999px; background: none; color: var(--muted); }
.share__link:hover, .share__link:focus-visible { background: none; border-color: var(--ink); color: var(--ink); }
.share__link[data-share-mastodon],
.share__link[data-share-mastodon]:hover { background: var(--accent); border-color: var(--accent); color: var(--on-accent); }
.share__link[data-share-mastodon]:hover { opacity: 0.85; }
.share__link.is-done { background: var(--ink); border-color: var(--ink); color: var(--on-ink); }
.share__ask-input { border-radius: 999px; background: var(--plate); padding: 0.4rem 0.9rem; font-family: var(--mono); }
.share__ask-go { border-radius: 999px; background: none; font-family: var(--mono); text-transform: lowercase; }
.share__ask-go:hover, .share__ask-go:focus-visible { border-color: var(--ink); color: var(--ink); }
.share__change { font-family: var(--mono); }

.comments { margin-top: 22px; padding-top: 16px; border-top: 1px solid var(--line); }
.comments h3 {
  font-family: var(--display);
  font-size: 22px;
  font-weight: 500;
  letter-spacing: -0.01em;
  text-transform: lowercase;
  margin-bottom: 12px;
}
.comment { border-top: 1px solid var(--line); }
.comment-avatar { border: 1px solid var(--line); }
/* Who wrote it and when are a line of labels; the underline is kept for
   links inside what they wrote. */
.comment-meta a { text-decoration: none; }
.comment-meta a:hover { text-decoration: underline; text-decoration-color: var(--accent); }
.comment-meta a:first-child { font-weight: 600; }
.comment-date { color: var(--muted); }
.comment-date, .comment-favs, .comments-note { font-family: var(--mono); font-size: 12px; letter-spacing: 0.04em; }
.comment-media img { border-radius: 10px; }

/* --------------------------------------------------------------- sidebar */

/* Each widget is a label in the engine's voice over a plate: one hairline
   card holding its rows. */
aside > .card:first-child { margin-top: 0; }
aside .card { margin-bottom: 22px; }
aside h3,
footer h3 {
  margin: 0 0 8px 2px;
  font-family: var(--mono);
  font-weight: 700;
  font-size: 12px;
  letter-spacing: 0.06em;
  text-transform: lowercase;
  color: var(--muted);
}
aside .card > div {
  border: 1px solid var(--line);
  border-radius: var(--corner);
  background: var(--plate);
  overflow: hidden;
  font-size: 14.5px;
  line-height: 1.45;
}
aside .card > div:empty { display: none; }
aside .chrome-text { padding: 11px 13px; }
aside .chrome-text p { margin: 0 0 0.6rem; }
aside .chrome-text p:last-child { margin-bottom: 0; }
/* A portrait opening the about text sits beside it, small, whatever size
   the text's own markup asked for. */
aside .chrome-text p > img:first-child {
  float: right;
  width: 56px !important;
  height: 56px !important;
  margin: 3px 0 4px 12px !important;
  border: 1px solid var(--line);
}

.last,
.last:first-child { padding: 11px 13px; font-size: 14.5px; border-top: 1px solid var(--line); }
.last:first-child { border-top: 0; }
.last-date {
  font-family: var(--mono);
  font-weight: 700;
  font-size: 11px;
  letter-spacing: 0.06em;
  text-transform: lowercase;
  color: var(--muted);
}
.last-content p { margin: 2px 0 0; }
.last-content a { text-decoration: none; }
.last-content a:hover { text-decoration: underline; text-decoration-color: var(--accent); }
.last-content strong { font-family: var(--mono); font-size: 12px; letter-spacing: 0.04em; }
.last > a {
  margin-top: 4px;
  font-family: var(--mono);
  font-size: 11px;
  color: var(--muted);
  text-decoration: none;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.last > a:hover { color: var(--ink); }

/* A picture row: the thumbnail beside its date and name, not under them. */
.last:has(.pixelfed-thumb) {
  display: grid;
  grid-template-columns: 46px minmax(0, 1fr);
  column-gap: 11px;
  align-items: center;
}
.last:has(.pixelfed-thumb) .last-date { grid-column: 2; grid-row: 1; }
.last:has(.pixelfed-thumb) .last-content { display: contents; }
.last:has(.pixelfed-thumb) .last-content p { grid-column: 2; grid-row: 2; }
.last:has(.pixelfed-thumb) .pixelfed-thumb {
  grid-column: 1;
  grid-row: 1 / span 3;
  width: 46px;
  height: 46px;
  margin: 0;
  object-fit: cover;
  border-radius: 9px;
  border: 1px solid var(--line);
}
.last:has(.pixelfed-thumb) > a { grid-column: 2; grid-row: 3; }

.on-this-day-all { padding: 11px 13px; border-top: 1px solid var(--line); font-size: 14.5px; }
.on-this-day-all summary {
  font-family: var(--mono);
  font-weight: 700;
  font-size: 12px;
  letter-spacing: 0.05em;
  text-transform: lowercase;
  color: var(--muted);
}
.on-this-day-all summary:hover { color: var(--ink); }
.on-this-day-all a { text-decoration: none; }
.on-this-day-all a:hover { text-decoration: underline; text-decoration-color: var(--accent); }

/* ------------------------------------------------------------------ foot */

footer {
  margin-top: 40px;
  padding: 24px 0 0;
  background: none;
  border-top: 1px solid var(--line);
  border-radius: 0;
  grid-template-columns: 1fr 2fr 1.4fr;
  gap: 28px;
  font-size: 14.5px;
}
@media (max-width: 760px) {
  footer { grid-template-columns: minmax(0, 1fr); }
}
footer li { margin-bottom: 4px; }
footer li::before { content: none; }
footer p { color: var(--ink); font-size: 14.5px; margin: 0 0 8px; }
footer .copyright {
  font-family: var(--mono);
  font-weight: 700;
  font-size: 12px;
  letter-spacing: 0.06em;
  text-transform: lowercase;
  color: var(--muted);
}
.social-icons { gap: 6px; flex-wrap: wrap; }
.social-icons a { border: 1px solid var(--line); border-radius: 999px; background: none; color: var(--muted); }
.social-icons a:hover { background: none; border-color: var(--ink); color: var(--ink); }

#scroll-top {
  width: 34px;
  height: 34px;
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: 8px;
  color: var(--muted);
}
#scroll-top:hover { background: var(--paper); border-color: var(--ink); color: var(--ink); }

/* --------------------------------------------------------------- archive */

/* A year a row: its name, how many, and its twelve months as keys -- the
   fuller the month, the more ink. */
.archive-map { width: 100%; margin: 0; border-top: 1px solid var(--line); }
.archive-year { gap: 8px 14px; padding: 11px 0; border-bottom: 1px solid var(--line); }
.archive-year-name {
  min-width: 74px;
  font-family: var(--display);
  font-size: 21px;
  font-weight: 500;
  color: var(--ink);
}
a.archive-year-name:hover { text-decoration: underline; text-decoration-color: var(--accent); text-underline-offset: 4px; text-decoration-thickness: 2px; }
.archive-year-count {
  min-width: 44px;
  font-family: var(--mono);
  font-weight: 700;
  font-size: 12px;
  color: var(--accent);
  font-variant-numeric: tabular-nums;
}
.archive-year.is-empty .archive-year-count { color: var(--muted); }
.archive-months { gap: 5px; margin-left: auto; }
.archive-month,
.archive-month.is-empty {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 30px;
  height: 30px;
  padding: 0;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: none;
  color: var(--ink);
  font-family: var(--mono);
  font-weight: 700;
  font-size: 12px;
  font-variant-numeric: tabular-nums;
}
.archive-month.is-empty { border-style: dashed; color: var(--muted); opacity: 0.45; }
.archive-month.is-l1 { background: color-mix(in srgb, var(--ink) 8%, transparent); color: var(--ink); }
.archive-month.is-l2 { background: color-mix(in srgb, var(--ink) 22%, transparent); color: var(--ink); }
.archive-month.is-l3 { background: color-mix(in srgb, var(--ink) 48%, transparent); color: var(--paper); border-color: transparent; }
.archive-month.is-l4 { background: var(--ink); color: var(--on-ink); border-color: var(--ink); }
.archive-month:hover { outline: 0; border-color: var(--accent); }
.archive-month:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

@media (max-width: 700px) {
  .archive-year { flex-wrap: wrap; gap: 8px 12px; }
  .archive-year-name { min-width: 0; }
  .archive-year-count { min-width: 0; margin-left: auto; font-size: 12px; }
  .archive-months { flex: 0 0 100%; display: grid; grid-template-columns: repeat(12, minmax(0, 1fr)); gap: 3px; margin-left: 0; }
  .archive-month, .archive-month.is-empty { width: auto; height: auto; aspect-ratio: 1; font-size: 10px; border-radius: 6px; }
}

/* A year: each month a key over a plate of its days. */
.archive-section { margin: 0 0 22px; }
.archive-section h2 {
  top: 56px;
  margin: 0 0 8px;
  padding: 6px 2px;
  background: var(--paper);
  border-bottom: 0;
  font-family: var(--mono);
  font-weight: 700;
  font-size: 13px;
  letter-spacing: 0.06em;
  color: var(--muted);
}
.archive-list { border: 1px solid var(--line); border-radius: var(--corner); background: var(--plate); overflow: hidden; }
.archive-list li { gap: 8px; padding: 9px 13px; border-top: 1px solid var(--line); font-size: 15.5px; }
.archive-list li:first-child { border-top: 0; }
.archive-list time {
  min-width: 28px;
  text-align: left;
  font-family: var(--mono);
  font-weight: 700;
  font-size: 12px;
  letter-spacing: 0.04em;
  color: var(--muted);
  font-variant-numeric: tabular-nums;
}
.archive-list a { text-decoration: none; }
.archive-list a:hover { text-decoration: underline; text-decoration-color: var(--accent); }
@media (max-width: 700px) {
  .archive-section h2 { position: static; }
}

/* ------------------------------------------------------------------ tags */

.tag-index { max-width: none; margin: 0; gap: 6px; }
.tag-index-letter {
  margin: 14px 0 4px;
  padding: 10px 2px 0;
  background: none;
  border-bottom: 0;
  border-top: 1px solid var(--line);
  font-family: var(--mono);
  font-weight: 700;
  font-size: 13px;
  color: var(--muted);
}
.tag-index-letter:first-child { margin-top: 0; }
.tag-index-count { font-size: 10px; font-weight: 700; opacity: 1; margin-left: 4px; color: var(--accent); }
.tag-index-sort { display: flex; gap: 6px; max-width: none; margin: 0 0 14px; }
.tag-index-sort-button,
.tag-index-sort-button:first-child,
.tag-index-sort-button:last-child {
  justify-self: auto;
  padding: 5px 11px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: none;
  color: var(--muted);
  font-family: var(--mono);
  font-size: 12px;
  letter-spacing: 0.05em;
  text-transform: lowercase;
}
.tag-index-sort-button:hover { color: var(--ink); border-color: var(--ink); }
.tag-index-sort-button[aria-pressed="true"] { background: var(--ink); border-color: var(--ink); color: var(--on-ink); font-weight: 700; }

/* ---------------------------------------------------------------- search */

.search-tagline { margin: 0 0 12px; color: var(--muted); font-size: 14.5px; max-width: 58ch; }
.search-tip {
  margin: 0 0 16px;
  padding: 11px 13px;
  border: 1px solid var(--line);
  border-radius: var(--corner);
  background: var(--plate);
  font-family: var(--mono);
  font-size: 13px;
  line-height: 1.6;
  color: var(--muted);
}
.search-status {
  margin: 0 0 10px;
  font-family: var(--mono);
  font-weight: 700;
  font-size: 12px;
  letter-spacing: 0.06em;
  text-transform: lowercase;
  color: var(--accent);
}
.search-result h2 { margin: 4px 0 6px; font-size: 21px; font-weight: 600; line-height: 1.25; }
.search-result p { margin: 0; }
.search-result p:not(.meta) { opacity: 0.82; }
.not-found-sign { margin-left: 0; color: var(--muted); }

/* ---------------------------------------------------------------- accent */

/* Where the site's own colour speaks, beyond links and the one filled
   button: the filter that is on, when a thing was written, what a box is
   called, the headings inside an article and the marks beside its counts.
   Titles and running text stay ink -- on paper this light the accent
   reads in fills, rules and bold labels, not in small regular type.
   Written last, so one block can be taken out to have the quiet version
   back. */
.wrap > nav a[aria-current="page"],
.wrap > nav li:first-child a[aria-current="page"],
.wrap > nav a[aria-current="page"]:hover,
.tag-index-sort-button[aria-pressed="true"] {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--on-accent);
}
.lang-switch__item.is-current,
a.lang-switch:hover .lang-switch__item.is-current { background: var(--accent); color: var(--on-accent); }

.date-badge,
.date-badge:hover,
.archive-list time { color: var(--accent); }

/* The cursor of the terminal the site is written in, standing after its
   name. */
.banner-title::after {
  content: "";
  display: inline-block;
  width: 0.5em;
  height: 0.92em;
  margin-left: 0.14em;
  background: var(--accent);
  vertical-align: -0.1em;
}

aside h3,
footer h3,
.toc-heading,
.share__heading { color: var(--accent); }

.content h1,
.content h2,
.content h3,
.content h4,
.content h5,
.content h6 { color: var(--accent); }

.post-stat svg { color: var(--accent); }

/* Two rules in the accent close the head of the page and open its foot:
   one under the menu, one over the footer. */
.wrap > nav { padding-bottom: 14px; border-bottom: 2px solid var(--accent); }
footer { border-top: 2px solid var(--accent); }
@media (max-width: 700px) {
  .wrap > nav { padding-bottom: 14px; }
}
/* On the front page and its continuations nothing stands between the
   menu's rule and the first post, so that post gives up its own. */
main .listing-heading--home ~ .post-list-item:first-of-type { border-top: 0; }

/* The archive counts in the accent rather than in ink: the fuller the
   month, the more of it -- four steps mixed into the paper, the way the
   engine's own map mixes them. The month over a year's list too. */
.archive-month.is-l1 { background: color-mix(in srgb, var(--accent) 14%, var(--paper)); border-color: color-mix(in srgb, var(--accent) 30%, var(--paper)); color: var(--ink); }
.archive-month.is-l2 { background: color-mix(in srgb, var(--accent) 36%, var(--paper)); border-color: transparent; color: var(--ink); }
.archive-month.is-l3 { background: color-mix(in srgb, var(--accent) 66%, var(--paper)); border-color: transparent; color: var(--on-accent); }
.archive-month.is-l4 { background: var(--accent); border-color: var(--accent); color: var(--on-accent); }
.archive-month:hover { border-color: var(--ink); }
.archive-section h2 { color: var(--accent); }

/* On a tag's listing the word "tag" stays ink and the tag itself is said
   in the accent. */
.listing-heading--tag .listing-heading__value,
.listing-heading--tag .listing-heading__link:hover,
.listing-heading--tag .listing-heading__link:focus-visible { color: var(--accent); }
/* The same on a series' listing and on a search that has a query: the
   kind of page in ink, the thing itself in the accent. */
.listing-heading--series .listing-heading__value,
.listing-heading--search .listing-heading__value { color: var(--accent); }

/* Three small marks join the accent: the glass that starts a search, the
   heart beside a comment somebody starred, the arrow back to the top. */
.search-form button,
.search-form button:hover { color: var(--accent); }
.search-form button:hover { opacity: 0.7; }
.comment-favs { color: var(--accent); }
#scroll-top,
#scroll-top:hover { color: var(--accent); }

/* Under the pointer, whatever can be clicked takes the accent: its frame
   and its words. The filled ones keep their fill, and the archive's
   months -- already the accent -- keep their ink frame. */
.wrap > nav a:hover,
#theme-toggle:hover,
a.tag-pill:hover,
.pagination a:hover,
.series-nav a:hover,
.share__link:hover,
.share__link:focus-visible,
.share__ask-go:hover,
.share__ask-go:focus-visible,
.social-icons a:hover,
.tag-index-sort-button:hover,
.file-card:hover { border-color: var(--accent); color: var(--accent); }
#scroll-top:hover { border-color: var(--accent); }
a.lang-switch:hover { border-color: var(--accent); }
a.lang-switch:hover .lang-switch__item { color: var(--accent); }
a.lang-switch:hover .lang-switch__item.is-current { color: var(--on-accent); }
.post-list-item a.tag-pill:hover { color: var(--accent); }

.wrap > nav a[aria-current="page"]:hover,
.tag-index-sort-button[aria-pressed="true"]:hover,
.pagination:not(.back) a:last-child:hover,
.share__link[data-share-mastodon]:hover,
.share__link[data-share-mastodon]:focus-visible { color: var(--on-accent); }
.share__link.is-done,
.share__link.is-done:hover { background: var(--ink); border-color: var(--ink); color: var(--on-ink); }

/* Nothing here: the one page that is a notice rather than a listing, so
   its three lines -- what it says, the signpost, what to do -- stand in
   the middle of the column. */
main:has(> .not-found-sign) > .listing-heading { text-align: center; margin-top: 24px; }
main > .not-found-sign { margin: 24px auto 20px; }
main:has(> .not-found-sign) > .search-tagline { margin: 0 auto 40px; text-align: center; max-width: 52ch; }

/* The tag index: the letter over each run is a mark to find one's place
   by on a long page, so it is set large and in the accent; and a tag's
   count stands on the line after its name rather than above it. */
.tag-index-letter {
  padding-top: 14px;
  font-family: var(--display);
  font-weight: 500;
  font-size: 22px;
  line-height: 1.1;
  letter-spacing: 0;
  text-transform: lowercase;
  color: var(--accent);
}
.tag-index-count {
  font-family: var(--mono);
  font-size: 11px;
  font-weight: 700;
  vertical-align: baseline;
  margin-left: 6px;
  letter-spacing: 0;
}

/* How much has been written under a tag, by the length of its count: one
   digit plain, two tinted, three or more filled further. A stylesheet
   cannot compare numbers, so the two rules name the counts they do NOT
   mean -- 1 to 9, and 1 to 99 -- and take what is left. */
.tag-index-item:not(:is([data-count="1"], [data-count="2"], [data-count="3"], [data-count="4"], [data-count="5"], [data-count="6"], [data-count="7"], [data-count="8"], [data-count="9"])) > .tag-pill {
  background: color-mix(in srgb, var(--accent) 12%, var(--paper));
  border-color: color-mix(in srgb, var(--accent) 40%, var(--paper));
  color: var(--ink);
  font-weight: 700;
}
.tag-index-item:not(:is(
    [data-count="1"], [data-count="2"], [data-count="3"], [data-count="4"], [data-count="5"], [data-count="6"], [data-count="7"], [data-count="8"], [data-count="9"], [data-count="10"],
    [data-count="11"], [data-count="12"], [data-count="13"], [data-count="14"], [data-count="15"], [data-count="16"], [data-count="17"], [data-count="18"], [data-count="19"], [data-count="20"],
    [data-count="21"], [data-count="22"], [data-count="23"], [data-count="24"], [data-count="25"], [data-count="26"], [data-count="27"], [data-count="28"], [data-count="29"], [data-count="30"],
    [data-count="31"], [data-count="32"], [data-count="33"], [data-count="34"], [data-count="35"], [data-count="36"], [data-count="37"], [data-count="38"], [data-count="39"], [data-count="40"],
    [data-count="41"], [data-count="42"], [data-count="43"], [data-count="44"], [data-count="45"], [data-count="46"], [data-count="47"], [data-count="48"], [data-count="49"], [data-count="50"],
    [data-count="51"], [data-count="52"], [data-count="53"], [data-count="54"], [data-count="55"], [data-count="56"], [data-count="57"], [data-count="58"], [data-count="59"], [data-count="60"],
    [data-count="61"], [data-count="62"], [data-count="63"], [data-count="64"], [data-count="65"], [data-count="66"], [data-count="67"], [data-count="68"], [data-count="69"], [data-count="70"],
    [data-count="71"], [data-count="72"], [data-count="73"], [data-count="74"], [data-count="75"], [data-count="76"], [data-count="77"], [data-count="78"], [data-count="79"], [data-count="80"],
    [data-count="81"], [data-count="82"], [data-count="83"], [data-count="84"], [data-count="85"], [data-count="86"], [data-count="87"], [data-count="88"], [data-count="89"], [data-count="90"],
    [data-count="91"], [data-count="92"], [data-count="93"], [data-count="94"], [data-count="95"], [data-count="96"], [data-count="97"], [data-count="98"], [data-count="99"])) > .tag-pill {
  background: color-mix(in srgb, var(--accent) 42%, var(--paper));
  border-color: var(--accent);
}
.tag-index-item:not(:is(
    [data-count="1"], [data-count="2"], [data-count="3"], [data-count="4"], [data-count="5"], [data-count="6"], [data-count="7"], [data-count="8"], [data-count="9"], [data-count="10"],
    [data-count="11"], [data-count="12"], [data-count="13"], [data-count="14"], [data-count="15"], [data-count="16"], [data-count="17"], [data-count="18"], [data-count="19"], [data-count="20"],
    [data-count="21"], [data-count="22"], [data-count="23"], [data-count="24"], [data-count="25"], [data-count="26"], [data-count="27"], [data-count="28"], [data-count="29"], [data-count="30"],
    [data-count="31"], [data-count="32"], [data-count="33"], [data-count="34"], [data-count="35"], [data-count="36"], [data-count="37"], [data-count="38"], [data-count="39"], [data-count="40"],
    [data-count="41"], [data-count="42"], [data-count="43"], [data-count="44"], [data-count="45"], [data-count="46"], [data-count="47"], [data-count="48"], [data-count="49"], [data-count="50"],
    [data-count="51"], [data-count="52"], [data-count="53"], [data-count="54"], [data-count="55"], [data-count="56"], [data-count="57"], [data-count="58"], [data-count="59"], [data-count="60"],
    [data-count="61"], [data-count="62"], [data-count="63"], [data-count="64"], [data-count="65"], [data-count="66"], [data-count="67"], [data-count="68"], [data-count="69"], [data-count="70"],
    [data-count="71"], [data-count="72"], [data-count="73"], [data-count="74"], [data-count="75"], [data-count="76"], [data-count="77"], [data-count="78"], [data-count="79"], [data-count="80"],
    [data-count="81"], [data-count="82"], [data-count="83"], [data-count="84"], [data-count="85"], [data-count="86"], [data-count="87"], [data-count="88"], [data-count="89"], [data-count="90"],
    [data-count="91"], [data-count="92"], [data-count="93"], [data-count="94"], [data-count="95"], [data-count="96"], [data-count="97"], [data-count="98"], [data-count="99"])) > .tag-pill .tag-index-count { color: var(--ink); }
.tag-index-item > a.tag-pill:hover { border-color: var(--accent); }

/* A search result is laid out like any other row of posts: its date in
   the margin and in the accent, the title and the excerpt beside it. */
.search-result {
  display: grid;
  grid-template-columns: 92px minmax(0, 1fr);
  column-gap: 18px;
  align-items: start;
}
.search-result > .meta { grid-column: 1; grid-row: 1 / span 2; margin: 0; padding-top: 5px; line-height: 1.4; color: var(--accent); }
.search-result > h2 { grid-column: 2; margin: 0 0 6px; }
.search-result > p:not(.meta) { grid-column: 2; }
@media (max-width: 560px) {
  .search-result { grid-template-columns: minmax(0, 1fr); }
  .search-result > .meta { grid-row: auto; padding-top: 0; margin-bottom: 4px; }
  .search-result > h2,
  .search-result > p:not(.meta) { grid-column: 1; }
}
/* Once there are results the page is theirs: the two lines on how to
   search step aside, and come back when a query finds nothing. */
main:has(.search-result) > .search-tagline,
main:has(.search-result) > .search-tip { display: none; }
/* What the search says about itself is a sentence, and keeps the capital
   the engine gave it; a count comes in lower case on its own. */
.search-status { text-transform: none; }

/* The foot of a post is two blocks, not four: what it belongs to and
   where it can be sent -- the series, the tags, the sharing -- under one
   rule, and the conversation under another. */
article .series-nav { margin: 24px 0 0; padding-top: 16px; border-top: 1px solid var(--line); }
article .tags { margin-top: 14px; padding-top: 0; border-top: 0; }
article .content + .tags { margin-top: 24px; padding-top: 16px; border-top: 1px solid var(--line); }
article .share { margin-top: 14px; padding-top: 0; border-top: 0; }

/* The one filled thing there is the way into the conversation; sending
   the post on is an outline like its neighbours. */
.share__link[data-share-mastodon] { background: none; border-color: var(--line); color: var(--muted); opacity: 1; }
.share__link[data-share-mastodon]:hover,
.share__link[data-share-mastodon]:focus-visible { background: none; border-color: var(--accent); color: var(--accent); opacity: 1; }
.comments-reply { margin: 0 0 16px; display: flex; flex-wrap: wrap; gap: 8px; }
.comments-reply a,
.comments-reply a:hover {
  display: inline-block;
  padding: 9px 18px;
  border-radius: 999px;
  background: var(--accent);
  color: var(--on-accent);
  font-family: var(--mono);
  font-weight: 700;
  font-size: 13px;
  letter-spacing: 0.05em;
  text-transform: lowercase;
  text-decoration: none;
}
.comments-reply a:hover { opacity: 0.85; }

/* A gallery in a post runs three across on a wide screen -- where it has
   three pictures, or five and more. Two stay a pair and four a square,
   as the engine lays them; so does every gallery on a phone. In three
   columns the odd last picture keeps its own cell instead of the row. */
@media (min-width: 701px) {
  article .content .photo-grid:has(> figure:nth-child(3)):not(:has(> figure:nth-child(4))),
  article .content .photo-grid:has(> figure:nth-child(5)) { grid-template-columns: repeat(3, 1fr); }
  article .content .photo-grid:has(> figure:nth-child(3)):not(:has(> figure:nth-child(4))) .span-2,
  article .content .photo-grid:has(> figure:nth-child(5)) .span-2 { grid-column: auto; }
}

/* The line over the comments is a sentence to the reader, not a reading
   off an instrument: the plain face, at the size of a label. */
.comments-note { font-family: var(--ui); font-size: 14.5px; letter-spacing: 0; line-height: 1.45; color: var(--muted); }

/* The parts on either side of this one are named by their titles, and a
   title is the post's own words: the plain face, its own capitals, ink.
   Side by side on a wide screen; on a phone one under the other, each the
   width of the column, the earlier to the left and the later to the right. */
.series-nav a,
.series-nav a:hover {
  max-width: 48%;
  padding: 9px 16px;
  font-family: var(--ui);
  font-weight: 600;
  font-size: 15px;
  letter-spacing: 0;
  text-transform: none;
  color: var(--ink);
}
.series-nav a:hover { color: var(--accent); }
@media (max-width: 700px) {
  .series-nav { flex-direction: column; gap: 8px; }
  .series-nav a,
  .series-nav a:hover { display: block; max-width: none; padding: 11px 14px; border-radius: var(--corner); line-height: 1.35; }
  .series-nav .series-next { margin-left: 0; text-align: right; }
}

/* A row in the sidebar is a glimpse, not the thing: what somebody posted
   or committed is cut at four lines, and the whole of it is a click away. */
#last-toots .last-content,
#last-commits .last-content,
#last-bluesky .last-content,
#last-rss .last-content {
  display: -webkit-box;
  -webkit-line-clamp: 4;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

/* The bare address under each sidebar row is not shown; the link that
   carried it is stretched over the row instead, so the row itself is the
   way to the thing. Links inside a row's own text stand above it and keep
   working. */
.last { position: relative; }
.last > a,
.last:has(.pixelfed-thumb) > a {
  position: absolute;
  inset: 0;
  /* No cell of its own: placed in the grid of a picture row it would be
     laid over that one cell, not over the row. */
  grid-area: auto;
  margin: 0;
  font-size: 0;
  z-index: 0;
}
.last > a:focus-visible { outline-offset: -3px; }
.last-content a { position: relative; z-index: 1; }
.last:has(> a:hover) { background: var(--plate); }

/* The foot: its three labels stand flush over what they name; its links
   are a plain list that takes the accent under the pointer; and on a
   narrow screen there is room under it for the arrow back to the top,
   which would otherwise sit on its last row. */
footer h3 { margin-left: 0; }
footer li a { text-decoration: none; }
footer li a:hover { color: var(--accent); }
@media (max-width: 1160px) {
  .wrap { padding-bottom: 84px; }
}
/* The foot's links are set small: a list of addresses beside a sentence. */
footer li { margin-bottom: 3px; }
footer li a { font-size: 12px; }

/* The copyright closes the foot on a line of its own, under all three
   columns. It is written inside the middle one, so that column's box is
   dissolved and its three children are placed in the foot's grid by hand:
   label and note where the column stood, the copyright across the bottom. */
/* The middle row takes whatever height the side columns need, so the
   label's own row stays as tall as the label. */
footer { row-gap: 0; grid-template-rows: min-content 1fr min-content; }
footer > div:nth-child(1) { grid-column: 1; grid-row: 1 / span 2; }
footer > div:nth-child(3) { grid-column: 3; grid-row: 1 / span 2; }
footer > div:nth-child(2) { display: contents; }
footer > div:nth-child(2) > h3 { grid-column: 2; grid-row: 1; }
footer > div:nth-child(2) > .chrome-text { grid-column: 2; grid-row: 2; }
footer > div:nth-child(2) > .copyright {
  grid-column: 1 / -1;
  grid-row: 3;
  margin: 24px 0 0;
  padding-top: 16px;
  border-top: 1px solid var(--line);
}
@media (max-width: 760px) {
  footer { grid-template-rows: none; }
  footer > div:nth-child(1) { grid-column: 1; grid-row: 1; margin-bottom: 24px; }
  footer > div:nth-child(2) > h3 { grid-column: 1; grid-row: 2; }
  footer > div:nth-child(2) > .chrome-text { grid-column: 1; grid-row: 3; margin-bottom: 24px; }
  footer > div:nth-child(3) { grid-column: 1; grid-row: 4; }
  footer > div:nth-child(2) > .copyright { grid-column: 1; grid-row: 5; }
}
/* ...and stands in the middle of its line, a colophon rather than the end
   of the left column. */
footer > div:nth-child(2) > .copyright { text-align: center; }

/* The head. On a wide screen the search field is as wide as the sidebar
   under it, so the two share an edge. On a phone the menu is one row that
   slides sideways, running off the right edge to say there is more of it,
   instead of two rows standing between the reader and the first post. */
@media (min-width: 701px) {
  .search-form input[type="search"] { width: 300px; }
}
@media (max-width: 700px) {
  nav ul,
  nav.nav-open ul {
    flex-wrap: nowrap;
    width: auto;
    flex: 1 1 100%;
    margin-right: -20px;
    padding-right: 20px;
    overflow-x: auto;
    scrollbar-width: none;
    -webkit-overflow-scrolling: touch;
  }
  nav ul::-webkit-scrollbar { display: none; }
  nav li { flex: none; }
}

/* The cursor after the site's name blinks the way a terminal's does: on,
   then off, with nothing in between. It stands still for a reader who has
   asked the system for less movement. */
@keyframes minimal-cursor {
  0%, 59% { opacity: 1; }
  60%, 100% { opacity: 0; }
}
.banner-title::after { animation: minimal-cursor 1.1s steps(1, end) infinite; }
@media (prefers-reduced-motion: reduce) {
  .banner-title::after { animation: none; }
}

/* A year's page: the month over each list is set like the letters of the
   tag index, large and in the accent, because it is the one mark to find
   one's place by; and a row is one line -- a post with no title is listed
   by its first sentence, which would otherwise run to two or three. */
.archive-section h2 {
  font-family: var(--display);
  font-weight: 500;
  font-size: 22px;
  line-height: 1.1;
  letter-spacing: 0;
}
.archive-list li a {
  flex: 1 1 auto;
  min-width: 0;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
/* The month follows the reader down its list in a band of its own, clear
   of the menu's rule above it, with a hairline under it. */
.archive-section h2 {
  top: 62px;
  margin: 0 0 10px;
  padding: 10px 2px 8px;
  background: var(--paper);
  border-bottom: 1px solid var(--line);
}

/* On a series' listing the order matters more than the day: the date
   steps back to grey and leaves the accent to the line that says which
   part this is. */
.listing-heading--series ~ .post-list-item .date-badge { color: var(--muted); }
.listing-heading--series ~ .post-list-item .date-badge:hover { color: var(--ink); }

/* The date's column is wide enough for the longest date a year has --
   two digits of day and two of month -- and a date never breaks: the
   year under the day read as two dates. The places that line up with
   that column move with it. */
.date-badge,
.date-badge:hover { width: 104px; white-space: nowrap; }
.search-result { grid-template-columns: 104px minmax(0, 1fr); }
.card:not(.has-hero) > article > .post-header > .date-badge,
.card:not(.has-hero) > article > .post-header > .date-badge:hover { width: 104px; }
.card:not(.has-hero) > article > .post-header > .post-body > .series-note { left: 122px; }
@media (max-width: 560px) {
  .date-badge, .date-badge:hover { width: auto; }
  .search-result { grid-template-columns: minmax(0, 1fr); }
}

/* A quotation that opens a card is cut like a paragraph is, a little
   later: six lines of somebody else's words, the rest on the post's page. */
.post-list-item .content > blockquote:first-child {
  display: -webkit-box;
  -webkit-line-clamp: 6;
  -webkit-box-orient: vertical;
  overflow: hidden;
  margin: 0;
}
.post-list-item .content > blockquote:first-child > :first-child { margin-top: 0; }

/* On the listings of pictures and of video a card shows its picture or
   its film as well as its opening words -- where the engine's cut of the
   card left it in. The listing is known by the menu item that is on. */
.wrap:has(> nav a[aria-current="page"][href$="/type/image/"]) .post-list-item .content > figure:first-of-type,
.wrap:has(> nav a[aria-current="page"][href$="/type/image/"]) .post-list-item .content > .photo-grid:first-of-type,
.wrap:has(> nav a[aria-current="page"][href$="/type/video/"]) .post-list-item .content > figure:first-of-type,
.wrap:has(> nav a[aria-current="page"][href$="/type/video/"]) .post-list-item .content > .embed-responsive:first-of-type {
  display: block;
  margin: 10px 0 0;
}
.wrap:has(> nav a[aria-current="page"][href$="/type/image/"]) .post-list-item .content > .photo-grid:first-of-type { display: grid; }
.post-list-item .content figure video { display: block; width: 100%; max-height: 420px; border-radius: var(--corner); border: 1px solid var(--line); background: #000; }

/* A listing by type is named by the menu item that is on, right above
   it; the heading saying the same word again is kept for a reader who
   moves by headings and taken out of sight. With nothing between the
   menu's rule and the first post, that post gives up its own rule. */
.listing-heading--type {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}
main .listing-heading--type ~ .post-list-item:first-of-type { border-top: 0; }

/* A post with no title of its own -- a toot, a tweet, a photograph --
   shows its picture or film in its card on every listing: there the
   picture is half of what was said. A titled post stays words. It shows
   only what the engine's cut of the card left in, which today is not
   much; the rule waits for the day the card carries its media. */
.post-list-item .post-body:not(:has(> h2)) .content > figure:first-of-type,
.post-list-item .post-body:not(:has(> h2)) .content > .embed-responsive:first-of-type { display: block; margin: 10px 0 0; }
.post-list-item .post-body:not(:has(> h2)) .content > .photo-grid:first-of-type { display: grid; margin: 10px 0 0; }

/* On black the same two tints sink into brown and towards each other, so
   the dark scheme mixes more of the accent into both. Written twice, as
   the palette is: once for a reader who follows the system, once for one
   who switched by hand. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .tag-index-item:not(:is([data-count="1"], [data-count="2"], [data-count="3"], [data-count="4"], [data-count="5"], [data-count="6"], [data-count="7"], [data-count="8"], [data-count="9"])) > .tag-pill {
    background: color-mix(in srgb, var(--accent) 26%, var(--paper));
    border-color: color-mix(in srgb, var(--accent) 55%, var(--paper));
  }
  :root:not([data-theme="light"]) .tag-index-item:not(:is(
      [data-count="1"], [data-count="2"], [data-count="3"], [data-count="4"], [data-count="5"], [data-count="6"], [data-count="7"], [data-count="8"], [data-count="9"], [data-count="10"],
      [data-count="11"], [data-count="12"], [data-count="13"], [data-count="14"], [data-count="15"], [data-count="16"], [data-count="17"], [data-count="18"], [data-count="19"], [data-count="20"],
      [data-count="21"], [data-count="22"], [data-count="23"], [data-count="24"], [data-count="25"], [data-count="26"], [data-count="27"], [data-count="28"], [data-count="29"], [data-count="30"],
      [data-count="31"], [data-count="32"], [data-count="33"], [data-count="34"], [data-count="35"], [data-count="36"], [data-count="37"], [data-count="38"], [data-count="39"], [data-count="40"],
      [data-count="41"], [data-count="42"], [data-count="43"], [data-count="44"], [data-count="45"], [data-count="46"], [data-count="47"], [data-count="48"], [data-count="49"], [data-count="50"],
      [data-count="51"], [data-count="52"], [data-count="53"], [data-count="54"], [data-count="55"], [data-count="56"], [data-count="57"], [data-count="58"], [data-count="59"], [data-count="60"],
      [data-count="61"], [data-count="62"], [data-count="63"], [data-count="64"], [data-count="65"], [data-count="66"], [data-count="67"], [data-count="68"], [data-count="69"], [data-count="70"],
      [data-count="71"], [data-count="72"], [data-count="73"], [data-count="74"], [data-count="75"], [data-count="76"], [data-count="77"], [data-count="78"], [data-count="79"], [data-count="80"],
      [data-count="81"], [data-count="82"], [data-count="83"], [data-count="84"], [data-count="85"], [data-count="86"], [data-count="87"], [data-count="88"], [data-count="89"], [data-count="90"],
      [data-count="91"], [data-count="92"], [data-count="93"], [data-count="94"], [data-count="95"], [data-count="96"], [data-count="97"], [data-count="98"], [data-count="99"])) > .tag-pill {
    background: color-mix(in srgb, var(--accent) 62%, var(--paper));
    border-color: var(--accent);
  }
  :root:not([data-theme="light"]) .tag-index-item:not(:is(
      [data-count="1"], [data-count="2"], [data-count="3"], [data-count="4"], [data-count="5"], [data-count="6"], [data-count="7"], [data-count="8"], [data-count="9"], [data-count="10"],
      [data-count="11"], [data-count="12"], [data-count="13"], [data-count="14"], [data-count="15"], [data-count="16"], [data-count="17"], [data-count="18"], [data-count="19"], [data-count="20"],
      [data-count="21"], [data-count="22"], [data-count="23"], [data-count="24"], [data-count="25"], [data-count="26"], [data-count="27"], [data-count="28"], [data-count="29"], [data-count="30"],
      [data-count="31"], [data-count="32"], [data-count="33"], [data-count="34"], [data-count="35"], [data-count="36"], [data-count="37"], [data-count="38"], [data-count="39"], [data-count="40"],
      [data-count="41"], [data-count="42"], [data-count="43"], [data-count="44"], [data-count="45"], [data-count="46"], [data-count="47"], [data-count="48"], [data-count="49"], [data-count="50"],
      [data-count="51"], [data-count="52"], [data-count="53"], [data-count="54"], [data-count="55"], [data-count="56"], [data-count="57"], [data-count="58"], [data-count="59"], [data-count="60"],
      [data-count="61"], [data-count="62"], [data-count="63"], [data-count="64"], [data-count="65"], [data-count="66"], [data-count="67"], [data-count="68"], [data-count="69"], [data-count="70"],
      [data-count="71"], [data-count="72"], [data-count="73"], [data-count="74"], [data-count="75"], [data-count="76"], [data-count="77"], [data-count="78"], [data-count="79"], [data-count="80"],
      [data-count="81"], [data-count="82"], [data-count="83"], [data-count="84"], [data-count="85"], [data-count="86"], [data-count="87"], [data-count="88"], [data-count="89"], [data-count="90"],
      [data-count="91"], [data-count="92"], [data-count="93"], [data-count="94"], [data-count="95"], [data-count="96"], [data-count="97"], [data-count="98"], [data-count="99"])) > .tag-pill .tag-index-count { color: var(--ink); }
}
:root[data-theme="dark"] .tag-index-item:not(:is([data-count="1"], [data-count="2"], [data-count="3"], [data-count="4"], [data-count="5"], [data-count="6"], [data-count="7"], [data-count="8"], [data-count="9"])) > .tag-pill {
  background: color-mix(in srgb, var(--accent) 26%, var(--paper));
  border-color: color-mix(in srgb, var(--accent) 55%, var(--paper));
}
:root[data-theme="dark"] .tag-index-item:not(:is(
    [data-count="1"], [data-count="2"], [data-count="3"], [data-count="4"], [data-count="5"], [data-count="6"], [data-count="7"], [data-count="8"], [data-count="9"], [data-count="10"],
    [data-count="11"], [data-count="12"], [data-count="13"], [data-count="14"], [data-count="15"], [data-count="16"], [data-count="17"], [data-count="18"], [data-count="19"], [data-count="20"],
    [data-count="21"], [data-count="22"], [data-count="23"], [data-count="24"], [data-count="25"], [data-count="26"], [data-count="27"], [data-count="28"], [data-count="29"], [data-count="30"],
    [data-count="31"], [data-count="32"], [data-count="33"], [data-count="34"], [data-count="35"], [data-count="36"], [data-count="37"], [data-count="38"], [data-count="39"], [data-count="40"],
    [data-count="41"], [data-count="42"], [data-count="43"], [data-count="44"], [data-count="45"], [data-count="46"], [data-count="47"], [data-count="48"], [data-count="49"], [data-count="50"],
    [data-count="51"], [data-count="52"], [data-count="53"], [data-count="54"], [data-count="55"], [data-count="56"], [data-count="57"], [data-count="58"], [data-count="59"], [data-count="60"],
    [data-count="61"], [data-count="62"], [data-count="63"], [data-count="64"], [data-count="65"], [data-count="66"], [data-count="67"], [data-count="68"], [data-count="69"], [data-count="70"],
    [data-count="71"], [data-count="72"], [data-count="73"], [data-count="74"], [data-count="75"], [data-count="76"], [data-count="77"], [data-count="78"], [data-count="79"], [data-count="80"],
    [data-count="81"], [data-count="82"], [data-count="83"], [data-count="84"], [data-count="85"], [data-count="86"], [data-count="87"], [data-count="88"], [data-count="89"], [data-count="90"],
    [data-count="91"], [data-count="92"], [data-count="93"], [data-count="94"], [data-count="95"], [data-count="96"], [data-count="97"], [data-count="98"], [data-count="99"])) > .tag-pill {
  background: color-mix(in srgb, var(--accent) 62%, var(--paper));
  border-color: var(--accent);
}
:root[data-theme="dark"] .tag-index-item:not(:is(
    [data-count="1"], [data-count="2"], [data-count="3"], [data-count="4"], [data-count="5"], [data-count="6"], [data-count="7"], [data-count="8"], [data-count="9"], [data-count="10"],
    [data-count="11"], [data-count="12"], [data-count="13"], [data-count="14"], [data-count="15"], [data-count="16"], [data-count="17"], [data-count="18"], [data-count="19"], [data-count="20"],
    [data-count="21"], [data-count="22"], [data-count="23"], [data-count="24"], [data-count="25"], [data-count="26"], [data-count="27"], [data-count="28"], [data-count="29"], [data-count="30"],
    [data-count="31"], [data-count="32"], [data-count="33"], [data-count="34"], [data-count="35"], [data-count="36"], [data-count="37"], [data-count="38"], [data-count="39"], [data-count="40"],
    [data-count="41"], [data-count="42"], [data-count="43"], [data-count="44"], [data-count="45"], [data-count="46"], [data-count="47"], [data-count="48"], [data-count="49"], [data-count="50"],
    [data-count="51"], [data-count="52"], [data-count="53"], [data-count="54"], [data-count="55"], [data-count="56"], [data-count="57"], [data-count="58"], [data-count="59"], [data-count="60"],
    [data-count="61"], [data-count="62"], [data-count="63"], [data-count="64"], [data-count="65"], [data-count="66"], [data-count="67"], [data-count="68"], [data-count="69"], [data-count="70"],
    [data-count="71"], [data-count="72"], [data-count="73"], [data-count="74"], [data-count="75"], [data-count="76"], [data-count="77"], [data-count="78"], [data-count="79"], [data-count="80"],
    [data-count="81"], [data-count="82"], [data-count="83"], [data-count="84"], [data-count="85"], [data-count="86"], [data-count="87"], [data-count="88"], [data-count="89"], [data-count="90"],
    [data-count="91"], [data-count="92"], [data-count="93"], [data-count="94"], [data-count="95"], [data-count="96"], [data-count="97"], [data-count="98"], [data-count="99"])) > .tag-pill .tag-index-count { color: var(--ink); }

/* A tag used once is the quiet ground the others stand on: small grey
   words with no frame and no count -- being unframed says the one. It is
   still a link, and takes the accent under the pointer like the rest. */
.tag-index-item[data-count="1"] > .tag-pill {
  border-color: transparent;
  padding-left: 4px;
  padding-right: 4px;
  font-size: 11px;
  opacity: 0.75;
}
.tag-index-item[data-count="1"] > a.tag-pill:hover { border-color: transparent; opacity: 1; }
.tag-index-item[data-count="1"] > .tag-pill .tag-index-count { display: none; }

/* The letter over a run of tags follows the reader down the page, as the
   month does on a year's page: under the menu, in a band of its own. The
   letters and the tags are one list, so a letter stays until the next
   one rides up over it. Not on a phone, where the menu does not stick
   either. */
@media (min-width: 701px) {
  .tag-index-letter {
    position: sticky;
    top: 62px;
    z-index: 1;
    margin: 14px 0 6px;
    padding: 10px 2px 8px;
    background: var(--paper);
    border-top: 0;
    border-bottom: 1px solid var(--line);
  }
  .tag-index-letter:first-child { margin-top: 0; }
}

/* A page that is not a post -- the Markdown cheat sheet -- is written as
   a title straight over its text, with no header around them. Its title
   is set like a post's; the list of its sections, which opens it, is a
   row of pills rather than a column of sixteen bullets; and each section's
   heading follows the reader down under the menu, as a month does in the
   archive. Only headings a contents link points at stick, so a heading
   shown as an example stays where it was written. */
.card > article > h1 {
  margin: 0 0 14px;
  font-size: clamp(27px, 4.4vw, 36px);
  font-weight: 700;
  line-height: 1.15;
  letter-spacing: -0.015em;
}
.card > article > .content > ul:has(> li > a[href^="#"]) {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  max-width: none;
  margin: 18px 0 8px;
  padding: 0;
  list-style: none;
}
.card > article > .content > ul:has(> li > a[href^="#"]) > li > a {
  display: inline-block;
  padding: 4px 11px;
  border: 1px solid var(--line);
  border-radius: 999px;
  font-family: var(--mono);
  font-size: 12px;
  letter-spacing: 0.05em;
  line-height: 1.3;
  text-transform: lowercase;
  text-decoration: none;
  color: var(--muted);
}
.card > article > .content > ul:has(> li > a[href^="#"]) > li > a:hover { border-color: var(--accent); color: var(--accent); }
@media (min-width: 701px) {
  .card > article > .content > h2[id] {
    position: sticky;
    top: 62px;
    z-index: 2;
    margin: 28px 0 18px;
    padding: 10px 0 8px;
    background: var(--paper);
    border-bottom: 1px solid var(--line);
  }
}
@media (max-width: 700px) {
  .card > article > h1 { font-size: clamp(25px, 7vw, 30px); }
}

/* The signpost of the page that is not there is drawn at the weight of
   everything else here: half the size, a thinner line. The sentence under
   it is the one thing the page has to say, so it is said in the text's own
   size and colour. */
main > .not-found-sign,
.not-found-sign { width: 170px; stroke-width: 2; }
main:has(> .not-found-sign) > .search-tagline { font-size: 16px; line-height: 1.55; color: var(--ink); }
@media (max-width: 700px) {
  .not-found-sign { width: 140px; }
}

/* By night a picture is turned down a fifth, so a white screenshot does
   not stand on a black page like a lamp. Under the pointer it comes back
   to what it is, and the enlarged view was never dimmed. Written twice,
   as the palette is. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .content figure img,
  :root:not([data-theme="light"]) .photo-grid img,
  :root:not([data-theme="light"]) .content video,
  :root:not([data-theme="light"]) .pixelfed-thumb { filter: brightness(0.82); transition: filter 0.2s ease-in-out; }
  :root:not([data-theme="light"]) .content figure img:hover,
  :root:not([data-theme="light"]) .photo-grid img:hover,
  :root:not([data-theme="light"]) .content video:hover,
  :root:not([data-theme="light"]) .last:hover .pixelfed-thumb { filter: none; }
}
:root[data-theme="dark"] .content figure img,
:root[data-theme="dark"] .photo-grid img,
:root[data-theme="dark"] .content video,
:root[data-theme="dark"] .pixelfed-thumb { filter: brightness(0.82); transition: filter 0.2s ease-in-out; }
:root[data-theme="dark"] .content figure img:hover,
:root[data-theme="dark"] .photo-grid img:hover,
:root[data-theme="dark"] .content video:hover,
:root[data-theme="dark"] .last:hover .pixelfed-thumb { filter: none; }

/* The phone, second pass. An article is set a size down, so a line holds
   more than five words; the arrow back to the top sits tight in the
   corner and lets the text under it show through, since on a phone there
   is no margin for it to stand in; and on the narrowest screens the
   site's name and claim are set smaller, so the head stays one row. */
@media (max-width: 700px) {
  .content { font-size: 16px; line-height: 1.62; }
  #scroll-top { right: 8px; bottom: 12px; opacity: 0.72; }
  #scroll-top:hover { opacity: 1; }
}
@media (max-width: 360px) {
  .banner-wrap { gap: 10px; }
  .banner-wrap::before,
  .banner-wrap:has(.banner-title)::before { width: 42px; height: 42px; }
  .banner-title { font-size: 25px; }
  .banner-claim { font-size: 12.5px; }
}

/* Under a post on a phone the sidebar keeps what is about the author and
   the day, and leaves out the three feeds -- toots, pictures, commits --
   that would put two more screens between the last comment and the foot.
   Listings keep all of it, and so does a wide screen. */
@media (max-width: 860px) {
  .layout:has(main article > .post-header) aside .card:has(#last-toots),
  .layout:has(main article > .post-header) aside .card:has(#last-pixelfeds),
  .layout:has(main article > .post-header) aside .card:has(#last-commits),
  .layout:has(main article > .post-header) aside .card:has(#last-bluesky),
  .layout:has(main article > .post-header) aside .card:has(#last-rss) { display: none; }
}

/* A letter may reach a pixel or two past the edge of its column -- the
   hook of a j does -- and whatever sticks is exactly as wide as that
   column, so the reach showed beside it as a speck while the line passed
   underneath. The ground of each sticking band is carried a little way out
   on both sides to cover it. */
@media (min-width: 701px) {
  .wrap > nav { box-shadow: -12px 0 0 var(--paper), 12px 0 0 var(--paper); }
  .archive-section h2,
  .tag-index-letter,
  .card > article > .content > h2[id] { box-shadow: -8px 0 0 var(--paper), 8px 0 0 var(--paper); }
}

/* The tablet. Between a phone and a full desk the head and the two
   columns are fitted to what room there is. Up to 860px, where the
   sidebar has gone under the content, the search field gives way so the
   menu stays one row -- the sticking headings below count on a bar one
   row tall. From there to 1000px the sidebar is narrower, so the column
   of posts is not squeezed to four words a line, and the search field
   matches it. */
@media (min-width: 701px) and (max-width: 860px) {
  .search-form { flex: 1 1 140px; min-width: 140px; max-width: 300px; }
  .search-form input[type="search"] { width: 100%; }
}
@media (min-width: 861px) and (max-width: 1000px) {
  .layout { grid-template-columns: minmax(0, 1fr) 240px; gap: 32px; }
  .search-form input[type="search"] { width: 240px; }
}

/* Where the sidebar has gone under the content and there is still room
   for two of its boxes abreast -- a tablet held upright -- they are poured
   into two columns the way a newspaper pours text: down the first, on
   down the second, the browser keeping the two the same height and never
   cutting a box in half. Laid out in rows instead, a short box left a
   hole beside a long one. */
@media (min-width: 561px) and (max-width: 860px) {
  aside { display: block; column-count: 2; column-gap: 24px; }
  aside .card { break-inside: avoid; margin: 0 0 22px; }
  aside > .card:first-child { margin-top: 0; }
}

/* A site in more than one language, on a phone. The two switches together
   are too wide to stand beside the name and the claim -- the claim was
   squeezed into a column three words wide and the head came apart. So
   there the pair is pinned to the top right, level with the site's name,
   which is short, and the claim runs the full width under both. */
@media (max-width: 700px) {
  .banner-wrap:has(.banner-tools) .banner-tools {
    position: absolute;
    top: 4px;
    right: 0;
    margin-left: 0;
  }
}
@media (max-width: 360px) {
  .banner-wrap:has(.banner-tools) .banner-tools { top: 0; gap: 4px; }
  .banner-wrap:has(.banner-tools) .lang-switch__item { padding: 3px 7px; }
}
/* On the narrowest screens the name's cursor would run into the pair, so
   there -- and only on a site with a second language -- it is left out. */
@media (max-width: 360px) {
  .banner-wrap:has(.banner-tools) .banner-title::after { content: none; }
}
/* And the name itself gives way to the pair instead of running under it.
   A stylesheet cannot see two things overlap, but it can work out the room:
   the screen less the mark, the pair and the air between them is what the
   name has, and a monospace is six tenths of its size to a character. So
   the name is set as large as that room allows for a name of --name-chars
   characters, between a floor and its full size. Nine is the base's guess
   -- "./blog.sh" -- and a site with a shorter or longer name says its own
   number in a stylesheet of its own. */
:root { --name-chars: 9; --name-floor: 19px; }
@media (max-width: 700px) {
  .banner-wrap:has(.lang-switch) .banner-title { font-size: clamp(var(--name-floor), calc((100vw - 250px) / (0.6 * var(--name-chars))), 34px); }
}

/* The two switches in the head are one kind of thing -- a setting, not a
   place to go -- and are drawn alike: keys, the shape the appearance
   switch and the arrow back to the top already have. A pill is left to
   mean a filter or a link. */
.lang-switch { height: 28px; box-sizing: border-box; padding: 2px; border-radius: 8px; }
.lang-switch__item { padding: 2px 8px; border-radius: 6px; }
@media (max-width: 360px) {
  .banner-wrap:has(.banner-tools) .lang-switch__item { padding: 2px 6px; }
}

/* Sharing, two details. The field that asks for an instance shows where
   the typing goes with its own frame in the accent and nothing around it
   -- frame and ring together were the heaviest thing on the page. And an
   address that has been copied says so the way everything switched on
   here does, filled with the accent, now that no neighbour of that button
   wears it at rest. */
.share__ask-input:focus,
.share__ask-input:focus-visible { outline: none; border-color: var(--accent); }
.share__link.is-done,
.share__link.is-done:hover,
.share__link.is-done:focus-visible { background: var(--accent); border-color: var(--accent); color: var(--on-accent); }

/* Somebody named at the head of a reply is an address, not the point of
   it: a mention -- in a comment, and in a toot in the sidebar -- is said in
   the accent with no rule under it, so the underline is left to links in
   what was actually written. */
.comment-content a.mention,
.last-content a.mention { color: var(--accent); text-decoration: none; }
.comment-content a.mention:hover,
.last-content a.mention:hover { color: var(--accent); text-decoration: underline; }

/* The whole of a day, unfolded: the year stands in a narrow column of
   its own and the titles line up beside it, the way days do on a year's
   page -- so a title that wraps does not run back under its year, and a
   year that comes six times can be read past. */
.on-this-day-all li {
  display: grid;
  grid-template-columns: 34px minmax(0, 1fr);
  column-gap: 8px;
  align-items: baseline;
  margin: 0;
  padding: 5px 0;
}
.on-this-day-all li .last-date { font-size: 11px; font-variant-numeric: tabular-nums; }
.on-this-day-all ul { margin-top: 6px; }

/* A post that opens with its picture (layout.hero, or `hero: true` in a
   post). The engine draws it for a card this skin does not have, so it is
   brought into line with the rest: the picture framed and cornered like
   any other and held to a height that leaves the title on the first
   screen, the title at a post's size and flush with the column, and the
   byline in the engine's voice -- the date in the accent, as everywhere. */
.card.has-hero .post-hero__media img {
  width: 100%;
  max-height: 460px;
  object-fit: cover;
  border-radius: var(--corner);
  border: 1px solid var(--line);
}
.card.has-hero .post-hero__content { padding: 18px 0 0; }
.card.has-hero .post-hero__content h1 {
  margin: 0 0 8px;
  font-size: clamp(27px, 4.4vw, 36px);
  font-weight: 700;
  line-height: 1.15;
  letter-spacing: -0.015em;
}
.card.has-hero .post-hero__meta {
  gap: 4px 14px;
  align-items: baseline;
  font-family: var(--mono);
  font-weight: 700;
  font-size: 12px;
  letter-spacing: 0.06em;
  text-transform: lowercase;
  color: var(--muted);
}
.card.has-hero .post-hero__meta a,
.card.has-hero .post-hero__meta a:hover { order: -1; color: var(--accent); text-decoration: none; }
.card.has-hero .post-hero__meta a:hover { text-decoration: underline; }
.card.has-hero .post-body { padding: 0; }
.card.has-hero .post-body > .post-meta { margin: 8px 0 0; }
.card.has-hero .post-body > .series-note { margin: 10px 0 0; }
.card.has-hero .post-body > .content { margin-top: 18px; padding-top: 4px; border-top: 1px solid var(--line); }
@media (max-width: 700px) {
  .card.has-hero .post-hero__content h1 { font-size: clamp(25px, 7vw, 30px); }
  .card.has-hero .post-hero__media img { max-height: 300px; }
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .post-hero__media img { filter: brightness(0.82); transition: filter 0.2s ease-in-out; }
  :root:not([data-theme="light"]) .post-hero__media img:hover { filter: none; }
}
:root[data-theme="dark"] .post-hero__media img { filter: brightness(0.82); transition: filter 0.2s ease-in-out; }
:root[data-theme="dark"] .post-hero__media img:hover { filter: none; }
/* The contents box floats from above the rule that opens the text there,
   so it is set down clear of it. */
@media (min-width: 701px) {
  .card.has-hero .post-body > .toc { margin-top: 36px; }
}

/* A continuation of the front page -- /page/300/ -- has no heading to
   see, so nothing at its top said it was not the front page. The number
   the engine writes between "newer" and "older" at the foot is lifted to
   the head of the list instead: a stylesheet cannot say it twice, and
   the top is where a reader asks where they are. Listings with a heading
   of their own keep the number at the foot. */
body.page-cont main:has(> .listing-heading--home) { position: relative; padding-top: 34px; }
body.page-cont main:has(> .listing-heading--home) > .pagination > span {
  position: absolute;
  top: 0;
  left: 0;
  color: var(--accent);
}
body.page-cont main:has(> .listing-heading--home) > .post-list-item:first-of-type { border-top: 1px solid var(--line); }

/* A film shot upright is held to about a screen's height and stands in
   the middle of the column; across the full width it came out twelve
   hundred pixels tall, its controls two screens down. One shot on its
   side already fits and is not touched. */
article .content figure video {
  display: block;
  width: auto;
  max-width: 100%;
  max-height: min(78vh, 720px);
  margin: 0 auto;
  background: #000;
}

/* A post with no title -- a toot, a tweet, a photograph -- had a gap in
   its head where the title would be. Its counts stand on the date's own
   line instead. A part of a series keeps the old shape: that line is the
   series' there. */
.card:not(.has-hero) > article > .post-header:not(:has(> .post-body > h1)):not(:has(> .post-body > .series-note)) { padding-top: 0; }
.card:not(.has-hero) > article > .post-header:not(:has(> .post-body > h1)):not(:has(> .post-body > .series-note)) > .post-body > .post-meta {
  margin-top: 0;
  padding-left: 122px;
  min-height: 17px;
}

/* ------------------------------------------------- after the engine of 6. 10.
   The engine began marking what a skin could not select, and put new
   things on three pages. What follows takes those up. */

/* The page that is not there: its field and its pills stand in the middle
   with the sentence above them. */
main > .not-found-search { margin: 22px auto 0; }
main > .not-found-links { margin-top: 22px; text-align: center; }
.not-found-links .tag-pill { margin: 0 3px 6px; }
.not-found-link[hidden] { display: none; }

/* A continuation of the front page has its number at the head of the
   list; the days it covers now come with it, on the same line, quieter.
   The word that marks the page the numbering starts from stays at the
   foot, where the link to older posts would be. */
body.page-cont main:has(> .listing-heading--home) > .pagination > span:not(.pagination-start) {
  text-align: left;
  white-space: nowrap;
}
body.page-cont main:has(> .listing-heading--home) > .pagination .pagination-sep { display: inline; color: var(--muted); }
body.page-cont main:has(> .listing-heading--home) > .pagination .pagination-dates { display: inline; color: var(--muted); }
body.page-cont main:has(> .listing-heading--home) > .pagination > .pagination-start {
  position: static;
  margin-left: auto;
  color: var(--muted);
}
.pagination-dates { margin-top: 2px; }

/* How many a listing holds: beside its name, in the engine's voice. */
.listing-heading__count {
  margin-left: 10px;
  font-family: var(--mono);
  font-weight: 700;
  font-size: 12px;
  letter-spacing: 0.04em;
  vertical-align: baseline;
  opacity: 1;
  color: var(--muted);
}

/* An archive year reads like a tag or a series: the kind in ink, the year
   in the accent. */
.listing-heading--archive .listing-heading__kind ~ .listing-heading__value,
.listing-heading--archive .listing-heading__kind ~ .listing-heading__value .listing-heading__link:hover { color: var(--accent); }

/* On a series' own listing the heading has said the name; each card says
   only which part it is. */
.listing-heading--series ~ .post-list-item .series-note__name,
.listing-heading--series ~ .post-list-item .series-note__sep { display: none; }

/* On a tag's listing every card carries that tag; there it steps back. */
.tag-pill-own { opacity: 0.45; }

/* A count of nothing is not written. */
.post-stat--zero { display: none; }

/* On the cheat sheet, what a source becomes is set off from the prose
   around it by a rule in the accent. */
.md-example { margin: 14px 0 18px; padding-left: 16px; border-left: 2px solid var(--accent); }
.md-example > :first-child { margin-top: 0; }
.md-example > :last-child { margin-bottom: 0; }
/* ...and when all three are nothing, the box that held them leaves the
   row too, or its gap stays behind between the reading time and the tags. */
.post-stats:has(.post-stat):not(:has(.post-stat:not(.post-stat--zero))) { display: none; }

/* "Comments the author chose" over no comments reads as if some were
   missing; the line waits for the first one. */
#comments:not(:has(.comment)) .comments-note { display: none; }

/* By night the archive's lightest month sank into the black beside it and
   read as an empty one; the dark scheme mixes more of the accent into the
   three lower steps, as it does for the tags. Written twice, as the
   palette is. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .archive-month.is-l1 { background: color-mix(in srgb, var(--accent) 26%, var(--paper)); border-color: color-mix(in srgb, var(--accent) 50%, var(--paper)); color: var(--ink); }
  :root:not([data-theme="light"]) .archive-month.is-l2 { background: color-mix(in srgb, var(--accent) 46%, var(--paper)); border-color: transparent; color: var(--ink); }
  :root:not([data-theme="light"]) .archive-month.is-l3 { background: color-mix(in srgb, var(--accent) 72%, var(--paper)); border-color: transparent; color: var(--on-accent); }
}
:root[data-theme="dark"] .archive-month.is-l1 { background: color-mix(in srgb, var(--accent) 26%, var(--paper)); border-color: color-mix(in srgb, var(--accent) 50%, var(--paper)); color: var(--ink); }
:root[data-theme="dark"] .archive-month.is-l2 { background: color-mix(in srgb, var(--accent) 46%, var(--paper)); border-color: transparent; color: var(--ink); }
:root[data-theme="dark"] .archive-month.is-l3 { background: color-mix(in srgb, var(--accent) 72%, var(--paper)); border-color: transparent; color: var(--on-accent); }

/* By night a tag used once was dimmed twice -- the muted grey and then
   three quarters of it -- and sat at the edge of reading. There it keeps
   the grey whole. Written twice, as the palette is. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .tag-index-item[data-count="1"] > .tag-pill { opacity: 1; }
}
:root[data-theme="dark"] .tag-index-item[data-count="1"] > .tag-pill { opacity: 1; }

/* ------------------------------------------------ one heading, everywhere
   A listing is headed the same way wherever it is: what kind of page in
   the display face and ink, the thing itself in the accent, how many in
   small grey type. Three places had gone their own way. */

/* A listing by type has its heading back. It says the word the menu's
   pill says, and it is where the count stands. */
.listing-heading--type {
  position: static;
  width: auto;
  height: auto;
  margin: 0 0 14px;
  overflow: visible;
  clip: auto;
  clip-path: none;
  white-space: normal;
}
main .listing-heading--type ~ .post-list-item:first-of-type { border-top: 1px solid var(--line); }

/* A continuation of the front page: "page 300" is the kind of page, set
   as one, and the days it covers take the count's place and voice. */
body.page-cont main:has(> .listing-heading--home) { padding-top: 49px; }
body.page-cont main:has(> .listing-heading--home) > .pagination > span:not(.pagination-start) {
  font-family: var(--display);
  font-weight: 500;
  font-size: 29px;
  line-height: 1.2;
  letter-spacing: -0.01em;
  text-transform: lowercase;
  color: var(--ink);
}
body.page-cont main:has(> .listing-heading--home) > .pagination .pagination-sep { display: none; }
body.page-cont main:has(> .listing-heading--home) > .pagination .pagination-dates {
  margin: 0 0 0 10px;
  font-family: var(--mono);
  font-weight: 700;
  font-size: 12px;
  letter-spacing: 0.04em;
  color: var(--muted);
}
@media (max-width: 700px) {
  body.page-cont main:has(> .listing-heading--home) { padding-top: 44px; }
  body.page-cont main:has(> .listing-heading--home) > .pagination > span:not(.pagination-start) { font-size: 25px; }
}

/* What a search found is a count like the others, and grey like them. */
.search-status { color: var(--muted); }

/* By night the listing's own tag, dimmed to under a half, was not there
   at all; it keeps more of itself. Written twice, as the palette is. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .tag-pill-own { opacity: 0.7; }
}
:root[data-theme="dark"] .tag-pill-own { opacity: 0.7; }

/* A search that found something says how many beside what was asked, as
   every other listing does. The count is written inside the list of
   results, so that list's box is dissolved and the count flows up beside
   the heading. A search that found nothing keeps its sentence on a line
   of its own, under the two lines on how to search. */
main:has(.search-result) > .listing-heading--search { display: inline-block; margin-right: 10px; }
main:has(.search-result) > #search-results { display: contents; }
main:has(.search-result) .search-status { display: inline; margin: 0; letter-spacing: 0.04em; }
main:has(.search-result) .search-result:first-of-type { border-top: 1px solid var(--line); }
/* The field and the pills are one thing -- the ways on -- so no rule runs
   between them. */
main > .not-found-links { margin-top: 16px; padding-top: 0; border-top: 0; }

/* On the cheat sheet a source is a filled plate and what it becomes is an
   outline of the same shape under it. The rule in the accent that marked
   a result stood beside a quotation's own and doubled it; an outline
   leaves the accent to what wears it on the site. */
.md-example {
  margin: 10px 0 20px;
  padding: 14px 16px;
  border: 1px solid var(--line);
  border-left: 1px solid var(--line);
  border-radius: var(--corner);
  background: none;
}

/* The claim breaks into lines of a like length, so a narrow screen does not
   leave its last word alone on a line. */
.banner-claim { text-wrap: balance; }

/* The pin is written before the date, and is shown after it: centred under the
   date on a wide screen, so the date stays level with the title as on every other
   card, and beside it on a narrow one. */
.post-list-item .date-badge.is-pinned {
  display: grid;
  grid-template-columns: max-content;
  justify-items: center;
}
.post-list-item .date-badge.is-pinned .pin-mark { order: 1; }
@media (max-width: 560px) {
  .post-list-item .date-badge.is-pinned { display: flex; align-items: center; }
}

/* The sidebar's rows, shortened. A toot's address is the short form Mastodon
   sends with it, on one line, so the text and the hashtags keep the room; a
   commit's message is three lines, not four. */
#last-toots .invisible { display: none; }
#last-toots .ellipsis::after { content: "\2026"; }
#last-toots .last-content a:has(> .ellipsis) {
  display: block;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
#last-commits .last-content { -webkit-line-clamp: 3; }

/* Two abreast under the content, the boxes go left, right, left, right in
   the order the sidebar has them, and each sits right under the one above it
   on its side: floats, the odd ones to the left and the even to the right,
   each clearing its own side only. */
@media (min-width: 561px) and (max-width: 860px) {
  aside { display: flow-root; column-count: auto; }
  aside > .card { width: calc((100% - 24px) / 2); }
  aside > .card:nth-child(odd) { float: left; clear: left; }
  aside > .card:nth-child(even) { float: right; clear: right; }
}

/* Where the sidebar has gone under the content, the text runs as wide as the
   pictures do: held to its measure it left an empty strip beside every
   paragraph, and the page two right-hand edges. */
@media (max-width: 860px) {
  .content > p,
  .content > ul,
  .content > ol,
  .content > blockquote,
  .content > dl { max-width: none; }
}

/* After the engine of 8. 10. -- what it now marks, said the skin's way. */

/* A page of the listing: the word in ink, the number as the thing a heading
   names is everywhere -- the text face, 21px, in the accent -- as a
   year of the archive and a tag are. */
body.page-cont main:has(> .listing-heading--home) > .pagination > span:not(.pagination-start) .pagination-number {
  font-family: var(--ui);
  font-size: 21px;
  font-weight: 600;
  letter-spacing: 0;
  text-transform: none;
  color: var(--accent);
}

/* The search's count stands beside the query as a number alone; the word
   stays for a screen reader. What was asked for is tinted where it was found. */
.search-unit {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}
.search-result mark {
  background: color-mix(in srgb, var(--accent) 24%, transparent);
  color: inherit;
  border-radius: 3px;
  padding: 0 2px;
}

/* A mention in a post's own text, as in a comment and a toot. */
.content a.mention { color: var(--accent); text-decoration: none; }
.content a.mention:hover { text-decoration: underline; }

/* The author among the replies wears the accent round the picture. */
.comment--author .comment-avatar {
  border-color: var(--accent);
  box-shadow: 0 0 0 1px var(--accent);
}

/* The labels of the rows that jump, and the legend's two words, are labels. */
.archive-jump__label,
.tag-index-jump__label,
.archive-legend__word {
  font-family: var(--mono);
  font-size: 12px;
  letter-spacing: 0.06em;
  text-transform: lowercase;
  color: var(--muted);
}

/* With a language switch in the head a phone has no room for the name's
   cursor: the switch stood on it. Up to 430px the cursor is left out there. */
@media (max-width: 430px) {
  .banner-wrap:has(.lang-switch) .banner-title::after { content: none; }
}

/* The row under a card on one axis. The reading time was a block set on the
   text's baseline and the numbers from the network a row that centres its
   own icons, so the two groups stood at two heights. Now the reading time
   centres its icon as the others do, and the row centres all of it. */
.post-stat.reading-time { display: inline-flex; align-items: center; }
.post-list-item .post-body > .post-meta > *,
.post-list-item .post-body > .tags > * { align-self: center; }

/* The lead. The post that opens the front page -- the pinned one where
   there is one, the newest where there is none -- is the one row of a
   listing that is not an open row: it stands on a ground of its own, its
   title is set large, its date goes above the title instead of beside it,
   and its opening words run to five lines instead of three.

   It is told by its place, the first post of the first page of the front
   page, and not by the engine's post-list-item--lead alone: the engine
   gives that class (layout.lead_card) only to a post with a picture to
   lead with, and a blog's newest post is the lead whether it has one or
   not. Where the engine did lift a picture, it is shown.

   The ground is the site's accent laid thin over the paper -- twelve parts
   in a hundred by day, ten by night -- so it is the paper a step warmer
   and not a second colour, and it follows a site that says another accent.
   No hairline round it; the tone is the edge. */
:root,
:root[data-theme="light"] { --lead-ground: color-mix(in srgb, var(--accent) 12%, var(--paper)); }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) { --lead-ground: color-mix(in srgb, var(--accent) 10%, var(--paper)); }
}
:root[data-theme="dark"] { --lead-ground: color-mix(in srgb, var(--accent) 10%, var(--paper)); }

/* Under it, air: fifty-four pixels to the next date, against forty-one
   between two rows, and no hairline, so the listing is seen to begin below
   the lead and the lead is not read as its first row. */
body.page-first main:has(> .listing-heading--home) > .post-list-item:is(.post-list-item--lead, :first-of-type) {
  margin: 18px 0 34px;
  padding: 24px 26px 22px;
  border: 0;
  border-radius: 14px;
  background: var(--lead-ground);
}
body.page-first main:has(> .listing-heading--home) > .post-list-item:is(.post-list-item--lead, :first-of-type) + .post-list-item { border-top: 0; }
/* From 561px up, which is where a row stops stacking by itself: below that
   the date is above the title already. */
@media (min-width: 561px) {
  body.page-first main:has(> .listing-heading--home) > .post-list-item:is(.post-list-item--lead, :first-of-type) .post-header { display: block; }
  body.page-first main:has(> .listing-heading--home) > .post-list-item:is(.post-list-item--lead, :first-of-type) .date-badge { margin: 0 0 10px; }
}
body.page-first main:has(> .listing-heading--home) > .post-list-item:is(.post-list-item--lead, :first-of-type) .post-body > h2 {
  font-size: clamp(26px, 3.3vw, 36px);
  line-height: 1.1;
  letter-spacing: -0.015em;
  margin: 0 0 10px;
  text-wrap: balance;
}
body.page-first main:has(> .listing-heading--home) > .post-list-item:is(.post-list-item--lead, :first-of-type) .content > figure:first-child { margin: 12px 0 16px; }
body.page-first main:has(> .listing-heading--home) > .post-list-item:is(.post-list-item--lead, :first-of-type) .content > figure:first-child figcaption { display: none; }
body.page-first main:has(> .listing-heading--home) > .post-list-item:is(.post-list-item--lead, :first-of-type) .content > p:first-of-type { -webkit-line-clamp: 5; font-size: 17px; line-height: 1.6; opacity: 0.88; }
@media (max-width: 700px) {
  /* Ten pixels into the gutter on each side, so the words inside keep the
     edge the rest of the page reads from. */
  body.page-first main:has(> .listing-heading--home) > .post-list-item:is(.post-list-item--lead, :first-of-type) { margin: 16px -10px 28px; padding: 16px 10px 14px; }
  body.page-first main:has(> .listing-heading--home) > .post-list-item:is(.post-list-item--lead, :first-of-type) .post-body > h2 { margin-bottom: 8px; }
  body.page-first main:has(> .listing-heading--home) > .post-list-item:is(.post-list-item--lead, :first-of-type) .content > figure:first-child { margin: 4px 0 12px; }
  body.page-first main:has(> .listing-heading--home) > .post-list-item:is(.post-list-item--lead, :first-of-type) .content > p:first-of-type { font-size: 16px; line-height: 1.55; }
}

/* A lead with no picture has room, and takes it: it shows everything the
   engine put in its card -- the teaser the author wrote, or as much of the
   opening as the engine's own budget for a card lets through -- as whole
   paragraphs, not five clamped lines. How long that is, is the engine's and
   the author's to say, not a count in this file. A heading the cut happened
   to end on is left out, since nothing follows it; and because whole
   paragraphs do not trail off, the way on to the rest is said in words. */
body.page-first main:has(> .listing-heading--home) > .post-list-item:is(.post-list-item--lead, :first-of-type):not(:has(.content > figure:first-child, .content > .photo-grid:first-child)) .content > * { display: block; margin: 0 0 12px; }
body.page-first main:has(> .listing-heading--home) > .post-list-item:is(.post-list-item--lead, :first-of-type):not(:has(.content > figure:first-child, .content > .photo-grid:first-child)) .content > :last-child { margin-bottom: 0; }
body.page-first main:has(> .listing-heading--home) > .post-list-item:is(.post-list-item--lead, :first-of-type):not(:has(.content > figure:first-child, .content > .photo-grid:first-child)) .content > p,
body.page-first main:has(> .listing-heading--home) > .post-list-item:is(.post-list-item--lead, :first-of-type):not(:has(.content > figure:first-child, .content > .photo-grid:first-child)) .content > p:first-of-type { display: block; overflow: visible; font-size: 16.5px; line-height: 1.6; opacity: 0.88; -webkit-line-clamp: none; }
body.page-first main:has(> .listing-heading--home) > .post-list-item:is(.post-list-item--lead, :first-of-type):not(:has(.content > figure:first-child, .content > .photo-grid:first-child)) .content > .photo-grid { display: grid; }
body.page-first main:has(> .listing-heading--home) > .post-list-item:is(.post-list-item--lead, :first-of-type):not(:has(.content > figure:first-child, .content > .photo-grid:first-child)) .content > table { display: table; }
body.page-first main:has(> .listing-heading--home) > .post-list-item:is(.post-list-item--lead, :first-of-type):not(:has(.content > figure:first-child, .content > .photo-grid:first-child)) .content > blockquote { }
body.page-first main:has(> .listing-heading--home) > .post-list-item:is(.post-list-item--lead, :first-of-type):not(:has(.content > figure:first-child, .content > .photo-grid:first-child)) .content > :is(h1, h2, h3, h4, h5, h6, hr):last-child { display: none; }
body.page-first main:has(> .listing-heading--home) > .post-list-item:is(.post-list-item--lead, :first-of-type):not(:has(.content > figure:first-child, .content > .photo-grid:first-child)) .read-more {
  /* one of the row it stands in: the engine's voice, the row's size, on the
     row's own axis */
  display: inline-block; order: 5; flex: 0 0 auto; align-self: center; margin: 0; color: var(--ink);
  font-family: var(--mono); font-size: 12px; font-weight: 700; letter-spacing: 0.05em; line-height: 1.2; text-transform: lowercase;
  text-decoration: underline; text-decoration-color: var(--accent); text-decoration-thickness: 1.5px; text-underline-offset: 3px;
}
body.page-first main:has(> .listing-heading--home) > .post-list-item:is(.post-list-item--lead, :first-of-type):not(:has(.content > figure:first-child, .content > .photo-grid:first-child)) .read-more:hover { color: var(--accent); }
@media (max-width: 700px) {
  body.page-first main:has(> .listing-heading--home) > .post-list-item:is(.post-list-item--lead, :first-of-type):not(:has(.content > figure:first-child, .content > .photo-grid:first-child)) .content > p,
  body.page-first main:has(> .listing-heading--home) > .post-list-item:is(.post-list-item--lead, :first-of-type):not(:has(.content > figure:first-child, .content > .photo-grid:first-child)) .content > p:first-of-type { font-size: 16px; line-height: 1.55; }
}

/* A pinned lead says so before its date: the pin, plain and in the accent,
   the size of the date it stands beside. It is the answer to the question a
   reader would otherwise have -- why a post months old is the first thing on
   the page -- and a lead that is simply the newest post has none. */
body.page-first main:has(> .listing-heading--home) > .post-list-item:is(.post-list-item--lead, :first-of-type) .date-badge.is-pinned { display: flex; align-items: center; justify-items: start; gap: 6px; }
body.page-first main:has(> .listing-heading--home) > .post-list-item:is(.post-list-item--lead, :first-of-type) .date-badge.is-pinned .pin-mark,
body.page-first main:has(> .listing-heading--home) > .post-list-item:is(.post-list-item--lead, :first-of-type) .date-badge.is-pinned:hover .pin-mark { display: inline-flex; order: -1; width: 14px; height: 14px; margin: 0; border-radius: 0; background: none; color: var(--accent); }
body.page-first main:has(> .listing-heading--home) > .post-list-item:is(.post-list-item--lead, :first-of-type) .date-badge.is-pinned .pin-mark svg { display: block; width: 14px; height: 14px; }

/* ---- manual: the layer over minimal ----------------------------------- */

:root { --contents: 250px; --page: 700px; --bar: 86px; }

/* ------------------------------------------------------------- a page

   A post with sections is a page of the manual. Its contents stand to the
   right of the text and stay on the screen while the text moves, so a
   reader always sees where in the page they are and can jump. What minimal
   keeps beside a post goes under it on such a page, three cards across:
   beside a manual's text there is room for one thing, and it is the
   contents. A post with no sections has no contents and keeps minimal's
   shape. Under nine hundred pixels the contents are a block over the text,
   as in minimal. */
@media (min-width: 901px) {
  .layout:has(article .toc) { display: block; }
  .layout:has(article .toc) > aside { margin-top: 56px; padding-top: 30px; border-top: 1px solid var(--line); columns: 3 280px; column-gap: 28px; }
  .layout:has(article .toc) > aside > .card { margin: 0 0 22px; break-inside: avoid; }
  .card:is(.has-hero, :not(.has-hero)) > article > .post-header > .post-body:has(> .toc) {
    display: grid;
    grid-template-columns: minmax(0, var(--page)) var(--contents);
    justify-content: space-between;
    column-gap: 56px;
    align-items: start;
  }
  .card:is(.has-hero, :not(.has-hero)) > article > .post-header > .post-body:has(> .toc) > * { grid-column: 1; min-width: 0; }
  .card:is(.has-hero, :not(.has-hero)) > article > .post-header > .post-body:has(> .toc) > .toc {
    grid-column: 2;
    grid-row: 1 / span 40;
    position: sticky;
    top: var(--bar);
    float: none;
    width: auto;
    max-height: calc(100vh - var(--bar) - 24px);
    margin: 4px 0 0;
    padding: 0 0 0 18px;
    overflow-y: auto;
    border: 0;
    border-left: 1px solid var(--line);
    border-radius: 0;
    background: none;
  }
}

/* The text of a page runs to the right edge of its column, where its
   pictures, its tables and its code end; the column is the measure. */
.card:is(.has-hero, :not(.has-hero)) > article > .post-header > .post-body:has(> .toc) > .content > * { max-width: none; }

/* The contents and the sections are numbered alike, by the stylesheet: the
   first section is 1 in the list and 1 over its text, and a section inside
   it is 1.1 in both. The number is the engine's voice, in the accent. */
.toc ol { margin: 8px 0 0; padding: 0; list-style: none; counter-reset: toc-a; }
.toc li { margin: 0; padding: 4px 0; font-size: 14px; line-height: 1.35; }
.toc li::before { display: inline-block; min-width: 2.2em; color: var(--accent); font-family: var(--mono); font-size: 12px; font-weight: 700; }
.toc li.toc-l2 { counter-increment: toc-a; counter-reset: toc-b; }
.toc li.toc-l2::before { content: counter(toc-a); }
.toc li:not(.toc-l2) { counter-increment: toc-b; padding-left: 14px; font-size: 13px; }
.toc li:not(.toc-l2)::before { content: counter(toc-a) "." counter(toc-b); min-width: 2.8em; }

article .content { counter-reset: sec-a; }
article .content > h2 { counter-increment: sec-a; counter-reset: sec-b; }
article .content > h3 { counter-increment: sec-b; }
article .content > h2::before,
article .content > h3::before { margin-right: 0.6em; color: var(--accent); font-family: var(--mono); font-size: 0.72em; font-weight: 700; letter-spacing: 0.02em; vertical-align: 0.08em; }
article .content > h2::before { content: counter(sec-a); }
article .content > h3::before { content: counter(sec-a) "." counter(sec-b); }

/* A section opens under a hairline, with air over it: a manual is looked
   things up in, and where a section starts has to be found at a glance.
   Headings are in the ink; the accent on them is their number. When a
   heading is jumped to, it stops under the menu, not behind it. */
article .content > :is(h2, h3) { color: var(--ink); scroll-margin-top: var(--bar); }
article .content > h2 { margin-top: 2.2em; padding-top: 1.1em; border-top: 1px solid var(--line); font-size: 1.45rem; }
article .content > h3 { margin-top: 1.7em; font-size: 1.12rem; }

/* A note is set apart from the text: a plate with the accent down its left
   edge. (The engine has one way of setting words apart, the quotation, and
   in a manual that is what it is used for.) */
article .content blockquote {
  margin: 1.3em 0;
  padding: 12px 16px;
  border: 0;
  border-left: 3px solid var(--accent);
  border-radius: 0 var(--corner) var(--corner) 0;
  background: var(--plate);
  font-size: 0.95em;
}
article .content blockquote > :first-child { margin-top: 0; }
article .content blockquote > :last-child { margin-bottom: 0; }

/* A link that leads off the site says so: a small arrow after it, in the
   accent. In a manual it matters whether a link is the next page or another
   place altogether. A stylesheet tells the two apart by the address alone:
   a link written with its protocol leads out, one written from the root
   stays. (A link to the site's own pages written in full is marked too;
   the engine writes its own links from the root.) */
article .content a:is([href^="http://"], [href^="https://"]):not(:has(img))::after { content: "\2197"; margin-left: 0.15em; color: var(--accent); font-family: var(--mono); font-size: 0.72em; font-weight: 700; vertical-align: 0.25em; text-decoration: none; display: inline-block; }

/* A table is ruled in full and takes the column's width: in a manual it is
   read across and down. */
article .content table { width: 100%; border-collapse: collapse; font-size: 0.9em; }
article .content :is(th, td) { padding: 7px 10px; border: 1px solid var(--line); text-align: left; vertical-align: top; }

/* The way on. At the foot of a page the page before and the page after are
   two cards side by side, as wide as the text, the next one on the right. */
article .series-nav { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; margin-top: 36px; }
article .series-nav a,
article .series-nav a:hover { display: block; max-width: none; padding: 14px 16px; border: 1px solid var(--line); border-radius: var(--corner); background: var(--plate); color: var(--ink); font-family: var(--ui); font-size: 15px; font-weight: 600; line-height: 1.35; letter-spacing: 0; text-transform: none; white-space: normal; }
article .series-nav a:hover { border-color: var(--accent); color: var(--accent); }
article .series-nav .series-next { grid-column: 2; text-align: right; }
article .series-nav .series-prev { grid-column: 1; }

/* The date of a page says when it was written, not what it is: muted. */
.card:not(.has-hero) > article > .post-header > .date-badge,
.card:not(.has-hero) > article > .post-header > .date-badge:hover { color: var(--muted); }

/* --------------------------------------------------------- the contents

   A listing is a table of contents: rows closer together than minimal's,
   each a title, two lines of what it is about, and the line of what the
   engine knows -- which part of which series first. */
main .post-list-item { padding: 14px 0; }
.post-list-item .content > p:first-child { -webkit-line-clamp: 2; }
.post-list-item .series-note { order: 4; flex: 0 0 auto; align-self: center; }
/* The date is where minimal literal has it: not in a margin of its own but
   in the row's line of what the engine knows, under the excerpt, in the
   engine's voice and the accent. A table of contents is read by its titles;
   the day a page was written is one of the facts about it. The lead keeps
   minimal's shape. */
main > .post-list-item:not(:where(body.page-first main:has(> .listing-heading--home) > :is(.post-list-item--lead, :first-of-type))) .post-header {
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 7px 14px;
}
main > .post-list-item:not(:where(body.page-first main:has(> .listing-heading--home) > :is(.post-list-item--lead, :first-of-type))) .post-body { display: contents; }
main > .post-list-item:not(:where(body.page-first main:has(> .listing-heading--home) > :is(.post-list-item--lead, :first-of-type))) .date-badge {
  order: 5;
  flex: 0 0 auto;
  width: auto;
  padding: 0;
}

/* The list of series is the list of chapters. The years a series ran say
   nothing about a chapter, so they are not shown; its name and how many
   pages it has are. */
.series-index-years { display: none; }
/* Chapters are numbered as sections are: by the stylesheet, the number in
   the engine's voice and in the accent, the name in the ink. The engine
   lists the series whose newest page is newest first, so the numbers follow
   the manual's order when its first chapter holds its newest pages. */
.series-index { counter-reset: chapter; }
.series-index-item { counter-increment: chapter; }
.series-index-item::before { content: counter(chapter); display: inline-block; min-width: 2.4em; color: var(--accent); font-family: var(--mono); font-size: 13px; font-weight: 700; letter-spacing: 0.02em; }
.series-index-name,
.series-index-name:hover { color: var(--ink); }
.series-index-name:hover { text-decoration: underline; text-decoration-color: var(--accent); text-decoration-thickness: 2px; text-underline-offset: 4px; }

@media (max-width: 700px) {
  article .series-nav { grid-template-columns: minmax(0, 1fr); }
  article .series-nav .series-next,
  article .series-nav .series-prev { grid-column: 1; }
}

/* ------------------------------------------------------------ the menu

   A manual's menu is its list of chapters -- what the site writes under
   `nav:` in its settings, each entry a series or a tag. On a wide screen it
   stands to the left of the page and stays there: search first, then the
   chapters one under another, the one being read filled with the accent.
   The page is then three things side by side: the chapters, the text, and
   the contents of the page. The line in the accent that minimal draws under
   its menu is drawn under the head instead, across the whole page. What
   minimal keeps beside the content goes under it, on every page. Under
   eleven hundred pixels the menu is minimal's row under the head. */
@media (min-width: 1100px) {
  :root { --menu: 184px; --contents: 200px; --page: 560px; --bar: 22px; }
  html { scroll-padding-top: 22px; }
  .wrap { display: grid; grid-template-columns: var(--menu) minmax(0, 1fr); column-gap: 44px; align-items: start; }
  .wrap > * { grid-column: 1 / -1; }
  .wrap > .banner-wrap { margin-bottom: 26px; padding-bottom: 18px; border-bottom: 2px solid var(--accent); }
  .wrap > nav,
  .wrap > .layout { grid-row: 2; }
  .wrap > .layout,
  .wrap > .layout:has(article .toc) { grid-column: 2; display: block; }
  .wrap > .layout > aside { margin-top: 56px; padding-top: 30px; border-top: 1px solid var(--line); columns: 2 280px; column-gap: 28px; }
  .wrap > .layout > aside > .card { margin: 0 0 22px; break-inside: avoid; }

  .wrap > nav {
    grid-column: 1;
    position: sticky;
    top: 22px;
    display: flex;
    flex-direction: column;
    align-items: stretch;
    gap: 14px;
    max-height: calc(100vh - 44px);
    margin: 0;
    padding: 0;
    overflow-y: auto;
    border: 0;
    background: none;
  }
  .wrap > nav .search-form { order: -1; flex: 0 0 auto; width: 100%; min-width: 0; max-width: none; margin: 0; }
  .wrap > nav .search-form input[type="search"] { width: 100%; }
  .wrap > nav ul { display: flex; flex-direction: column; flex-wrap: nowrap; gap: 2px; width: 100%; overflow: visible; }
  .wrap > nav li { width: 100%; font-size: 13px; text-transform: none; }
  /* a chapter is a row, not a pill: its name from the left, as written */
  .wrap > nav a,
  .wrap > nav li:last-child a { display: block; padding: 7px 10px; border: 0; border-radius: 8px; color: var(--ink); font-family: var(--ui); font-size: 14.5px; font-weight: 400; letter-spacing: 0; line-height: 1.3; white-space: normal; }
  .wrap > nav a:hover { background: var(--plate); color: var(--accent); }
  .wrap > nav a[aria-current="page"],
  .wrap > nav li:first-child a[aria-current="page"],
  .wrap > nav a[aria-current="page"]:hover { padding: 7px 10px; margin: 0; background: var(--accent); color: var(--on-accent); font-weight: 600; }
}
