/* type.css — generated by scripts/type-build.mjs from src/type/metrics.json and
   src/type/config.json. Edit those and run `npm run type`, not this file. */

html.type {
  font-size: var(--base);
  line-height: round(nearest, calc(var(--rho) * 1rem), 1px);
  /* An explicit ratio, not from-font: from-font resolves per element, so it
     would leave the mono face at its own x-height instead of matching body. */
  font-size-adjust: var(--x);
}
/* Whole CSS pixels only. A half-pixel line height looks crisper at 2x but
   Safari truncates line boxes to whole pixels while `rlh` stays fractional,
   so text drifts off the grid by half a pixel per line. */
@media (width < 45em) {
  html.type { line-height: round(nearest, calc(var(--rho-narrow) * 1rem), 1px); }
  /* A 3-line-high h1 is ~87px on a phone, wider than the column for words like
     "company"; two lines is ~58px. */
  html.type { --h1-n: 2; }
}
/* Backstop for a word that is still too wide. */
html.type .post-header h1,
html.type .page-title,
html.type .tag-archive-title { hyphens: auto; overflow-wrap: anywhere; }
/* schibsted-grotesk instead of the site's Figtree; the numbers above were
   measured from it. */
html.type { --font-sans: 'Schibsted Grotesk', 'Helvetica Neue', Helvetica, Arial, sans-serif; }
/* Mono: JetBrains Mono, so the code baseline maths match what is shown. */
html.type { --font-mono: 'JetBrains Mono', Menlo, ui-monospace, 'SF Mono', Monaco, monospace; }
html.type body {
  font-size: 1rem;
  line-height: inherit;
}

/* Column: width from the measure; top padding a whole number of lines so the
   article starts on the grid. */
html.type :is(article.post, article.page:not(.reviews, .poker, .specimen), section.page, .home-feed, .archives, .tag-archive) {
  max-width: calc(var(--measure) + 2 * var(--gutter) + var(--col-extra, 0px));
  padding-top: 7rlh;
}

/* Below 720px style.css makes the brand and nav static, so they push the
   article down by their own px height (112px: 32 + 40 avatar, 8 + 40 nav).
   Top up to a whole number of lines so the article still starts on the grid.
   Stage 4 should size that chrome in rlh and drop this. */
@media (max-width: 720px) {
  html.type :is(article.post, article.page:not(.reviews, .poker, .specimen), section.page, .home-feed, .archives, .tag-archive) { margin-top: calc(round(up, 112px, 1rlh) - 112px); }
}

/* Headings, subtitle and date: size falls out of the grid. A heading of k
   lines is exactly k·n rlh tall. */
html.type .post-header h1,
html.type .page-title,
html.type .tag-archive-title { --n: var(--h1-n); --lambda: var(--h1-lambda); font-weight: var(--h1-weight); }
html.type .prose h2 { --n: var(--h2-n); --lambda: var(--h2-lambda); font-weight: var(--h2-weight); }
html.type .prose h3,
html.type .excerpt-title,
html.type p.post-subtitle,
html.type p.post-date { --n: var(--h3-n); --lambda: var(--h3-lambda); }

html.type .post-header h1,
html.type .page-title,
html.type .tag-archive-title,
html.type .excerpt-title,
html.type .prose h2,
html.type .prose h3,
html.type p.post-subtitle,
html.type p.post-date,
html.type .tax p.tx-big {
  font-size: calc(var(--n) * 1rlh / var(--lambda));
  line-height: calc(var(--n) * 1rlh);
  /* Baseline of the heading's first line within its box. */
  --bh: calc(var(--n) * 0.5rlh + (var(--a) - var(--d)) / 2 * var(--n) * 1rlh / var(--lambda));
  /* Smallest shift (up or down) that puts it back on the body baseline. */
  --delta: calc(mod(var(--beta) - var(--bh) + 0.5rlh, 1rlh) - 0.5rlh);
  translate: 0 var(--delta);
}
html.type .post-header h1,
html.type .page-title,
html.type .tag-archive-title { margin: 0 0 1rlh; }
html.type p.post-subtitle { margin: 0 0 1rlh; }
/* The rule under the date is drawn by the header, not by the date: the date
   is translated for its baseline correction and would carry the rule off the
   grid with it. */
