@layer blocks {
  /* Running text: legal pages, settings, landing copy. Only covers what
     actually appears inside .prose: headings, paragraphs, lists, tables, code.
     Colour is inherited rather than set on p/li, so a colour utility on a
     paragraph inside .prose still wins. */
  .prose {
    --flow-space: var(--space-half);
    color: var(--color-text-prose);
  }

  /* Increase legibility by limiting line lengths */
  .prose :is(p, :not([role="list"]) > li) {
    max-width: var(--measure);
  }

  .prose :is(h1, h2, h3, h4) {
    max-width: var(--measure-narrow);
    font-weight: var(--weight-semi);
    color: var(--color-text);
  }

  .prose :is(h1, h2, h3) {
    overflow-wrap: anywhere;
  }

  /* Order matters: these three tie on specificity. */
  .prose table,
  .prose table + * {
    --flow-space: var(--space-cell);
  }

  .prose :is(h1, h2, h3, h4) + * {
    --flow-space: var(--space-half);
  }

  .prose * + :is(h1, h2, h3, h4) {
    --flow-space: var(--space-half);
  }

  /* Reading lists only. A [role="list"] is a data list (tasks, users,
     members) and keeps the reset's flush start. */
  .prose ul:not([role="list"]) {
    padding-inline-start: var(--space-half);
  }

  .prose ul:not([role="list"]) li {
    padding-inline-start: var(--space-2);
  }

  .prose ul:not([role="list"]) li + li,
  .prose ul:not([role="list"]) li > ul {
    margin-block-start: var(--space-2);
  }

  /* List items holding paragraphs get paragraph spacing. */
  .prose ul:not([role="list"]) li + li:has(p) {
    margin-block-start: var(--flow-space);
  }

  .prose ul:not([role="list"]) li:has(> p) > p {
    margin-block-start: var(--space-2);
  }

  .prose code {
    font-weight: var(--weight-semi);
    font-size: 0.95em;
    background: revert;
  }

  .prose code::before,
  .prose code::after {
    content: "`";
  }
}
