diff --git a/static/css/_src/components/content/prose.css b/static/css/_src/components/content/prose.css index 8728e66..f8fea76 100644 --- a/static/css/_src/components/content/prose.css +++ b/static/css/_src/components/content/prose.css @@ -23,7 +23,7 @@ /* ── Headings ── */ .prose :where(h2, h3, h4, h5, h6) { - @apply mb-6 leading-normal font-semibold text-text; + @apply relative mb-6 leading-normal font-semibold wrap-break-word text-text; } .prose :where(h2, h3, h4, h5, h6) + * { @@ -31,7 +31,7 @@ } .prose :where(h2) { - @apply mt-[2.25em] pb-[0.4em] text-[1.4em] font-bold after:absolute after:right-0 after:bottom-0 after:left-5 after:border-b after:border-border-overlay; + @apply mt-[2.25em] pb-[0.4em] text-[1.4em] font-bold after:absolute after:right-0 after:bottom-0 after:left-0 after:border-b after:border-border-overlay; } .prose :where(h3) { @@ -140,13 +140,37 @@ .prose :where(a:not(.not-prose, .not-prose *)) { @apply pb-0.5 no-underline; - &:hover { + &:hover, + &:focus-visible { @apply text-link-hover; } } -.prose .heading-anchor, -.prose .heading-anchor:hover, +.prose :where(.heading-anchor) { + @apply border-b-0 p-0 text-inherit; + font-weight: inherit; + + @variant xl { + &:hover, + &:focus-visible { + @apply text-inherit; + } + + &::before { + @apply absolute -left-5 text-link opacity-0 transition-opacity; + content: '#'; + } + + &:hover::before { + @apply opacity-60; + } + + &:focus-visible::before { + @apply opacity-100; + } + } +} + .prose .footnote-reference a, .prose .footnote-reference a:hover, .prose .footnote-backref, @@ -186,24 +210,6 @@ @apply wrap-break-word; } - /* ── Heading Anchors ── */ - - .prose :where(h1, h2, h3, h4, h5, h6) { - @apply relative -ml-5 pl-5; - } - - .prose .heading-anchor { - @apply absolute left-0 text-link no-underline opacity-0 transition-opacity; - } - - .prose :where(h2, h3, h4, h5, h6):hover .heading-anchor { - @apply opacity-60; - } - - .prose :where(.callout, blockquote) .heading-anchor { - @apply hidden; - } - /* ── Images ── */ .prose figure img { diff --git a/static/css/style.css b/static/css/style.css index 4ae8523..1de498e 100644 --- a/static/css/style.css +++ b/static/css/style.css @@ -2131,11 +2131,13 @@ --tw-prose-captions: var(--color-text-secondary); } .prose :where(h2, h3, h4, h5, h6) { + position: relative; margin-bottom: calc(var(--spacing) * 6); --tw-leading: var(--leading-normal); line-height: var(--leading-normal); --tw-font-weight: var(--font-weight-semibold); font-weight: var(--font-weight-semibold); + overflow-wrap: break-word; color: var(--color-text); } .prose :where(h2, h3, h4, h5, h6) + * { @@ -2161,7 +2163,7 @@ } &::after { content: var(--tw-content); - left: calc(var(--spacing) * 5); + left: 0px; } &::after { content: var(--tw-content); @@ -2286,11 +2288,39 @@ .prose :where(a:not(.not-prose, .not-prose *)) { padding-bottom: calc(var(--spacing) * 0.5); text-decoration-line: none; - &:hover { + &:hover, &:focus-visible { color: var(--color-link-hover); } } -.prose .heading-anchor, .prose .heading-anchor:hover, .prose .footnote-reference a, .prose .footnote-reference a:hover, .prose .footnote-backref, .prose .footnote-backref:hover { +.prose :where(.heading-anchor) { + border-bottom-style: var(--tw-border-style); + border-bottom-width: 0px; + padding: 0px; + color: inherit; + font-weight: inherit; + @media (width >= 80rem) { + &:hover, &:focus-visible { + color: inherit; + } + &::before { + position: absolute; + left: calc(var(--spacing) * -5); + color: var(--color-link); + opacity: 0%; + transition-property: opacity; + transition-timing-function: var(--tw-ease, var(--default-transition-timing-function)); + transition-duration: var(--tw-duration, var(--default-transition-duration)); + content: '#'; + } + &:hover::before { + opacity: 60%; + } + &:focus-visible::before { + opacity: 100%; + } + } +} +.prose .footnote-reference a, .prose .footnote-reference a:hover, .prose .footnote-backref, .prose .footnote-backref:hover { border-bottom-style: var(--tw-border-style); border-bottom-width: 0px; } @@ -2322,27 +2352,6 @@ .prose :where(p, li) { overflow-wrap: break-word; } - .prose :where(h1, h2, h3, h4, h5, h6) { - position: relative; - margin-left: calc(var(--spacing) * -5); - padding-left: calc(var(--spacing) * 5); - } - .prose .heading-anchor { - position: absolute; - left: 0px; - color: var(--color-link); - text-decoration-line: none; - opacity: 0%; - transition-property: opacity; - transition-timing-function: var(--tw-ease, var(--default-transition-timing-function)); - transition-duration: var(--tw-duration, var(--default-transition-duration)); - } - .prose :where(h2, h3, h4, h5, h6):hover .heading-anchor { - opacity: 60%; - } - .prose :where(.callout, blockquote) .heading-anchor { - display: none; - } .prose figure img { margin-inline: auto; border-radius: var(--radius-lg); diff --git a/static/js/content/content.js b/static/js/content/content.js index 90957b0..cd7896c 100644 --- a/static/js/content/content.js +++ b/static/js/content/content.js @@ -109,13 +109,17 @@ ); const jumpToPrefix = document.documentElement.dataset.i18nJumpTo; for (const heading of headings) { + if (heading.closest('.callout, blockquote') || heading.querySelector('a')) { + continue; + } + const anchor = document.createElement('a'); anchor.href = `#${heading.id}`; anchor.className = 'heading-anchor'; - anchor.textContent = '#'; const label = jumpToPrefix ? `${jumpToPrefix} ${heading.textContent}` : heading.textContent; anchor.setAttribute('aria-label', label); - heading.prepend(anchor); + anchor.append(...heading.childNodes); + heading.append(anchor); } };