html.type p.post-date {
  margin: 0;
  padding-bottom: 0;
  box-shadow: none;
}
html.type .post-header::after {
  --step: var(--step-date);
  content: "";
  display: block;
  height: 1rlh;
  margin-bottom: 1rlh;
  box-shadow: inset 0 -1px 0 currentColor;
  color: color-mix(in srgb, var(--fg) clamp(0%, calc((var(--tone-start) - var(--tone-step) * var(--step)) * 100%), 100%), var(--bg));
}
/* The tool page goes straight from title to results, with no rule between. The space stays. */
html.type .tax .post-header::after { box-shadow: none; }
html.type .prose h2,
html.type .prose h3 { margin: 2rlh 0 1rlh; }
html.type .prose h2:first-child,
html.type .prose h3:first-child { margin-top: 0; }

/* h4 stays body-sized. */
/* Browsers make <strong> "bolder" than its parent, which from a body weight of
   550 lands on 900. Step up a fixed amount instead. */
html.type .prose :is(p, li, td, blockquote) :is(strong, b) {
  font-weight: clamp(1, calc(var(--body-weight) + var(--strong-step)), 1000);
}
html.type { --strong-step: 150; }

html.type .prose h4 {
  font-size: 1rem;
  line-height: 1rlh;
  margin: 1rlh 0;
}

/* Tone. mix(fg, bg) rather than opacity, so borders and underlines drawn in
   currentColor soften with the text. Clamped so a slider overshoot cannot
   invalidate the declaration. */
html.type .post-header h1 { --step: var(--step-h1); }
html.type p.post-subtitle { --step: var(--step-subtitle); }
html.type .prose h2 { --step: var(--step-h2); }
html.type .prose h3 { --step: var(--step-h3); }
html.type p.post-date { --step: var(--step-date); }
html.type .prose p,
html.type .prose li { --step: var(--step-body); }

html.type .post-header h1,
html.type p.post-subtitle,
html.type .prose h2,
html.type .prose h3,
html.type p.post-date,
html.type .prose p,
html.type .prose li {
  color: color-mix(in srgb, var(--fg) clamp(0%, calc((var(--tone-start) - var(--tone-step) * var(--step)) * 100%), 100%), var(--bg));
}
@media (prefers-color-scheme: dark) {
  html.type {
    --tone-start: var(--tone-start-dark);
    --tone-step: var(--tone-step-dark);
    /* Further from the black background than style.css's 24%. */
    --code-bg: color-mix(in srgb, var(--fg) 28%, transparent);
    /* Light type on black looks heavier, so mono is a touch lighter. */
    --mono-weight: 480;
  }
}

/* Body. */
html.type .prose p,
html.type .prose li {
  font-size: 1rem;
  line-height: 1rlh;
  font-weight: var(--body-weight);
}
html.type .prose p { margin: 0 0 1rlh; }
html.type .prose ul,
html.type .prose ol { margin: 0 0 1rlh; }
html.type .prose li { margin-bottom: 1rlh; }
html.type .prose li:last-child { margin-bottom: 0; }
html.type .prose blockquote { margin: 1rlh 0; }
html.type .prose blockquote p:last-child { margin: 0; }
/* Quote: set in the note serif, italic, indented, no rule. Own size, so the
   baseline correction is the note one with --quote-size in place of --note-size;
   the source (<cite>) goes on its own line, upright. */
html.type {
  --quote-size: 1.1rem;
  --quote-translate: calc(var(--beta) - (0.5rlh + (var(--a-note) - var(--d-note)) / 2 * var(--note-scale) * var(--quote-size)));
}
html.type .prose blockquote { border: 0; padding-left: 1.5rem; }
html.type .prose blockquote p {
  font-family: var(--note-font);
  font-size: var(--quote-size);
  font-weight: var(--note-weight);
  font-style: italic;
  line-height: 1rlh;
  translate: 0 var(--quote-translate);
}
/* Source line: the caption label style (small uppercase sans). Its translate is
   the label correction less the quote's own, which it inherits through the <p>. */
html.type .prose blockquote cite {
  display: block;
  font-family: var(--font-sans);
  font-style: normal;
  font-size: 12px;
  font-weight: 400;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  translate: 0 calc((var(--a) - var(--d)) / 2 * (1rem - 12px) - var(--quote-translate));
}

