:root {
  --unit: 1em;

  /*
    The children of `.nq-prose` will have font-sizes and margins proportional fluid value depending on the value that
    the element has.
    For example, if we set `font-size: 24px` to `.nq-prose`:
      - h1: will have (3 * 24)px for desktop and (2.75 * 24)px for mobile
      - p: will have (24)px for desktop and (2.75 * 24)px for mobile
  */
  --nq-screen-width-min-lh: 20;
  --nq-screen-width-max-lh: 72;
  --f-screen-range-lh: calc(var(--nq-screen-width-max-lh) - var(--nq-screen-width-min-lh));
  --nq-screen-width-min-em: 20;
  --nq-screen-width-max-em: 72;
  --f-screen-range-em: calc(var(--nq-screen-width-max-em) - var(--nq-screen-width-min-em));
  --font-size-min-em: 1;
  --font-size-max-em: 1;
  --margin-min-lh: 0;
  --margin-max-lh: 0;
}

/**
 * Make sure to import also nimiq-colors layer found in this package
 **/
.nq-prose,
[nq-prose],
.nq-prose-compact,
[nq-prose-compact] {
  font-size: 1rem;
  /* Default font-size */
  margin-trim: block;

  &:not(:where(.nq-prose-compact, [nq-prose-compact])) {
    > *:not(
        :where(
          .nq-raw,
          .nq-raw *,
          .nq-not-prose,
          .nq-not-prose *,
          .shiki *,
          img,
          video,
          iframe,
          figure,
          blockquote,
          pre,
          code
        )
      ) {
      padding-right: 0;
      padding-left: 0;

      &:last-child {
        padding-bottom: 6rem;

        @media (min-width: 1153px) {
          padding-bottom: 8rem;
        }
      }
    }

    > :where(img, video, iframe, figure, blockquote, pre, code) {
      padding-right: 2rem;
      padding-left: 2rem;

      &:last-child {
        padding-bottom: 6rem;

        @media (min-width: 1153px) {
          padding-bottom: 8rem;
        }
      }
    }
  }

  * {
    --lh-unit: 1lh;
    --f-factor-margin: calc((100vw - (var(--lh-unit) * var(--nq-screen-width-min-lh))) / var(--f-screen-range-lh));
    --f-factor: calc((100vw - (var(--unit) * var(--nq-screen-width-min-em))) / var(--f-screen-range-em));

    /* Margin calculation */
    --nq-m-range: calc(var(--margin-max-lh) - var(--margin-min-lh));
    --nq-m-fluid: calc(var(--lh-unit) * var(--margin-min-lh) + var(--nq-m-range) * var(--f-factor-margin));
    --nq-m-size: clamp(
      calc(var(--lh-unit) * var(--margin-min-lh)),
      var(--nq-m-fluid),
      calc(var(--margin-max-lh) * var(--lh-unit))
    );

    /* derived values */
    --font-size-range: calc(var(--font-size-max-em) - var(--font-size-min-em));
    --tp-font-size-fluid: calc(var(--unit) * var(--font-size-min-em) + var(--font-size-range) * var(--f-factor));
    --tp-font-size: clamp(
      var(--unit) * var(--font-size-min-em),
      var(--tp-font-size-fluid),
      var(--unit) * var(--font-size-max-em)
    );
    font-size: var(--tp-font-size);
  }

  > *:first-child {
    margin-top: 0;
    /* TODO Remove margin-top and margin-bottom on last element when margin-trim is widely supported */
  }

  > *:last-child {
    margin-bottom: 0;
  }

  *:not(:where(.nq-raw, .nq-raw *, .nq-not-prose, .nq-not-prose *, .shiki *)) {
    line-height: 1.5;
    max-width: var(--nq-prose-max-width, 78ch);
    margin-left: auto;
    margin-right: auto;
    font-family: var(--nq-font-sans, 'Mulish');

    &:where(h1) {
      --font-size-min-em: 2.25;
      --font-size-max-em: 2.5;
      line-height: 1.5;
      font-weight: 700;
    }

    &:where(h1 + *:not(:where(h1, h2, h3, h4))) {
      --margin-min-lh: 4.6667;
      --margin-max-lh: 5;
      margin-top: var(--nq-m-size);
    }

    &:where(h2) {
      --font-size-min-em: 1.75;
      --font-size-max-em: 2;
      line-height: 1.3;
      font-weight: 700;

      margin-top: 2lh;
      margin-bottom: 24px;
      --margin-min-lh: 4.2308;
      --margin-max-lh: 4.6154;

      &:where(h1 + h2) {
        --margin-min-lh: 1.9231;
        --margin-max-lh: 2.3077;
      }
    }

    &:where(h3) {
      --font-size-min-em: 1.4;
      --font-size-max-em: 1.625;
      line-height: 1.3;
      font-weight: 700;

      margin-bottom: 24px;
      margin-top: 1.7lh;
      --margin-min-lh: 4.2308;
      --margin-max-lh: 4.6154;

      &:where(h2 + h3) {
        --margin-min-lh: 1.5385;
        --margin-max-lh: 1.7308;
      }
    }

    &:where(h4) {
      --font-size-min-em: 1.25;
      --font-size-max-em: 1.4;
      line-height: 1.3;
      font-weight: 700;

      margin-top: 1.4lh;
      margin-bottom: 24px;
      --margin-min-lh: 4.2308;
      --margin-max-lh: 4.6154;
    }

    &:where(h3 + h4) {
      --margin-min-lh: 1.5385;
      --margin-max-lh: 1.7308;
      margin-top: 1.2lh;
    }

    &:where(h5) {
      --font-size-min-em: 1.125;
      --font-size-max-em: 1.25;
      line-height: 1.3;
      font-weight: 700;

      margin-top: 1.2lh;
      margin-bottom: 24px;
      --margin-min-lh: 4.2308;
      --margin-max-lh: 4.6154;
    }

    &:where(h6) {
      --font-size-min-em: 1;
      --font-size-max-em: 1.125;
      line-height: 1.3;
      font-weight: 700;

      margin-top: 1.2lh;
      margin-bottom: 24px;
      --margin-min-lh: 4.2308;
      --margin-max-lh: 4.6154;
    }

    /* Anchors in headings */
    &:where(h1, h2, h3, h4, h5, h6)[id] {
      position: relative;
      margin-left: -1.25rem;
      padding-left: 1rem;
      padding-right: 1rem;
      width: 100%;
      min-height: 1em;
      color: var(--colors-neutral);

      &::after {
        content: '#';
        opacity: 0;
        position: absolute;
        z-index: 1;
        top: 0;
        left: 0;
        height: 100%;
        transition: 50ms opacity var(--nq-ease, ease-in-out);
        pointer-events: none;
      }

      @media (min-width: 769px) {
        :where(&, &::after):hover {
          &::after {
            opacity: 0.5;
          }
        }
      }

      &:has(a:focus-visible) {
        outline: 0.125rem solid var(--colors-blue);
        outline-offset: 0.125rem;
      }

      > a {
        position: absolute;
        inset: 0;
        padding-left: 20px;
        font-size: inherit;
        font-weight: inherit;
        top: -6px;
        color: var(--colors-neutral);

        &::after {
          position: absolute;
          inset: 0;
        }
      }
    }

    &:where(p) {
      margin-top: 0;
      margin-bottom: 0;
      line-height: 1.5;
      --font-size-min-em: 0.9;
      --font-size-max-em: 1;

      & + p {
        margin-top: 16px;
      }
    }

    &:where(figure) {
      figcaption {
        color: var(--colors-neutral-700);
        --font-size-min-em: 0.75;
        --font-size-max-em: 0.875;
        font-weight: 700;
        line-height: 1.3125;
        padding: 16px;

        :where(.dark, [data-theme='dark']) & {
          color: color-mix(in oklch, var(--colors-white) 80%, transparent);
        }
      }
    }

    &:where(blockquote) {
      background: var(--colors-green-400);
      --margin-min-em: 1.5;
      --margin-max-em: 2;
      margin-top: var(--nq-m-size);
      margin-bottom: var(--nq-m-size);
      margin-left: -8px;
      margin-right: -8px;
      padding: 1em;
      border-radius: 6px;
      box-shadow: 0 0 0 1.5px var(--colors-green-600);
      font-weight: 600;
      width: calc(100% + 16px);
      box-sizing: border-box;
      --font-size-min-em: 0.75;
      --font-size-max-em: 0.875;

      @media (min-width: 768px) {
        margin-left: 0;
        margin-right: 0;
        width: 100%;
      }

      p {
        line-height: 1.3;
        margin: 0;
      }

      > *:not(:first-child) {
        margin-top: 0.75lh;
      }

      code,
      pre {
        background-color: var(--colors-green-600);
        color: var(--colors-green-1100);
      }
    }

    &:where(img, video, iframe) {
      border-radius: 6px;
      --margin-min-lh: 0.75;
      --margin-max-lh: 0.9167;
      margin-top: var(--nq-m-size);

      &:has(+ figcaption) {
        --margin-min-lh: 0.5;
        --margin-max-lh: 0.6667;
        margin-bottom: var(--nq-m-size);
      }

      &:not(:has(+ figcaption)) {
        --margin-min-lh: 0.75;
        --margin-max-lh: 0.9167;
        margin-bottom: var(--nq-m-size);
      }
    }

    article &:where(img) {
      background-color: white;
    }

    /* Rules to use a wider container (8px on the sides). Mainly for phones */
    &:where(img, video, iframe, table),
    /* Select code and pre that are not child of p,ul,ol... */
    &:where(code, pre):not(:where(:where(p, ul, ol, pre, code, table) :where(pre, code))) {
      margin-left: -1.5rem;
      width: min(calc(100% + 3rem), 700px);

      @media (min-width: 768px) {
        margin-left: 0;
        width: 100%;
        max-width: 100%;
      }
    }

    &:where(ul) {
      list-style: none;
      margin-top: 24px;
      margin-bottom: 24px;

      li {
        display: block;
        position: relative;
        margin: 16px 0 16px 20px;

        > ol li {
          margin-left: 0;
        }

        :not(ul ol) &::before {
          content: '';
          width: 6px;
          height: 6px;
          border-radius: 3px;
          background-color: currentColor;
          opacity: 0.2;
          display: inline-block;
          margin-right: 12px;
          position: absolute;
          left: -20px;
          top: 8px;
        }
      }
    }

    &:where(ol) {
      list-style: none;
      counter-reset: item;
      margin-top: 24px;
      margin-bottom: 24px;

      li {
        counter-increment: item;
        position: relative;
        margin: 16px 0 16px 20px;

        > ol {
          counter-reset: subitem;

          li {
            counter-increment: subitem;

            &::before {
              content: counters(item, '.') '.' counter(subitem);
              top: 0;
              left: -32px;
            }
          }
        }

        &::before {
          content: counters(item, '.');
          font-weight: 700;
          display: inline-block;
          margin-right: 12px;
          position: absolute;
          left: -20px;
          color: currentColor;
          opacity: 0.5;
          top: 2px;
        }
      }
    }

    :where(ol, ul) ol,
    ul ul {
      margin-top: 8px;
      margin-bottom: 16px;
      padding-left: 8px;

      li {
        margin-top: 0;
        margin-left: 12px;
      }
    }

    &:where(code, pre, kbd, pre *, code *) {
      font-family: var(--nq-font-mono, 'Fira Code');
      /* font-size-adjust: from-font;
          TODO
          Remove all font-sizes for Fira Code and instead using font-size-adjust to adjust the font-size to the parent element.
        https://developer.mozilla.org/en-US/docs/Web/CSS/font-size-adjust
    */
    }

    &:where(code) {
      --font-size-min-em: 0.75;
      --font-size-max-em: 0.875;
      border-radius: 4px;
    }

    :where(:where(h1, h2, h3, h4, h5, h6, p, li, span, a) > code) {
      padding: 0 0.15em;
      line-height: inherit;
      vertical-align: baseline;
    }

    &:where(pre) {
      width: 100%;
      --font-size-min-em: 0.75;
      --font-size-max-em: 0.875;
      --margin-min-lh: 0.8333;
      --margin-max-lh: 1;
      margin-top: var(--nq-m-size);
      margin-bottom: var(--nq-m-size);
      padding: 20px 24px;
      border-radius: 6px;
      outline: 1.5px solid color-mix(in oklch, var(--colors-neutral) 8%, transparent);
    }

    kbd {
      padding: 0.25em 0.125em;
      --font-size-min: 0.75;
      --font-size-max: 0.875;
      color: var(--colors-neutral-800);
      background-color: var(--colors-neutral-200);
      border-radius: 0.25em;
      box-shadow: 0 0 0 1px var(--colors-neutral-400);
      margin: 0 0.25em -0.25em 0.25em;
      white-space: nowrap;
      line-height: 1;
    }

    &:where(pre, code):where(h1, h2, h3, h4 &) {
      font-size: 0.8em;
      padding: 2px 0.5rem;
      position: relative;
      top: -1px;
    }

    &:where(a) {
      text-decoration: none;
      color: var(--colors-blue);
      font-weight: 600;

      code {
        font-weight: 400;
      }
    }

    table {
      --margin-min-lh: 1;
      --margin-max-lh: 1.3333;
      margin-bottom: var(--nq-m-size);
      margin-top: var(--nq-m-size);
      display: block;
      overflow-x: auto;
      border-spacing: 0;
      border-collapse: separate;
      border-radius: 6px;
      border: 1px solid var(--colors-neutral-300);
      max-height: 90dvh;
      max-width: max-content;
      scroll-behavior: smooth;

      code,
      pre {
        --line-height: 1.3;
        padding: 4px 0.25rem;
        position: relative;
      }

      th,
      td {
        padding: 12px 0.75rem;
      }

      thead th {
        z-index: 1;
        position: sticky;
        top: -1px;
        text-wrap: balance;
        white-space: nowrap;
        font-weight: 400;
        color: var(--colors-neutral-800);
        background-color: var(--colors-neutral-100);
      }

      tbody {
        td {
          vertical-align: initial;
          text-wrap: balance;
        }

        > tr:not(:last-child) td {
          border-bottom: 1px solid var(--colors-neutral-300);
        }
      }

      /* Apply a border to the right of all but the last column */
      th:not(:last-child),
      td:not(:last-child) {
        border-right: 1px solid var(--colors-neutral-300);
      }
    }

    hr {
      --margin-min-lh: 0.8333;
      --margin-max-lh: 1;
      margin: var(--nq-m-size) auto;
      width: 128px;
      border-color: var(--colors-neutral-500);
    }

    details {
      /* TODO Animate open/closing https://developer.chrome.com/docs/css-ui/animate-to-height-auto#animate_the_details_element */
      border-radius: 6px;
      background-color: var(--colors-neutral-200);
      --margin-min-lh: 0.75;
      --margin-max-lh: 0.9167;
      margin-top: var(--nq-m-size);
      margin-bottom: var(--nq-m-size);
      color: var(--colors-neutral-900);
      box-shadow: 0 0 0 1.5px color-mix(in oklch, var(--colors-neutral) 10%, transparent);

      ::marker {
        color: transparent;
      }

      summary {
        padding: 14px 2rem 14px calc(0.7rem + 2.3em);
        --font-size-min-em: 0.9;
        --font-size-max-em: 1;
        position: relative;
        display: flex;
        align-items: center;
        cursor: pointer;

        &::before {
          content: '';
          --icon: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxZW0iIGhlaWdodD0iMWVtIiB2aWV3Qm94PSIwIDAgMTIgMTIiPjxwYXRoIGZpbGw9ImN1cnJlbnRDb2xvciIgZD0iTTIgMS40MTNBLjguOCAwIDAxMy4yMTIuNzI3bDcuNjQ1IDQuNTg3YS44LjggMCAwMTAgMS4zNzJsLTcuNjQ1IDQuNTg3QS44LjggMCAwMTIgMTAuNTg3eiIvPjwvc3ZnPg==);
          -webkit-mask: var(--icon) no-repeat;
          mask: var(--icon) no-repeat;
          -webkit-mask-size: 100% 100%;
          mask-size: 100% 100%;
          background-color: currentColor;
          color: inherit;
          width: 0.622em;
          height: 0.622em;
          transition: transform 100ms ease-out;
          display: inline-block;
          position: absolute;
          left: 0;
          padding-left: 4rem;
        }
      }

      &[open] summary {
        &::before {
          transform: rotate(90deg);
        }
      }

      > *:not(summary) {
        padding: 0 1rem 14px 1rem;
      }

      p {
        margin: 0.75lh;
      }

      &[open] p {
        margin: 0.75lh;
      }
    }
  }
}
