@layer wa-utilities {
  /* `wa-prose` applies hierarchical, asymmetric typographic rhythm to a block
     of long-form content. Builds on `wa-native`'s base block styles instead of
     duplicating them. Em-based spacing scales when composed with `wa-font-size-*`.
     The class and its element selectors are wrapped in `:where()` so every rule
     sits at 0,0,0 specificity — any utility class or element rule the author
     applies inside the container takes precedence without weight tricks. */

  /* @scope is Newly Available in Baseline 2025. As such, it should be reserved for
     non-essential, progressive enhancement features until @scope is established
     as Widely Available. https://caniuse.com/css-cascade-scope */
  @scope (.wa-prose) to (.wa-not-prose) {
    :where(:scope) {
      /* #region Tokens ~~~~~~~~~~~~ */

      /* Em-based rhythm scale: each token resolves at the use site, so margins
        scale with the element's own font-size. `--wa-prose-rhythm-scale` is a
        single knob to tighten or loosen everything at once. */
      --wa-prose-rhythm-scale: 1;
      --wa-prose-rhythm-2xs: calc(0.25em * var(--wa-space-scale) * var(--wa-prose-rhythm-scale));
      --wa-prose-rhythm-xs: calc(0.5em * var(--wa-space-scale) * var(--wa-prose-rhythm-scale));
      --wa-prose-rhythm-s: calc(0.75em * var(--wa-space-scale) * var(--wa-prose-rhythm-scale));
      --wa-prose-rhythm-m: calc(1em * var(--wa-space-scale) * var(--wa-prose-rhythm-scale));
      --wa-prose-rhythm-l: calc(1.5em * var(--wa-space-scale) * var(--wa-prose-rhythm-scale));
      --wa-prose-rhythm-xl: calc(2em * var(--wa-space-scale) * var(--wa-prose-rhythm-scale));
      --wa-prose-rhythm-2xl: calc(2.5em * var(--wa-space-scale) * var(--wa-prose-rhythm-scale));
      --wa-prose-rhythm-3xl: calc(3em * var(--wa-space-scale) * var(--wa-prose-rhythm-scale));

      --wa-prose-line-length: 65ch;

      max-inline-size: var(--wa-prose-line-length);

      /* Oldstyle proportional figures for running text; tables reassert
        `tabular-nums` below. Fonts without the OpenType feature fall back. */
      font-variant-numeric: oldstyle-nums proportional-nums;

      /* Inherits to descendants. Safari today; progressive enhancement elsewhere. */
      hanging-punctuation: first last allow-end;
      /* #endregion */

      /* #region Headings ~~~~~~~~~~~~ */

      /* Em sizes inherit through the cascade — re-applying `--wa-font-size-scale`
        here would double-scale. Authors overriding should stay em-based. */
      & :where(h1) {
        font-size: 2.5625em;
      }
      & :where(h2) {
        font-size: 2em;
      }
      & :where(h3) {
        font-size: 1.5625em;
      }
      & :where(h4) {
        font-size: 1.25em;
      }
      & :where(h5) {
        font-size: 1em;
      }
      & :where(h6) {
        font-size: 0.75em;
      }

      /* Slight optical tracking; only the larger sizes need it. */
      & :where(h1, h2) {
        letter-spacing: -0.01em;
      }

      /* Headings hug what they introduce: generous above, tight below. */
      & :where(h1):has(+ *) {
        margin-block-end: var(--wa-prose-rhythm-s);
      }

      & * + :where(h2) {
        margin-block-start: var(--wa-prose-rhythm-2xl);
      }
      & :where(h2):has(+ *) {
        margin-block-end: var(--wa-prose-rhythm-s);
      }

      & * + :where(h3) {
        margin-block-start: var(--wa-prose-rhythm-xl);
      }
      & :where(h3):has(+ *) {
        margin-block-end: var(--wa-prose-rhythm-s);
      }

      & :where(h4, h5, h6):has(+ *) {
        margin-block-end: var(--wa-prose-rhythm-xs);
      }

      /* Back-to-back headings tighten so the second reads as subordinate.
        Enumerated explicitly — skipping more than two levels is rare enough
        that the default rhythm reads better. */
      & :where(h1 + h2, h1 + h3, h2 + h3, h2 + h4, h3 + h4, h4 + h5, h5 + h6) {
        margin-block-start: var(--wa-prose-rhythm-m);
      }
      /* #endregion */

      /* #region Body text & lists ~~~~~~~~~~~~ */

      /* Replaces wa-native's rem-based `--wa-content-spacing` with em rhythm. */
      & :where(p, ul, ol, dl):has(+ *) {
        margin-block-end: var(--wa-prose-rhythm-l);
      }

      & :where(ul, ol) > :where(li):has(+ li) {
        margin-block-end: var(--wa-prose-rhythm-2xs);
      }

      & :where(dd):has(+ *) {
        margin-block-end: var(--wa-prose-rhythm-s);
      }
      /* #endregion */

      /* #region Captions ~~~~~~~~~~~~ */

      /* Em-based override keeps caption spacing in step with the prose
        container; wa-native sets the visual style. */
      & :where(figcaption) {
        margin-block-start: var(--wa-prose-rhythm-xs);
      }
      /* #endregion */

      /* #region Inline code & long-word breaks ~~~~~~~~~~~~ */

      /* `anywhere` is the right trade-off in prose: long URLs and identifiers
        break instead of overflowing the column. */
      & :where(code, pre) {
        overflow-wrap: anywhere;
      }
      /* #endregion */

      /* #region Section breaks & major non-text blocks ~~~~~~~~~~~~ */

      /* `<hr>`'s own margin defines the gap; the next heading shouldn't double-stack. */
      & :where(hr) {
        margin-block: var(--wa-prose-rhythm-3xl);
      }
      & :where(hr + :is(h1, h2, h3, h4, h5, h6)) {
        margin-block-start: 0;
      }

      /* Major non-text blocks get more air than running prose, but headings
        still hug — so the top-margin rule excludes the heading-to-block case
        (handled separately below with a smaller gap). */
      & :where(pre, figure, table, blockquote, wa-callout, details):has(+ *) {
        margin-block-end: var(--wa-prose-rhythm-xl);
      }

      & :where(:not(h1, h2, h3, h4, h5, h6) + :is(pre, figure, table, blockquote, wa-callout, details)) {
        margin-block-start: var(--wa-prose-rhythm-xl);
      }

      & :where(:is(h1, h2, h3, h4, h5, h6) + :is(pre, figure, table, blockquote, wa-callout, details)) {
        margin-block-start: var(--wa-prose-rhythm-m);
      }
      /* #endregion */
    }
  }
}