/* Inline hazards: nothing inline may grow the line box. */
html.type .prose sup,
html.type .prose sub {
  line-height: 0;
  position: relative;
  vertical-align: baseline;
}
html.type .prose sup { top: -0.5em; }
html.type .prose sub { top: 0.3em; }
html.type .prose code { font-size: 1em; line-height: 0; }
html.type code, html.type pre { font-weight: var(--mono-weight, inherit); }

/* Figures. The build gives each image its pixel size (--iw, --ih); its height
   is rounded to a whole number of lines, cropping at most half a line, so the
   text after it stays on the grid. 100cqw is the column width. */
html.type .prose { container-type: inline-size; }
html.type .prose :is(figure:not(.margin), p) > :is(img, video)[style*="--iw"] {
  width: min(100cqw, calc(var(--iw) * 1px));
  height: max(1rlh, round(calc(min(100cqw, var(--iw) * 1px) * var(--ih) / var(--iw)), 1rlh));
  object-fit: cover;
}
/* An image alone in a paragraph: the paragraph supplies the spacing. */
html.type .prose p > img { margin: 0; }
/* Fixed-height players: block, so there is no baseline gap, rounded up. */
html.type .prose iframe[style*="--ih"] {
  display: block;
  margin: 1rlh 0;
  height: round(up, calc(var(--ih) * 1px), 1rlh) !important;
}
/* Embeds are 16:9 boxes; round their height the same way. */
html.type .prose .video-embed { padding-bottom: 0; margin: 1rlh 0; height: round(calc(100cqw * 9 / 16), 1rlh); }
/* Not figure.margin: the reviews pages float those into the right margin with a negative margin-right, which this would reset. */
html.type .prose figure:not(.margin) { margin: 1rlh 0; }
html.type .prose figure figcaption {
  line-height: 1rlh;
  margin-top: 0;
  translate: 0 calc((var(--a) - var(--d)) / 2 * (1rem - 12px));
}
/* Not images inside a figure, which style.css keeps flush with the caption. */
html.type .prose img:not(figure img),
html.type .prose video { margin: 1rlh 0; }

/* Rule: a whole line tall, hairline drawn rather than bordered. */
html.type .prose hr {
  border: 0;
  height: 1rlh;
  margin: 1rlh 0;
  /* Same tone as the rule under the post header. */
  --step: var(--step-date);
  color: color-mix(in srgb, var(--fg) clamp(0%, calc((var(--tone-start) - var(--tone-step) * var(--step)) * 100%), 100%), var(--bg));
  background: linear-gradient(currentColor 0 1px, transparent 1px) center / 100% 1px no-repeat;
}

/* Code blocks: the 1px border is taken back out of the padding so the block
   stays a whole number of lines. Mono glyphs shift to the body baseline. */
html.type .prose pre {
  font-size: 1em;
  line-height: 1rlh;
  padding-block: calc(1rlh - 1px);
  margin: 1rlh 0;
}
html.type .prose pre code {
  display: block;
  line-height: 1rlh;
  /* Baseline of a mono line, using the mono face's own ascent and descent at
     its x-height-matched size. */
  --beta-mono: calc(0.5rlh + (var(--a-mono) - var(--d-mono)) / 2 * var(--mono-scale) * 1rem);
  translate: 0 calc(var(--beta) - var(--beta-mono));
}

/* Footnotes: smaller text, same line height, baseline shifted back. */
html.type .prose .footnotes {
  margin-top: 2rlh;
  padding-top: calc(1rlh - 1px);
}
html.type {
  --note-font: 'Newsreader', Georgia, serif;
  /* Baseline of a note line using the note face's own ascent and descent at its
     scaled size, taken back to the body baseline. */
  --note-translate: calc(var(--beta) - (0.5rlh + (var(--a-note) - var(--d-note)) / 2 * var(--note-scale) * var(--note-size)));
}
/* The note text sits in a <p>; without this the body-paragraph rule sets it at
   full body size and weight and the note size above never shows. */
html.type .prose .footnotes li p { font-size: inherit; font-weight: inherit; margin: 0; }
html.type .prose .footnotes li p + p { margin-top: 1rlh; }
html.type .prose .footnotes li {
  font-family: var(--note-font);
  font-size: var(--note-size);
  line-height: 1rlh;
  font-weight: var(--note-weight);
  translate: 0 var(--note-translate);
}

/* Footnote reference: a small raised number, no brackets or underline. The
   marker keeps line-height 0 (above) so it cannot grow the line box. */
html.type .prose .footnote-ref { font-size: 0.7em; font-weight: 700; margin-left: 0.1em; }
html.type .prose .footnote-ref a { text-decoration: none; padding: 0 0.3em; margin: 0 -0.3em; }

/* Sidenotes: on wide screens the footnote text sits in the right margin, level
   with its reference, and the list at the bottom goes. The note floats out of
   the paragraph so it takes no height; each is a whole number of lines and
   clears the one before, so stacked notes stay on the grid. Same baseline
   correction as the footnotes. */
@media (width > 59em) {
  /* Place the text and its notes as one block: --left-share of the free space
     goes on the left of the text, the rest to the right of the notes (0.25 =
     25 / 75). The article's own side padding is taken off the margin. */
  html.type :is(article.post, article.page:not(.reviews, .poker, .specimen), section.page, .home-feed, .archives, .tag-archive),
  html.type .site-footer-inner {
    margin-left: max(0px, calc((100% - (var(--measure) + var(--sn-gap) + var(--sn-width))) * var(--left-share) - var(--gutter)));
    margin-right: 0;
  }
  html.type .prose .fn-note {
    display: block;
    float: right;
    clear: right;
    width: var(--sn-width);
    margin: 0 calc(-1 * (var(--sn-width) + var(--sn-gap))) 0 0;
    font-family: var(--note-font);
    font-size: var(--note-size);
    line-height: 1rlh;
    font-weight: var(--note-weight);
    translate: 0 var(--note-translate);
  }
  html.type .prose .fn-note::before {
    content: attr(data-n) " ";
    font-family: var(--font-sans);
    font-size: 0.75em;
    font-weight: 700;
    position: relative;
    top: -0.4em;
  }
  html.type .prose .footnotes { display: none; }
  /* The link has nowhere to go here (see sidenotes.js). */
  html.type .prose .footnote-ref a { pointer-events: none; cursor: default; }
}

/* Tool pages (/tax/). A reading column with the controls in the margin where
   sidenotes would go, and the same rules for everything inside: every control
   is a whole number of lines, text sits on the body baseline, and a rule or
   box edge is drawn rather than bordered so it cannot add a pixel of height. */
html.type {
  --tool-width: 20rem;
  --small: 0.875rem;
  --small-shift: calc((var(--a) - var(--d)) / 2 * (1rem - var(--small)));
  --label-shift: calc((var(--a) - var(--d)) / 2 * (1rem - 12px));
  --muted: color-mix(in srgb, var(--fg) 62%, var(--bg));
}
html.type article.page.tax {
  /* Wider than the reading column: the results keep a fixed width and the
     controls sit at the far edge of the page, centred as before. */
  max-width: var(--max-w);
  margin-left: auto;
  margin-right: auto;
}
html.type .tax .tx-subtitle { padding: 0; border: 0; }
html.type .tax .tx-layout {
  grid-template-columns: minmax(0, 41rem) var(--tool-width);
  gap: 0 var(--sn-gap);
  justify-content: space-between;
}
@media (width < 54em) {
  html.type .tax .tx-layout { grid-template-columns: minmax(0, 1fr); }
}
html.type .tax .tx-results { container-type: inline-size; }

/* Labels and small print. */
html.type .tax p.label,
html.type .tax .tx-details summary {
  margin: 0;
  font-size: 12px;
  line-height: 1rlh;
  opacity: 1;
  translate: 0 var(--label-shift);
}
html.type .tax p.tx-sub,
html.type .tax p.tx-hint,
html.type .tax .tx-field-label {
  display: block;
  margin: 0;
  font-size: var(--small);
  line-height: 1rlh;
  opacity: 1;
  color: var(--muted);
  translate: 0 var(--small-shift);
}
html.type .tax p.tx-hint { margin-bottom: 1rlh; }
html.type .tax p.label,
html.type .tax .tx-group-title { color: var(--muted); }
html.type .tax .tx-group-title { margin: 0; }
html.type .tax .tx-controls .tx-group-title:not(:first-child) { margin-top: 1rlh; }

/* Headline figures: two lines tall, sized like a heading. */
html.type .tax .tx-stats { margin: 0 0 1rlh; gap: 0 var(--gutter); }
html.type .tax p.tx-big {
  --n: 2;
  --lambda: 1.4;
  --step: var(--step-h1);
  margin: 0;
  font-weight: var(--h1-weight);
  letter-spacing: -0.01em;
}
@media (max-width: 560px) {
  html.type .tax .tx-stats { gap: 1rlh 0; }
}
html.type .tax .tx-est { padding: 0 4px; }

/* Charts: the box is rounded up to whole lines (the script sets --h). */
html.type .tax .tx-figure figcaption { margin-bottom: 0; }
html.type .tax .tx-chart { height: round(up, var(--h, 1rlh), 1rlh); }
html.type .tax .tx-key { margin: 0 0 1rlh; }

/* Tables: a row is one line, its rule drawn at the bottom edge. Sans with
   tabular figures rather than mono, so numbers share the body baseline. */
html.type .tax .tx-table {
  font-family: var(--font-sans);
  font-size: var(--small);
  font-weight: var(--body-weight);
  line-height: 1rlh;
  margin: 0 0 1rlh;
}
html.type .tax .tx-table tbody :is(th, td) { translate: 0 var(--small-shift); }
html.type .tax .tx-table th,
html.type .tax .tx-table td {
  padding: 0 8px 0 0;
  border: 0;
  vertical-align: top;
  /* Rules inside the table are light; the one under the header and the last
     one are the full muted tone. */
  background: linear-gradient(var(--rule, color-mix(in srgb, var(--fg) 20%, var(--bg))) 0 1px, transparent 1px) 0 100% / 100% 1px no-repeat;
}
html.type .tax .tx-table thead th,
html.type .tax .tx-table tbody:last-of-type tr:last-child > * { --rule: var(--muted); }
html.type .tax .tx-table thead th {
  font-size: 12px;
  opacity: 1;
  color: var(--muted);
  translate: 0 var(--label-shift);
}
/* The second line in an example cell (effective rate, or the row's name).
   The cell is already shifted for its own size, so only the difference is added. */
html.type .tax .tx-table .tx-rate {
  display: block;
  font-size: 12px;
  line-height: 1rlh;
  opacity: 1;
  color: var(--muted);
  translate: 0 calc((var(--a) - var(--d)) / 2 * (var(--small) - 12px));
}
html.type .tax .tx-table .tx-own { width: 13ch; margin: -2px 0; padding: 0 28px 0 4px; }
@media (width < 45em) {
  html.type .tax .tx-table th, html.type .tax .tx-table td { padding-right: 6px; }
  html.type .tax .tx-table thead th { letter-spacing: 0.08em; }
}
/* "What it could pay for": rows like the table's. Each is whole lines tall with a
   light rule drawn under it, and the last one takes the full muted tone. */
/* Two lines above: the table before it already leaves one, and margins collapse. */
html.type .tax .tx-buys { margin: 2rlh 0 0; }
html.type .tax .tx-buys ul { margin: 0 0 1rlh; }
html.type .tax .tx-buys li {
  margin: 0;
  padding: 0;
  border: 0;
  font-size: var(--small);
  line-height: 1rlh;
  background: linear-gradient(var(--rule, color-mix(in srgb, var(--fg) 20%, var(--bg))) 0 1px, transparent 1px) 0 100% / 100% 1px no-repeat;
}
html.type .tax .tx-buys li:last-child { --rule: var(--muted); }
html.type .tax .tx-buys li > * { translate: 0 var(--small-shift); }
html.type .tax .tx-buys li a { font-family: var(--font-sans); font-size: var(--small); color: var(--muted); opacity: 1; }
html.type .tax .tx-details { margin: 1rlh 0; }
/* list-item keeps the disclosure triangle, which display: block removes. */
html.type .tax .tx-details summary { display: list-item; }
html.type .tax p.label { display: block; }
html.type .tax .tx-details[open] > summary { margin-bottom: 1rlh; }
html.type .tax .tx-note { margin: 0 0 1rlh; }

/* Chips and buttons: a one-line slot with a 20px outline drawn behind the
   text, so the text sits on the baseline and rows of them never touch. */
html.type .tax .tx-chips { gap: 0 4px; }
html.type .tax .tx-chips button,
html.type .tax .tx-actions button,
html.type .tax .tx-band-meta button {
  position: relative;
  isolation: isolate;
  height: 1rlh;
  padding: 0 10px;
  border: 0;
  background: none;
  font-size: 12px;
  line-height: 1rlh;
  translate: 0 var(--label-shift);
}
html.type .tax .tx-chips button::before,
html.type .tax .tx-actions button::before,
html.type .tax .tx-band-meta button::before {
  content: "";
  position: absolute;
  inset: calc((1rlh - 20px) / 2) 0;
  z-index: -1;
  border: 1px solid currentColor;
}
html.type .tax .tx-chips button:hover,
html.type .tax .tx-actions button:hover,
html.type .tax .tx-band-meta button:hover,
html.type .tax .tx-chips button[aria-pressed="true"] { background: none; color: var(--bg); }
html.type .tax .tx-chips button:hover::before,
html.type .tax .tx-actions button:hover::before,
html.type .tax .tx-band-meta button:hover::before,
html.type .tax .tx-chips button[aria-pressed="true"]::before { background: var(--fg); }
html.type .tax .tx-actions button:disabled { opacity: 0.4; cursor: default; }
html.type .tax .tx-actions { display: flex; margin: 1rlh 0 0; }
html.type .tax .tx-chips + .tx-hint { margin-top: 1rlh; }

/* Fields: label line, then a one-line slot holding a 4px taller box. The text
   is centred in the box, so it lands on the baseline of the slot's line. */
html.type .tax .tx-field { display: grid; margin: 0 0 1rlh; }
html.type .tax input[type="number"] {
  box-sizing: border-box;
  display: block;
  height: calc(1rlh + 4px);
  margin: -2px 0;
  padding: 0 28px 0 8px;
  font-family: var(--font-sans);
  font-size: var(--small);
  font-weight: var(--body-weight);
  font-variant-numeric: tabular-nums;
}
/* The checkbox label is small print like the field labels, not body text. */
html.type .tax .tx-check { gap: 8px; margin: 0 0 1rlh; font-size: var(--small); line-height: 1rlh; color: var(--muted); }
html.type .tax .tx-check > span { translate: 0 var(--small-shift); }
/* It qualifies the field above, so it sits right under it. */
html.type .tax .tx-field + .tx-check { margin-top: -1rlh; }
html.type .tax .tx-check input { margin: calc((1rlh - 13px) / 2) 0 0; }
html.type .tax .tx-band {
  margin: 0;
  padding-top: 1rlh;
  border: 0;
  background: linear-gradient(var(--muted) 0 1px, transparent 1px) 0 0.5rlh / 100% 1px no-repeat;
}
/* Each band draws its own rule half a line above its text, so the hint needs no space of its own. */
html.type .tax p.tx-hint + #tx-bands { margin-top: -1rlh; }
html.type .tax .tx-band-row { gap: 0 8px; }
/* The slider that used to sit under the fields is gone, so the line of space it needed goes too. */
html.type .tax .tx-band-row .tx-field { margin-bottom: 0; }
html.type .tax .tx-band-meta {
  min-height: 1rlh;
  margin: 0;
  font-size: var(--small);
  line-height: 1rlh;
  opacity: 1;
  color: var(--muted);
}
html.type .tax .tx-band-meta .gross { translate: 0 var(--small-shift); }
html.type .tax .tx-controls {
  padding-left: 1.5rem;
  border-left-color: var(--muted);
}
@media (width < 54em) {
  html.type .tax .tx-controls {
    padding: 0 0 calc(1rlh - 1px);
    margin-bottom: 1rlh;
    border-bottom: 1px solid var(--muted);
  }
}

/* Chrome below the article: tags, previous/next, footer. Each text line is one
   rlh tall and translated by (a - d) / 2 * (body size - its size), the same
   correction as the footnotes, so its baseline lands on the body baseline.
   Translate does not move the layout box, so heights stay whole lines. */
html.type .post-tags { margin-top: 2rlh; }
html.type .post-tags > .label,
html.type .post-nav-item .label,
html.type .site-footer-row > .label {
  display: block;
  line-height: 1rlh;
  margin: 0;
  translate: 0 calc((var(--a) - var(--d)) / 2 * (1rem - 12px));
}
html.type .post-tags ul,
html.type .excerpt-tags { gap: 0 4px; }
html.type .post-tags ul li,
html.type .excerpt-tags li { height: 1rlh; margin: 0; }
/* A 20px chip inside a one-line slot, dropped so its text sits on the baseline:
   2px padding + half of the 16px line + the glyphs' offset from the line centre. */
html.type .post-tags ul a,
html.type .excerpt-tags a {
  display: block;
  padding: 2px 8px;
  line-height: 16px;
  translate: 0 calc(var(--beta) - 10px - (var(--a) - var(--d)) / 2 * 10px);
}

/* style.css gives the pages 128px below; make it whole lines. */
html.type :is(article.post, article.page:not(.reviews, .poker, .specimen), section.page, .home-feed, .archives, .tag-archive) { padding-bottom: 4rlh; }
html.type .post-nav { margin-top: 3rlh; }
html.type .post-nav-item { padding: 1rlh 0; }
/* The 1px rule is taken back out of the padding so the block stays whole. */
html.type .post-nav-title {
  font-size: 1rem;
  line-height: 1rlh;
  margin: 0;
  padding-top: calc(1rlh - 1px);
}
html.type p.post-nav-excerpt {
  font-size: 16px;
  line-height: 1rlh;
  margin: 0;
  translate: 0 calc((var(--a) - var(--d)) / 2 * (1rem - 16px));
}

/* Home feed: title, date, excerpt and tags, each a whole number of lines. The
   1px rule between items is taken back out of the padding, as with the post nav. */
html.type .excerpt-item { padding: 1rlh 0 calc(1rlh - 1px); }
html.type .excerpt-item:last-child { padding-bottom: 1rlh; }
html.type .excerpt-head { align-items: start; margin-bottom: 0; gap: var(--gutter); }
html.type .excerpt-title { font-weight: var(--h2-weight); margin: 0; }
html.type .excerpt-head time {
  line-height: 1rlh;
  translate: 0 calc((var(--a) - var(--d)) / 2 * (1rem - 12px));
}
html.type .excerpt-body {
  font-size: 16px;
  line-height: 1rlh;
  translate: 0 calc((var(--a) - var(--d)) / 2 * (1rem - 16px));
}
html.type .excerpt-tags { margin: 1rlh 0 0; }
@media (max-width: 640px) {
  html.type .excerpt-head { gap: 0; }
  /* style.css stacks the post nav with a 48px gap, not a whole number of lines. */
  html.type .post-nav-grid { gap: 2rlh; }
}

/* Archive and tag lists. A row is its text lines plus one empty line, with the
   rule drawn half a line up from the bottom, so it sits half a line from the
   text on either side however many lines the title wraps to. The rule is a
   background, not a border, so the row stays a whole number of lines. */
html.type .archives > .label,
html.type .tag-archive > .label {
  display: block;
  line-height: 1rlh;
  margin: 0 0 1rlh;
  translate: 0 calc((var(--a) - var(--d)) / 2 * (1rem - 12px));
}
html.type .weeknotes-intro { font-size: 1rem; line-height: 1rlh; margin: 0 0 1rlh; }
html.type .archive-item {
  align-items: start;
  padding: 0 0 1rlh;
  border-bottom: 0;
}
html.type .archive-item:not(:last-child) {
  background: linear-gradient(currentColor 0 1px, transparent 1px) 0 calc(100% - 0.5rlh + 0.5px) / 100% 1px no-repeat;
}
html.type .archive-item:last-child { padding-bottom: 0; }
html.type .archive-item a { font-size: 1rem; line-height: 1rlh; }
html.type .archive-item > .label,
html.type .archive-item > time {
  line-height: 1rlh;
  translate: 0 calc((var(--a) - var(--d)) / 2 * (1rem - 12px));
}
@media (max-width: 640px) {
  html.type .archive-item { gap: 0; }
  html.type .archive-item:has(.tag-count) { gap: 16px; align-items: start; }
}
html.type .tag-archive-back {
  margin-top: 1rlh;
  line-height: 1rlh;
  translate: 0 calc((var(--a) - var(--d)) / 2 * (1rem - 12px));
}

/* 404: the small label above the heading. */
html.type section.page > .post-header > .label {
  font-size: 12px;
  display: block;
  line-height: 1rlh;
  margin: 0;
  translate: 0 calc((var(--a) - var(--d)) / 2 * (1rem - 12px));
}

html.type .site-footer-inner {
  max-width: calc(var(--measure) + 2 * var(--gutter));
  padding: calc(2rlh - 1px) var(--gutter) 3rlh;
}
html.type .site-footer-row {
  align-items: start;
  line-height: 1rlh;
}
html.type .site-footer-row > :not(.label) {
  translate: 0 calc((var(--a) - var(--d)) / 2 * (1rem - 16px));
}
